示例#1
0
def page_detail_captcha(session, isId):
    url = 'https://captcha.jd.com/verify/image'
    acid = '{}_{}'.format(random.random(), random.random())
    payload = {
        'acid': acid,
        'srcid': 'trackWeb',
        'is': isId,
    }
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/531.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        "Referer": "https://trade.jd.com/shopping/order/getOrderInfo.action",
        "Connection": "keep-alive",
        'Host': 'captcha.jd.com',
    }
    try:
        resp = session.get(url=url, params=payload, headers=headers)
        if not response_status(resp):
            logger.error('获取订单验证码失败')
            return ''
        logger.info('解析验证码开始')
        image = Image.open(BytesIO(resp.content))
        image.save('captcha.jpg')
        result = analysis_captcha(resp.content)
        if not result:
            logger.error('解析订单验证码失败')
            return ''
        global submit_captcha_text, submit_captcha_rid
        submit_captcha_text = result
        submit_captcha_rid = acid
        return result
    except Exception as e:
        logger.error('订单验证码获取异常:%s', e)
    return ''
示例#2
0
def check_stock():
    skuidString = ','.join(skuids)
    callback = 'jQuery' + str(random.randint(1000000, 9999999))
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/531.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        "Referer": "https://cart.jd.com/cart.action",
        "Connection": "keep-alive",
    }
    url = 'https://c0.3.cn/stocks'
    payload = {
        'type': 'getstocks',
        'skuIds': skuidString,
        'area': area,
        'callback': callback,
        '_': int(time.time() * 1000),
    }
    resp = checksession.get(url=url, params=payload, headers=headers)
    resptext = resp.text.replace(callback + '(', '').replace(')', '')
    respjson = json.loads(resptext)
    inStockSkuid = []
    nohasSkuid = []
    abnormalSkuid = []
    for i in skuids:
        try:
            if respjson[i]['StockStateName'] != '无货':
                inStockSkuid.append(i)
            else:
                nohasSkuid.append(i)
        except Exception as e:
            abnormalSkuid.append(i)
    logger.info('[%s]类型口罩无货', ','.join(nohasSkuid))
    if len(abnormalSkuid) > 0:
        logger.info('[%s]类型口罩查询异常', ','.join(abnormalSkuid))
    return inStockSkuid
    def _get_QRcode_ticket(self):
        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.default_user_agent,
            'Referer': 'https://passport.jd.com/new/login.aspx',
        }
        resp = self.session.get(url=url, headers=headers, params=payload)

        if not resp.ok:
            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_seckill_init_info(self):
     """获取秒杀初始化信息(包括:地址,发票,token)
     :return: 初始化信息组成的dict
     """
     for i in range(3):
         logger.info('获取秒杀初始化信息:{}次...'.format(i))
         url = 'https://marathon.jd.com/seckillnew/orderService/pc/init.action'
         data = {
             'sku': self.sku_id,
             'num': 1,
             'isModifyAddress': 'false',
         }
         headers = {
             'User-Agent': self.default_user_agent,
             'Host': 'marathon.jd.com',
         }
         resp = self.session.post(url=url, data=data, headers=headers)
         if not resp.ok:
             continue
         if resp.text == "null":
             continue
         if resp.text.find("{") != -1:
             break
         else:
             logger.info('获取秒杀初始化信息 respText:' + resp.text)
     return parse_json(resp.text)
    def login_by_QRcode(self):
        """二维码登陆
        :return:
        """
        if self.is_login:
            logger.info('登录成功')
            return

        self._get_login_page()

        # download QR code
        if not self._get_QRcode():
            logger.info('二维码下载失败')
            return

        # 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:
            logger.info('二维码过期,请重新获取扫描')
            return

        # validate QR code ticket
        if not self._validate_QRcode_ticket(ticket):
            logger.info('二维码信息校验失败')
            return
        logger.info('二维码登录成功')
        self.is_login = True
        self.nick_name = self.get_user_info()
示例#6
0
def fastMode():
    flag = 1
    while (1):
        try:
            if flag == 1:
                validate_cookies()
                getUsername()
                select_all_cart_item()
                remove_item()
            # modelType
            logger.info('第' + str(flag) + '次 ')
            flag += 1
            # 检测库存
            inStockSkuid = check_stock()
            # 下单任务
            fastModeAutoBuy(inStockSkuid)
            timesleep = random.randint(5, 10) / 10
            time.sleep(timesleep)
            if flag % 40 == 0:
                logger.info('校验是否还在登录')
                validate_cookies()
        except Exception as e:

            print(traceback.format_exc())
            time.sleep(10)
