Ejemplo n.º 1
0
    def __init__(self, mail_user, mail_pwd, mail_host=''):
        if global_config.getRaw('messenger', 'email_enable') == 'false':
            return

        smtpObj = smtplib.SMTP()
        # 没传会自动判断 判断不出来默认QQ邮箱
        if mail_host:
            self.mail_host = mail_host
        elif mail_user.endswith('163.com'):
            self.mail_host = 'smtp.163.com'
        elif mail_user.endswith(('sina.com', 'sina.cn')):
            self.mail_host = 'smtp.163.com'
        elif mail_user.endswith('qq.com'):
            self.mail_host = 'smtp.qq.com'
        elif mail_user.endswith('sohu.com'):
            self.mail_host = 'smtp.sohu.com'
        else:
            self.mail_host = 'smtp.qq.com'
        self.mail_user = mail_user
        self.is_login = False
        try:
            smtpObj.connect(mail_host, 25)
            smtpObj.login(mail_user, mail_pwd)
            self.is_login = True
        except Exception as e:
            logger.info('邮箱登录失败!', e)
        self.smtpObj = smtpObj
Ejemplo n.º 2
0
 def send(self, title, msg, receivers: list, img=''):
     """
     发送smtp邮件至收件人
     :param title:
     :param msg: 如果发送图片,需在msg内嵌入<img src='cid:xxx'>,xxx为图片名
     :param receivers:
     :param img: 图片名
     :return:
     """
     if self.is_login:
         message = MIMEMultipart('alternative')
         msg_html = MIMEText(msg, 'html', 'utf-8')
         message.attach(msg_html)
         message['Subject'] = title
         message['From'] = self.mail_user
         if img:
             with open(img, "rb") as f:
                 msg_img = MIMEImage(f.read())
             msg_img.add_header('Content-ID', img)
             message.attach(msg_img)
         try:
             self.smtpObj.sendmail(self.mail_user, receivers, message.as_string())
         except Exception as e:
             logger.info('邮件发送失败!', e)
     else:
         logger.info('邮箱未登录')
    def _get_seckill_init_info(self):
        """获取秒杀初始化信息(包括:地址,发票,token)
        :return: 初始化信息组成的dict
        """
        logger.info('获取秒杀初始化信息...')
        url = 'https://marathon.jd.com/seckillnew/orderService/pc/init.action'
        data = {
            'sku': self.sku_id,
            'num': self.seckill_num,
            'isModifyAddress': 'false',
        }
        headers = {
            'User-Agent': self.user_agent,
            'Host': 'marathon.jd.com',
            'referer': 'https://marathon.jd.com/seckill/seckill.action?skuId={0}&num={1}&rid={2}'.format(
                self.sku_id, self.seckill_num, int(time.time())),
        }
        resp = self.session.post(url=url, data=data, headers=headers)

        resp_json = None
        try:
            resp_json = parse_json(resp.text)
        except Exception:
            raise SKException('获取秒杀初始化信息失败,返回信息:{}'.format(resp.text[0: 128]))

        return resp_json
Ejemplo n.º 4
0
 def make_reserve(self):
     """商品预约"""
     logger.info('商品名称:{}'.format(self.get_sku_title()))
     url = 'https://yushou.jd.com/youshouinfo.action?'
     payload = {
         'callback': 'fetchJSON',
         'sku': self.sku_id,
         '_': str(int(time.time() * 1000)),
     }
     headers = {
         'User-Agent': self.user_agent,
         'Referer': 'https://item.jd.com/{}.html'.format(self.sku_id),
     }
     resp = self.session.get(url=url, params=payload, headers=headers)
     resp_json = parse_json(resp.text)
     reserve_url = resp_json.get('url')
     self.timers.start()
     while True:
         try:
             self.session.get(url='https:' + reserve_url)
             logger.info('预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约')
             if global_config.getRaw('messenger', 'enable') == 'true':
                 success_message = "预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约"
                 send_wechat(success_message)
             break
         except Exception as e:
             logger.error('预约失败正在重试...')