示例#7
0
 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': 1,
         'isModifyAddress': 'false',
     }
     headers = {
         'User-Agent': self.default_user_agent,
         'Host': 'marathon.jd.com',
     }
     #in request_seckill_url  sleep(0.1)  NameError: name 'sleep' is not defined  报错信息在这,调用time.sleep(0.1)
     #此处如果获取不到,会自动重定向,重定向会报错,这里去掉重定向
     while True:
         resp = self.session.post(url=url,
                                  data=data,
                                  headers=headers,
                                  allow_redirects=False)
         if len(resp.text) >= 100:
             break
         else:
             sleep(0.01)
     print(resp)
     return parse_json(resp.text)
示例#8
0
def remove_item():
    url = "https://cart.jd.com/batchRemoveSkusFromCart.action"
    data = {
        't': 0,
        'null': '',
        'outSkus': '',
        'random': random.random(),
        'locationId': '19-1607-4773-0'
    }
    headers = {
        "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.37",
        "Accept": "application/json, text/javascript, */*; q=0.01",
        "Referer": "https://cart.jd.com/cart.action",
        "Host": "cart.jd.com",
        "Content-Type": "application/x-www-form-urlencoded",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Encoding": "zh-CN,zh;q=0.9,ja;q=0.8",
        "Origin": "https://cart.jd.com",
        "Connection": "keep-alive"
    }
    resp = session.post(url, data=data, headers=headers)
    logger.info('清空购物车')
    if resp.status_code != requests.codes.OK:
        print('Status: %u, Url: %s' % (resp.status_code, resp.url))
        return False
    return True
示例#9
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.default_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("抢购链接获取失败,%s不是抢购商品或抢购页面暂未刷新,0.5秒后重试")
             time.sleep(0.1)