Ejemplo n.º 5
0
 def get_seckill_url(self):
     """获取商品的抢购链接
     点击"抢购"按钮后,会有两次302跳转,最后到达订单结算页面
     这里返回第一次跳转后的页面url,作为商品的抢购链接
     :return: 商品的抢购链接
     """
     url = 'https://itemko.jd.com/itemShowBtn'
     payload = {
         'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
         'skuId': self.sku_id,
         'from': 'pc',
         '_': str(int(time.time() * 1000)),
     }
     headers = {
         'User-Agent': self.user_agent,
         'Host': 'itemko.jd.com',
         'Referer': 'https://item.jd.com/{}.html'.format(self.sku_id),
     }
     while True:
         resp = self.session.get(url=url, headers=headers, params=payload)
         resp_json = parse_json(resp.text)
         if resp_json.get('url'):
             # https://divide.jd.com/user_routing?skuId=8654289&sn=c3f4ececd8461f0e4d7267e96a91e0e0&from=pc
             router_url = 'https:' + resp_json.get('url')
             # https://marathon.jd.com/captcha.html?skuId=8654289&sn=c3f4ececd8461f0e4d7267e96a91e0e0&from=pc
             seckill_url = router_url.replace('divide', 'marathon').replace(
                 'user_routing', 'captcha.html')
             logger.info("抢购链接获取成功: %s", seckill_url)
             return seckill_url
         else:
             logger.info("抢购链接获取失败,稍后自动重试")
             wait_some_time()
Ejemplo n.º 6
0
    def _get_qrcode_ticket(self):
        """
        通过 token 获取票据
        :return:
        """
        url = 'https://qr.m.jd.com/check'
        payload = {
            'appid': '133',
            'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
            'token': self.session.cookies.get('wlfstk_smdl'),
            '_': str(int(time.time() * 1000)),
        }
        headers = {
            'User-Agent': self.spider_session.get_user_agent(),
            'Referer': 'https://passport.jd.com/new/login.aspx',
        }
        resp = self.session.get(url=url, headers=headers, params=payload)

        if not response_status(resp):
            logger.error('获取二维码扫描结果异常')
            return False

        resp_json = parse_json(resp.text)
        if resp_json['code'] != 200:
            logger.info('Code: %s, Message: %s', resp_json['code'],
                        resp_json['msg'])
            return None
        else:
            logger.info('已完成手机客户端确认')
            return resp_json['ticket']
    def _get_qrcode(self):
        """
        缓存并展示登录二维码
        :return:
        """
        url = 'https://qr.m.jd.com/show'
        payload = {
            'appid': 133,
            'size': 147,
            't': str(int(time.time() * 1000)),
        }
        headers = {
            'User-Agent': self.spider_session.get_user_agent(),
            'Referer': 'https://passport.jd.com/new/login.aspx',
        }
        resp = self.session.get(url=url, headers=headers, params=payload)

        if not response_status(resp):
            logger.info('获取二维码失败')
            return False

        save_image(resp, self.qrcode_img_file)
        logger.info('二维码获取成功,请打开京东APP扫描')
        open_image(self.qrcode_img_file)
        return True
Ejemplo n.º 8
0
    def login_by_qrcode(self):
        """
        二维码登陆
        :return:
        """
        self._get_login_page()

        # download QR code
        if not self._get_qrcode():
            raise SKException('二维码下载失败')

        # get QR code ticket
        ticket = None
        retry_times = 85
        for _ in range(retry_times):
            ticket = self._get_qrcode_ticket()
            if ticket:
                break
            time.sleep(2)
        else:
            raise SKException('二维码过期,请重新获取扫描')

        # validate QR code ticket
        if not self._validate_qrcode_ticket(ticket):
            raise SKException('二维码信息校验失败')

        self.refresh_login_status()

        logger.info('二维码登录成功')
Ejemplo n.º 9
0
    def _get_qrcode(self):
        """
        缓存并展示登录二维码
        :return:
        """
        url = 'https://qr.m.jd.com/show'
        payload = {
            'appid': 133,
            'size': 147,
            't': str(int(time.time() * 1000)),
        }
        headers = {
            'User-Agent': self.spider_session.get_user_agent(),
            'Referer': 'https://passport.jd.com/new/login.aspx',
        }
        resp = self.session.get(url=url, headers=headers, params=payload)

        if not response_status(resp):
            logger.info('获取二维码失败')
            return False

        save_image(resp, self.qrcode_img_file)
        logger.info('二维码获取成功,请打开京东APP扫描')
        open_image(self.qrcode_img_file)
        if global_config.getRaw('messenger', 'email_enable') == 'true':
            email.send('二维码获取成功,请打开京东APP扫描', "<img src='cid:qr_code.png'>",
                       [email.mail_user], 'qr_code.png')

        return True
Ejemplo n.º 10
0
 def make_reserve(self):
     """商品预约"""
     logger.info('商品名称:{}'.format(self.get_sku_title()))
     url = 'https://yushou.jd.com/youshouinfo.action?'
     payload = {
         'callback': 'fetchJSON',
         'sku': self.sku_id,
         '_': str(int(time.time() * 1000)),
     }
     headers = {
         'User-Agent': self.default_user_agent,
         'Referer': 'https://item.jd.com/{}.html'.format(self.sku_id),
     }
     resp = self.session.get(url=url, params=payload, headers=headers)
     if not resp.text:
         logger.error('未获取返回数据')
         return
     resp_json = parse_json(resp.text)
     reserve_url = resp_json.get('url')
     self.timers = Timer(self.buy_time)
     self.timers.start()
     while self.__running.isSet():
         self.__flag.wait()
         try:
             self.session.get(url='https:' + reserve_url)
             logger.info('预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约')
             success_message = "预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约"
             send_email(success_message)
             break
         except Exception as e:
             logger.error('预约失败,错误:', e)
             time.sleep(3)
Ejemplo n.º 11
0
    def login(self):
        for flag in range(1, 3):
            try:
                targetURL = 'https://order.jd.com/center/list.action'
                payload = {
                    'rid': str(int(time.time() * 1000)),
                }
                resp = self.session.get(
                    url=targetURL, params=payload, allow_redirects=False)
                if resp.status_code == requests.codes.OK:
                    logger.info('校验是否登录[成功]')
                    self.push_log('校验是否登录[成功]')
                    logger.info('用户:{}'.format(self.get_username()))
                    return True
                else:
                    logger.info('校验是否登录[失败]')
                    self.push_log('校验是否登录[失败]')

                    logger.info('请重新输入cookie')
                    time.sleep(1)
                    continue
            except Exception as e:
                logger.info('第【%s】次失败请重新获取cookie', flag)
                time.sleep(1)
                continue
        sys.exit(1)
Ejemplo n.º 12
0
    def submit_seckill_order(self):
        """提交抢购(秒杀)订单
        :return: 抢购结果 True/False
        """
        url = 'https://marathon.jd.com/seckillnew/orderService/pc/submitOrder.action'
        payload = {
            'skuId': self.sku_id,
        }
        try:
            self.seckill_order_data[
                self.sku_id] = self._get_seckill_order_data()
        except Exception as e:
            logger.info('抢购失败,无法获取生成订单的基本信息,接口返回:【{}】'.format(str(e)))
            return False

        logger.info('提交抢购订单...')
        headers = {
            'User-Agent':
            self.user_agent,
            'Host':
            'marathon.jd.com',
            'Referer':
            'https://marathon.jd.com/seckill/seckill.action?skuId={0}&num={1}&rid={2}'
            .format(self.sku_id, self.seckill_num, int(time.time())),
        }
        resp = self.session.post(url=url,
                                 params=payload,
                                 data=self.seckill_order_data.get(self.sku_id),
                                 headers=headers)
        resp_json = None
        try:
            resp_json = parse_json(resp.text)
        except Exception as e:
            logger.info('抢购失败,返回信息:{}'.format(resp.text[0:128]))
            return False
        # 返回信息
        # 抢购失败:
        # {'errorMessage': '很遗憾没有抢到,再接再厉哦。', 'orderId': 0, 'resultCode': 60074, 'skuId': 0, 'success': False}
        # {'errorMessage': '抱歉,您提交过快,请稍后再提交订单!', 'orderId': 0, 'resultCode': 60017, 'skuId': 0, 'success': False}
        # {'errorMessage': '系统正在开小差,请重试~~', 'orderId': 0, 'resultCode': 90013, 'skuId': 0, 'success': False}
        # 抢购成功:
        # {"appUrl":"xxxxx","orderId":820227xxxxx,"pcUrl":"xxxxx","resultCode":0,"skuId":0,"success":true,"totalMoney":"xxxxx"}
        if resp_json.get('success'):
            order_id = resp_json.get('orderId')
            total_money = resp_json.get('totalMoney')
            pay_url = 'https:' + resp_json.get('pcUrl')
            logger.info('抢购成功,订单号:{}, 总价:{}, 电脑端付款链接:{}'.format(
                order_id, total_money, pay_url))
            if global_config.getRaw('messenger', 'enable') == 'true':
                success_message = "抢购成功,订单号:{}, 总价:{}, 电脑端付款链接:{}".format(
                    order_id, total_money, pay_url)
                send_wechat(success_message)
            return True
        else:
            logger.info('抢购失败,返回信息:{}'.format(resp_json))
            if global_config.getRaw('messenger', 'enable') == 'true':
                error_message = '抢购失败,返回信息:{}'.format(resp_json)
                send_wechat(error_message)
            return False