示例#10
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
示例#11
0
 def make_reserve(self):
     """商品预约"""
     logger.info('商品名称:{}'.format(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)
     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('预约失败正在重试...')
 def make_reserve(self):
     """商品预约"""
     logger.info('商品名称:{}'.format(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),
     }
     print("payload" + json.dumps(payload) + "\n" + "headers" +
           json.dumps(headers))
     resp = self.session.get(url=url, params=payload, headers=headers)
     print(resp)
     resp_json = parse_json(resp.text)
     reserve_url = resp_json.get('url')
     for flag in range(10):
         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('预约失败正在重试...' + str(flag) + " " + str(e))
             sleep(random.randint(1, 3))
     sys.exit(1)
示例#13
0
def V3check(skuId):
    select_all_cart_item()
    remove_item()
    validate_cookies()
    logger.info('校验是否还在登录')
    add_item_to_cart(skuId)
    if not item_removed(skuId):
        logger.info('[%s]已下柜商品', skuId)
示例#14
0
def check_Config():
    global configMd5, configTime
    nowMd5 = getconfigMd5()
    configTime = time.time()
    if not nowMd5 == configMd5:
        logger.info('配置文件修改,重新读取文件')
        getconfig()
        configMd5 = nowMd5
示例#15
0
    def get_seckill_url(self):
        """获取商品的抢购链接
        点击"抢购"按钮后,会有两次302跳转,最后到达订单结算页面
        这里返回第一次跳转后的页面url,作为商品的抢购链接
        :return: 商品的抢购链接
        """

        url = 'https://item-soa.jd.com/getWareBusiness'

        payload = {
            'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)),
            'skuId': self.sku_id,
            '_': str(int(time.time() * 1000)),
        }
        headers = {
            'User-Agent':
            self.default_user_agent,
            # 'Host': 'item-soa.jd.com',
            'Referer':
            'https://item.jd.com/',
            'authority':
            'item-soa.jd.com',
            'scheme':
            'https',
            'method':
            'GET',
            'num':
            '1',
            'path':
            '/getWareBusiness?callback=' + payload['callback'] + '&skuId=' +
            self.sku_id,
        }
        tryTime = 0
        while True and tryTime < 20:
            # self.session.mount('https://cart.jd.com/', HTTP20Adapter())
            # 加购物车
            resp = self.session.get(url=url, headers=headers, params=payload)
            resp_json = parse_json(resp.text)
            yuyueInfo = resp_json.get('yuyueInfo')
            if yuyueInfo is not None and yuyueInfo.get('state') == 4:
                cookies = self.session.cookies
                url = 'https://cart.jd.com/gate.action?pcount=1&ptype=1&pid=' + self.sku_id
                resp = requests.get(url, cookies=cookies)
                return resp.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("抢购链接获取失败,%s不是抢购商品或抢购页面暂未刷新,0.1秒后重试")
                time.sleep(0.2)

            tryTime = tryTime + 1
示例#16
0
 def start(self):
     logger.info('正在等待到达设定时间:%s' % self.buy_time)
     now_time_local = datetime.now
     while True:
         now_time = datetime.fromtimestamp(self.getTime())
         if now_time >= self.buy_time or now_time_local() >= self.buy_time:
             logger.info('时间到达,开始执行……')
             break
         else:
             time.sleep(self.sleep_interval)
示例#17
0
 def start(self):
     logger.info('正在等待到达设定时间:%s' % self.buy_time)
     now_time = datetime.now
     print(now_time())
     while True:
         if now_time() >= self.buy_time:
             logger.info('时间到达,开始执行……')
             break
         else:
             time.sleep(self.sleep_interval)
示例#18
0
 def request_seckill_checkout_page(self):
     """访问抢购订单结算页面"""
     logger.info('访问抢购订单结算页面...')
     url = 'https://marathon.jd.com/seckill/seckill.action'
     payload = {'skuId': self.sku_id, 'num': 1, 'rid': int(time.time())}
     headers = {
         'User-Agent': self.default_user_agent,
         'Host': 'marathon.jd.com',
         'Referer': 'https://item.jd.com/{}.html'.format(self.sku_id),
     }
     self.session.get(url=url, params=payload, headers=headers)
示例#19
0
def normalModeAutoBuy(inStockSkuid):
    for skuId in inStockSkuid:
        if item_removed(skuId):
            logger.info('[%s]类型口罩有货啦!马上下单', skuId)
            skuidUrl = 'https://item.jd.com/' + skuId + '.html'
            if normalModeBuyMask(skuId):
                message.send(skuidUrl, True)
                sys.exit(1)
            else:
                message.send(skuidUrl, False)
        else:
            logger.info('[%s]类型口罩有货,但已下柜商品', skuId)
 def _get_seckill_order_data(self):
     """生成提交抢购订单所需的请求体参数
     :return: 请求体参数组成的dict
     """
     logger.info('生成提交抢购订单所需参数...')
     # 获取用户秒杀初始化信息
     try:
         self.seckill_init_info[self.sku_id] = self._get_seckill_init_info()
         init_info = self.seckill_init_info.get(self.sku_id)
         if init_info == None:
             return None
         default_address = init_info['addressList'][0]  # 默认地址dict
         invoice_info = init_info.get('invoiceInfo', {})  # 默认发票信息dict, 有可能不返回
         token = init_info['token']
         data = {
             'skuId': self.sku_id,
             'num': 1,
             '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': global_config.getRaw('config', 'eid'),
             'fp': global_config.getRaw('config', 'fp'),
             'token': token,
             'pru': ''
         }
         return data
     except Exception as e:
         logger.error('获取用户秒杀初始化信息失败{0},正在重试...'.format(e))
         return None
示例#21
0
def get_checkout_page_detail():
    """获取订单结算页面信息

    该方法会返回订单结算页面的详细信息:商品名称、价格、数量、库存状态等。

    :return: 结算信息 dict
    """
    url = 'http://trade.jd.com/shopping/order/getOrderInfo.action'
    # url = 'https://cart.jd.com/gotoOrder.action'
    payload = {
        'rid': str(int(time.time() * 1000)),
    }
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/531.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        "Referer": "https://cart.jd.com/cart.action",
        "Connection": "keep-alive",
        'Host': 'trade.jd.com',
    }
    try:
        resp = session.get(url=url, params=payload, headers=headers)
        if not response_status(resp):
            logger.error('获取订单结算页信息失败')
            return ''
        if '刷新太频繁了' in resp.text:
            return '刷新太频繁了'
        soup = BeautifulSoup(resp.text, "html.parser")
        showCheckCode = get_tag_value(soup.select('input#showCheckCode'), 'value')
        if not showCheckCode:
            pass
        else:
            if showCheckCode == 'true':
                logger.info('提交订单需要验证码')
                global is_Submit_captcha, encryptClientInfo
                encryptClientInfo = get_tag_value(soup.select('input#encryptClientInfo'), 'value')
                is_Submit_captcha = True
        risk_control = get_tag_value(soup.select('input#riskControl'), 'value')

        order_detail = {
            'address': soup.find('span', id='sendAddr').text[5:],  # remove '寄送至: ' from the begin
            'receiver': soup.find('span', id='sendMobile').text[4:],  # remove '收件人:' from the begin
            'total_price': soup.find('span', id='sumPayPriceId').text[1:],  # remove '¥' from the begin
            'items': []
        }

        logger.info("下单信息:%s", order_detail)
        return risk_control
    except requests.exceptions.RequestException as e:
        logger.error('订单结算页面获取异常:%s' % e)
    except Exception as e:
        logger.error('下单页面数据解析异常:%s', e)
    return ''