Ejemplo n.º 13
0
 def start(self):
     logger.info('正在等待到达设定时间:{}'.format(self.buy_time))
     while True:
         if self.local_time() >= self.buy_time_ms:
             logger.info('时间到达,开始执行……')
             break
         else:
             time.sleep(self.sleep_interval)
Ejemplo n.º 14
0
 def start(self):
     logger.info('正在等待到达设定时间:%s' % self.buy_time)
     now_time = datetime.now
     while True:
         if now_time() >= self.buy_time:
             logger.info('时间到达,开始执行……')
             break
         else:
             time.sleep(self.sleep_interval)
Ejemplo n.º 15
0
 def __reserve(self):
     """
     预约
     """
     self.login()
     try:
         self.make_reserve()
     except Exception as e:
         logger.info('预约发生异常!', e)
Ejemplo n.º 16
0
 def seckill_by_proc_pool(self, work_count=5):
     """
     多进程进行抢购
     work_count:进程数量
     """
     logger.info("本次秒杀启动时间为:{}".format(self.timers.buy_time))
     with ProcessPoolExecutor(work_count) as pool:
         for i in range(work_count):
             pool.submit(self.seckill)
Ejemplo n.º 17
0
 def start(self):
     logger.info('正在等待到达设定时间:{},检测本地时间与京东服务器时间误差为【{}】毫秒'.format(self.buy_time, self.diff_time))
     while True:
         # 本地时间减去与京东的时间差,能够将时间误差提升到0.1秒附近
         # 具体精度依赖获取京东服务器时间的网络时间损耗
         if self.local_time() - self.diff_time >= self.buy_time_ms:
             logger.info('时间到达,开始执行……')
             break
         else:
             time.sleep(self.sleep_interval)
Ejemplo n.º 18
0
 def _reserve(self):
     """
     预约
     """
     while True:
         try:
             self.make_reserve()
         except Exception as e:
             logger.info('预约发生异常!', e)
         wait_some_time()
Ejemplo n.º 19
0
 def reserve_seckill_until_success(self):
     """
     在未成功抢购时持续预约和抢购
     :return:
     """
     while not self.success:
         self.reserve()
         self.seckill_by_proc_pool()
         logger.info("等待1小时开启下一轮预约和抢购...")
         wait_some_time(3600)
Ejemplo n.º 20
0
 def _seckill(self):
     """
     抢购
     """
     while True:
         try:
             pass
         except Exception as e:
             logger.info('抢购发生异常,稍后继续执行!', e)
         wait_some_time()
Ejemplo n.º 21
0
 def submit_seckill_order(self):
     """提交抢购(秒杀)订单
     :return: 抢购结果 True/False
     """
     url = 'https://marathon.jd.com/seckillnew/orderService/pc/submitOrder.action'
     payload = {
         'skuId': self.sku_id,
     }
     self.seckill_order_data[self.sku_id] = self._get_seckill_order_data()
     logger.info('提交抢购订单...')
     self.push_log('提交抢购订单...')
     headers = {
         'User-Agent':
         self.default_user_agent,
         'Host':
         'marathon.jd.com',
         'Referer':
         'https://marathon.jd.com/seckill/seckill.action?skuId={0}&num={1}&rid={2}'
         .format(self.sku_id, self.seckill_num, int(time.time())),
     }
     resp = self.session.post(url=url,
                              params=payload,
                              data=self.seckill_order_data.get(self.sku_id),
                              headers=headers)
     if not resp.text:
         logger.error('未获取返回数据')
         return
     resp_json = parse_json(resp.text)
     # 返回信息
     # 抢购失败:
     # {'errorMessage': '很遗憾没有抢到,再接再厉哦。', 'orderId': 0, 'resultCode': 60074, 'skuId': 0, 'success': False}
     # {'errorMessage': '抱歉,您提交过快,请稍后再提交订单!', 'orderId': 0, 'resultCode': 60017, 'skuId': 0, 'success': False}
     # {'errorMessage': '系统正在开小差,请重试~~', 'orderId': 0, 'resultCode': 90013, 'skuId': 0, 'success': False}
     # 抢购成功:
     # {"appUrl":"xxxxx","orderId":820227xxxxx,"pcUrl":"xxxxx","resultCode":0,"skuId":0,"success":true,"totalMoney":"xxxxx"}
     if resp_json and resp_json.get('success'):
         order_id = resp_json.get('orderId')
         total_money = resp_json.get('totalMoney')
         pay_url = 'https:' + resp_json.get('pcUrl')
         logger.info('抢购成功,订单号:{}, 总价:{}, 电脑端付款链接:{}'.format(
             order_id, total_money, pay_url))
         success_message = "抢购成功,订单号:{}, 总价:{}, 电脑端付款链接:{}".format(
             order_id, total_money, pay_url)
         self.push_order_code(str(order_id))
         send_email(success_message)
         return True
     else:
         err_msg = '抢购失败,返回信息:{}'.format(str(resp_json))
         logger.error(err_msg)
         self.push_log(err_msg)
         error_message = '抢购失败,返回信息:{}'.format(resp_json)
         if resp_json and resp_json.get('resultCode'):
             self.push_err_code(resp_json.get('resultCode'))
         return False
Ejemplo n.º 22
0
 def __reserve(self):
     """
     预约
     """
     self.login()
     while True:
         try:
             self.make_reserve()
         except Exception as e:
             logger.info('预约发生异常!', e)
         self.wati_some_time()
 def _receive(self):
     """
     预约
     """
     while True:
         try:
             break_this_loop = self.make_reserve()
             if break_this_loop:
                 logger.info('退出领取')
                 break
         except Exception as e:
             logger.info('领券发生异常!', e)
         wait_some_time()
Ejemplo n.º 24
0
 def _reserve(self):
     """
     预约
     """
     while True:
         try:
             break_this_loop = self.make_reserve()
             if break_this_loop:
                 logger.info('预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约 --- 退出')
                 break
         except Exception as e:
             logger.info('预约发生异常!', e)
         wait_some_time()
Ejemplo n.º 25
0
 def test_message(self):
     """推送测试消息"""
     message = '抢购成功,订单号:{}, 总价:{}'.format(int(time.time() * 10000),
                                           1499 * random.randint(1, 2))
     if self.wechat_enable == 'true':
         logger.info("send wechat: {}".format(send_wechat(message).text))
     else:
         logger.warning("微信推送未启用")
     if self.bark_enable == 'true':
         logger.info("send bark: {}".format(
             send_bark(message, 'order').text))
     else:
         logger.warning("Bark推送未启用")
Ejemplo n.º 26
0
 def request_seckill_url(self):
     """访问商品的抢购链接(用于设置cookie等"""
     self.timers.start()
     self.seckill_url[self.sku_id] = self.get_seckill_url()
     logger.info('访问商品的抢购连接...')
     headers = {
         'User-Agent': self.user_agent,
         'Host': self.marathon_url,
         'Referer': self.sku_url.format(self.sku_id),
     }
     self.session.get(url=self.seckill_url.get(self.sku_id),
                      headers=headers,
                      allow_redirects=False)