示例#22
0
def parse_json(text):
    try:
        begin = text.find('{')
        end = text.rfind('}') + 1
        return json.loads(text[begin:end])
    except Exception as e:
        logger.error('parse_json error:{0}'.format(e))
        try:
            return json.loads(text)
        except Exception as ex:
            logger.error('parse_json error:{0}'.format(ex))
            logger.info('resp json string:' + text)
            return None
示例#23
0
def analysis_captcha(pic):
    for i in range(1, 10):
        try:
            url = captchaUrl
            resp = session.post(url, pic)
            if not response_status(resp):
                logger.error('解析验证码失败')
                continue
            logger.info('解析验证码[%s]', resp.text)
            return resp.text
        except Exception as e:
            print(traceback.format_exc())
            continue
    return ''
示例#24
0
def validate_cookies():
    for flag in range(1, 3):
        try:
            targetURL = 'https://order.jd.com/center/list.action'
            payload = {
                'rid': str(int(time.time() * 1000)),
            }
            resp = session.get(url=targetURL,
                               params=payload,
                               allow_redirects=False)
            if resp.status_code == requests.codes.OK:
                logger.info('登录成功')
                return True
            else:
                logger.info('第【%s】次请重新获取cookie', flag)
                time.sleep(5)
                continue
        except Exception as e:
            logger.info('第【%s】次请重新获取cookie', flag)
            time.sleep(5)
            continue
    wx_info = 'Cookie失效了!请及时更新!'
    data = {'text': '警告', 'desp': wx_info}
    requests.post('微信接口', data=data)
    logger.info('Cookie失效通知已发送微信!')
示例#25
0
文件: jdBuyMask.py 项目: linechina/jd
def getUsername():
    userName_Url = 'https://passport.jd.com/new/helloService.ashx?callback=jQuery339448&_=' + str(
        int(time.time() * 1000))
    session.headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/531.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        "Referer": "https://order.jd.com/center/list.action",
        "Connection": "keep-alive"
    }
    resp = session.get(url=userName_Url, allow_redirects=True)
    resultText = resp.text
    resultText = resultText.replace('jQuery339448(', '')
    resultText = resultText.replace(')', '')
    usernameJson = json.loads(resultText)
    logger.info('登录账号名称' + usernameJson['nick'])
示例#26
0
def V3AutoBuy(inStockSkuid):
    if skuId in inStockSkuid:
        global submit_Time
        submit_Time = int(time.time() * 1000)
        logger.info('[%s]类型口罩有货啦!马上下单', skuId)
        skuidUrl = 'https://item.jd.com/' + skuId + '.html'
        if buyMask(skuId):
            message.send(skuidUrl, True)
            sys.exit(1)
        else:
            if item_removed(skuId):
                message.send(skuidUrl, False)
            else:
                logger.info('[%s]已下柜商品', skuId)
                sys.exit(1)
示例#27
0
def fastModeAutoBuy(inStockSkuid):
    for skuId in inStockSkuid:
        logger.info('[%s]类型口罩有货啦!马上下单', skuId)
        skuidUrl = 'https://item.jd.com/' + skuId + '.html'
        if fastModeBuyMask(skuId):
            message.send(skuidUrl, True)
            sys.exit(1)
        else:
            if item_removed(skuId):
                message.send(skuidUrl, False)
            else:
                logger.info('[%s]商品已下柜,商品列表中踢出')
                skuids.remove(skuId)
            select_all_cart_item()
            remove_item()
示例#28
0
def real_time():
    jd_headers={
    "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36",
    }
    global Info
    flag = 1
    while True:
        try:
            if flag == 1:
            	   # 检测Cookie有效性
                validate_cookies()
                # 获取京东账户名
                getUsername()
            # 记录检测次数
            flag += 1
            # 检测列表所有链接
            for url1 in jd_url_list:
                req = requests.get(url1, headers=jd_headers, timeout=10)
                # 提取出商品实际链接
                jd_url = "https://item.jd.com/"+ url1.split('skuId=')[1].split('&')[0]+'.html'
                if req.text.find('无货') > 0:
                    print ('[%s]--无货...'%jd_url)
                else:
                	 # 将信息写到日志文件中
                    logger.info('[%s]--有货!!!'%jd_url)
                    # 购买商品,购买异常则退出
                    if buyMask(url1.split('skuId=')[1].split('&')[0]):
                        sys.exit(1)
                    # Info存储到货的商品链接
                    Info = jd_url
        except Exception as e:
            print (str(e))
        if Info != '':
            # 微信信息
            wx_info = '口罩有货了!点击进入:'+'['+Info+']'+'('+Info+')'
            data = {'text': '口罩有货了', 'desp': wx_info}
            # 在Server酱中绑定微信获取
            requests.post('server酱微信接口', data=data)
            # 对列表中的邮箱发送邮件
            for mailto_list in mailto_lists:
                send_mail(mailto_list)
            Info = ''
        time.sleep(5)
        # 每检测20次,就检查一次cookie的有效性
        if flag % 20 == 0:
            logger.info('校验是否还在登录')
            validate_cookies()
    def _validate_QRcode_ticket(self, ticket):
        url = 'https://passport.jd.com/uc/qrCodeTicketValidation'
        headers = {
            'User-Agent': self.default_user_agent,
            'Referer': 'https://passport.jd.com/uc/login?ltype=logout',
        }
        resp = self.session.get(url=url, headers=headers, params={'t': ticket})

        if not resp.ok:
            return False
        resp_json = parse_json(resp.text)
        if resp_json['returnCode'] == 0:
            return True
        else:
            logger.info(resp_json)
            return False
示例#30
0
def cart_detail():
    url = 'https://cart.jd.com/cart.action'
    headers = {
        "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/531.36",
        "Accept":
        "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        "Referer": "https://order.jd.com/center/list.action",
        "Host": "cart.jd.com",
        "Connection": "keep-alive"
    }
    resp = session.get(url, headers=headers)
    soup = BeautifulSoup(resp.text, "html.parser")

    cart_detail = dict()
    for item in soup.find_all(class_='item-item'):
        try:
            sku_id = item['skuid']  # 商品id
        except Exception as e:
            logger.info('购物车中有套装商品,跳过')
            continue
        try:
            # 例如:['increment', '8888', '100001071956', '1', '13', '0', '50067652554']
            # ['increment', '8888', '100002404322', '2', '1', '0']
            item_attr_list = item.find(class_='increment')['id'].split('_')
            p_type = item_attr_list[4]
            promo_id = target_id = item_attr_list[-1] if len(
                item_attr_list) == 7 else 0

            cart_detail[sku_id] = {
                'name': get_tag_value(item.select('div.p-name a')),  # 商品名称
                'verder_id': item['venderid'],  # 商家id
                'count': int(item['num']),  # 数量
                'unit_price':
                get_tag_value(item.select('div.p-price strong'))[1:],  # 单价
                'total_price':
                get_tag_value(item.select('div.p-sum strong'))[1:],  # 总价
                'is_selected': 'item-selected' in item['class'],  # 商品是否被勾选
                'p_type': p_type,
                'target_id': target_id,
                'promo_id': promo_id
            }
        except Exception as e:
            logger.error("商品%s在购物车中的信息无法解析,报错信息: %s,该商品自动忽略", sku_id, e)

    logger.info('购物车信息:%s', cart_detail)
    return cart_detail