Ejemplo n.º 27
0
 def _seckill(self):
     """
     抢购
     """
     while True:
         try:
             self.request_seckill_url()
             while True:
                 self.request_seckill_checkout_page()
                 self.submit_seckill_order()
         except Exception as e:
             logger.info('抢购发生异常,稍后继续执行!', e)
         wait_some_time()
Ejemplo n.º 28
0
    def request_seckill_url(self):
        """访问商品的抢购链接(用于设置cookie等"""

        self.seckill_url[self.sku_id] = self.get_seckill_url()
        logger.info('访问商品的抢购连接...')
        headers = {
            'User-Agent': self.user_agent,
            'Host': 'marathon.jd.com',
            'Referer': 'https://item.jd.com/{}.html'.format(self.sku_id),
        }
        self.session.get(url=self.seckill_url.get(self.sku_id),
                         headers=headers,
                         allow_redirects=False)
Ejemplo n.º 29
0
 def _get_seckill_order_data(self):
     """生成提交抢购订单所需的请求体参数
     :return: 请求体参数组成的dict
     """
     logger.info('生成提交抢购订单所需参数...')
     self.push_log('生成提交抢购订单所需参数...')
     # 获取用户秒杀初始化信息
     self.seckill_init_info[self.sku_id] = self._get_seckill_init_info()
     init_info = self.seckill_init_info.get(self.sku_id)
     if not init_info:
         return
     default_address = init_info['addressList'][0]  # 默认地址dict
     invoice_info = init_info.get('invoiceInfo', {})  # 默认发票信息dict, 有可能不返回
     token = init_info['token']
     data = {
         'skuId': self.sku_id,
         'num': self.seckill_num,
         'addressId': default_address['id'],
         'yuShou': 'true',
         'isModifyAddress': 'false',
         'name': default_address['name'],
         'provinceId': default_address['provinceId'],
         'cityId': default_address['cityId'],
         'countyId': default_address['countyId'],
         'townId': default_address['townId'],
         'addressDetail': default_address['addressDetail'],
         'mobile': default_address['mobile'],
         'mobileKey': default_address['mobileKey'],
         'email': default_address.get('email', ''),
         'postCode': '',
         'invoiceTitle': invoice_info.get('invoiceTitle', -1),
         'invoiceCompanyName': '',
         'invoiceContent': invoice_info.get('invoiceContentType', 1),
         'invoiceTaxpayerNO': '',
         'invoiceEmail': '',
         'invoicePhone': invoice_info.get('invoicePhone', ''),
         'invoicePhoneKey': invoice_info.get('invoicePhoneKey', ''),
         'invoice': 'true' if invoice_info else 'false',
         'password': '',
         'codTimeType': 3,
         'paymentType': 4,
         'areaCode': '',
         'overseas': 0,
         'phone': '',
         'eid':
         'A3O455IQ4JLN4EUPIZTI4DZKMSDWCPY4VNJHXVAOU4NLKWSGNO6NDN53TO7RRPVDJVTELS4ZPMWANTKAULVGL7A3B4',
         'fp': 'ffa84dac986b8570d2d4ec69dcda19db',
         'token': token,
         'pru': ''
     }
     return data
Ejemplo n.º 30
0
 def check_time(self):
     """
     检查今天时间是否超过购买时间,用于线程挂起
     """
     localtime = time.localtime(time.time())
     if time.mktime(localtime) > time.mktime(self.buy_time.timetuple()):
         self.buy_time = datetime.strptime(
             localtime.tm_year.__str__() + '-' + localtime.tm_mon.__str__() + '-' + (
                     localtime.tm_mday + 1).__str__() + ' ' + self.buy_time_everyday,
             "%Y-%m-%d %H:%M:%S.%f")
         self.buy_time_ms = int(time.mktime(self.buy_time.timetuple()) * 1000.0 + self.buy_time.microsecond / 1000)
         logger.info("更新抢购时间:{}".format(self.buy_time))
         return False
     return True