def _get_QRcode_ticket(self): url = 'https://qr.m.jd.com/check' payload = { 'appid': '133', 'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)), 'token': self.sess.cookies.get('wlfstk_smdl'), '_': str(int(time.time() * 1000)), } headers = { 'User-Agent': USER_AGENT, 'Referer': 'https://passport.jd.com/new/login.aspx', } resp = self.sess.get(url=url, headers=headers, params=payload) if not response_status(resp): print(get_current_time(), '获取二维码扫描结果出错') return False resp_json = parse_json(resp.text) if resp_json['code'] != 200: print( get_current_time(), 'Code: {0}, Message: {1}'.format(resp_json['code'], resp_json['msg'])) return None else: print(get_current_time(), '已完成手机客户端确认') return resp_json['ticket']
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)
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 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)) self.running_flag = False 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
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', } resp = self.session.post(url=url, data=data, headers=headers) #logger.info("秒杀初始化信息.: " + json.dumps(resp)) resp_json = None try: #print(resp.text) resp_json = parse_json(resp.text) except Exception: raise SKException('抢购失败,返回信息:{}'.format(resp.text[0:128])) return resp_json
def get_username(self): """获取用户信息""" url = 'https://passport.jd.com/user/petName/getUserInfoForMiniJd.action' payload = { 'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)), '_': str(int(time.time() * 1000)), } headers = { 'User-Agent': self.user_agent, 'Referer': 'https://order.jd.com/center/list.action', } resp = self.session.get(url=url, params=payload, headers=headers) try_count = 5 while not resp.text.startswith("jQuery"): try_count = try_count - 1 if try_count > 0: resp = self.session.get(url=url, params=payload, headers=headers) else: break wait_some_time() # 响应中包含了许多用户信息,现在在其中返回昵称 # jQuery2381773({"imgUrl":"//storage.360buyimg.com/i.imageUpload/xxx.jpg","lastLoginTime":"","nickName":"xxx","plusStatus":"0","realName":"xxx","userLevel":x,"userScoreVO":{"accountScore":xx,"activityScore":xx,"consumptionScore":xxxxx,"default":false,"financeScore":xxx,"pin":"xxx","riskScore":x,"totalScore":xxxxx}}) return parse_json(resp.text).get('nickName')
def run(self): message = '' while True: try: self.send_responses() except socket.error: break try: data = self.s.recv(1024) except socket.timeout: continue except: data = '' if not data: break message += data while True: cmd, message = parse_json(message) if not cmd: break self.process(cmd) self.server.remove_client(self)
def make_reserve(self,lineName,stationName,enterDate,timeSlot): """地铁预约 :param lineName: 几号线(昌平线) :param stationName: 地铁站名(沙河站) :param enterDate: 预约日期 :param timeSlot: 时间段(0730-0740) :return:bool """ url = BASE_URL+"/Appointment/CreateAppointment" data = {"lineName": lineName, "snapshotWeekOffset": 0, "stationName": stationName, "enterDate": enterDate, "snapshotTimeSlot": "0630-0930", "timeSlot": timeSlot} result = requests.post(url, json=data, headers=self.header,verify=False) resp_json =parse_json(result.text) try: if(resp_json['balance']<=0): logger.error("本次预约失败:无票可抢。余额:%s",resp_json['balance']) if self.send_message: self.messenger.send(text='预约失败:%s' % result.text) return False logger.info(result.text) if self.send_message: self.messenger.send(text='预约成功:%s' % result.text) return True except KeyError: logger.error("无法预约,请检查错误:%s",result.text) return False
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 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不是抢购商品或抢购页面暂未刷新,1秒后重试") time.sleep(1)
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
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)
def parse_cli(self, args=None): # explicitly set cmd-line options, parsed according to default parser super(FrameworkCLIHandler, self).parse_cli(args) cli_opts = self.config # default values only, from running default parser on empty input defaults = vars(self.parser.parse_args([])) chained_dict_list = [cli_opts, defaults] # deal with options set in user-specified file, if present config_path = cli_opts.get('config_file', None) file_str = '' if config_path: try: with open(config_path, 'r') as f: file_str = f.read() except Exception: print( "ERROR: Can't read config file at {}.".format(config_path)) if file_str: try: file_opts = util.parse_json(file_str) # overwrite default case_list and pod_list, if given if 'case_list' in file_opts: self.case_list = file_opts.pop('case_list') if 'pod_list' in file_opts: self.pod_list = file_opts.pop('pod_list') if 'argument_groups' in file_opts or 'arguments' in file_opts: # assume config_file is a modified copy of the defaults, # with options to define parser. Set up the parser and run # CLI arguments through it (instead of default). # Don't error on unrecognized args here, since those will be # caught by the default parser. custom_parser = self.make_parser(file_opts) chained_dict_list = [ # CLI parsed with config_file's parser vars(custom_parser.parse_known_args()[0]), # defaults set in config_file's parser vars(custom_parser.parse_known_args([])[0]) ] + chained_dict_list else: # assume config_file a JSON dict of option:value pairs. file_opts = { self.canonical_arg_name(k): v for k, v in file_opts.iteritems() } chained_dict_list = [cli_opts, file_opts, defaults] except Exception: if 'json' in os.path.splitext('config_path')[1].lower(): print("ERROR: Couldn't parse JSON in {}.".format( config_path)) raise # assume config_file is a plain text file containing flags, etc. # as they would be passed on the command line. file_str = util.strip_comments(file_str, '#') file_opts = vars(self.parser.parse_args(shlex.split(file_str))) chained_dict_list = [cli_opts, file_opts, defaults] # CLI opts override options set from file, which override defaults self.config = dict(ChainMap(*chained_dict_list))
def get_download_url(repo_url, sha=None, branch=None): repo_fullname = "/".join(repo_url.split("/")[-2:]) if sha: return f'https://github.com/{repo_fullname}/archive/{sha}.zip' else: if branch is None: branch = util.parse_json(get_api(repo_url))['default_branch'] return f'https://github.com/{repo_fullname}/archive/{branch}.zip'
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
def get_multi_item_stock(self, sku_ids, area): """获取多个商品库存状态 该方法需要登陆才能调用,用于同时查询多个商品的库存。 京东查询接口返回每种商品的状态:有货/无货。当所有商品都有货,返回True;否则,返回False。 :param sku_ids: 多个商品的id。可以传入中间用英文逗号的分割字符串,如"123,456";或传入商品列表,如["123", "456"] :param area: 地区id :return: 多个商品是否同时有货 True/False """ if not isinstance(sku_ids, list): sku_ids = parse_sku_id(sku_ids=sku_ids) area_code = parse_area_id(area) url = 'https://trade.jd.com/api/v1/batch/stock' headers = { 'User-Agent': USER_AGENT, 'Origin': 'https://trade.jd.com', 'Content-Type': 'application/json; charset=UTF-8', 'Referer': 'https://trade.jd.com/shopping/order/getOrderInfo.action?rid=' + str(int(time.time() * 1000)), } data = { "areaRequest": { "provinceId": area_code[0], "cityId": area_code[1], "countyId": area_code[2], "townId": area_code[3] }, "skuNumList": [] } for sku_id in sku_ids: data['skuNumList'].append({"skuId": sku_id, "num": "1"}) # convert to string data = json.dumps(data) resp = self.sess.post(url=url, headers=headers, data=data) resp_json = parse_json(resp.text) result = resp_json.get('result') stock = True for sku_id in result: status = result.get(sku_id).get('status') if '无货' in status: stock = False break return stock
def get_item_price(self, sku_id): """获取商品价格 :param sku_id: 商品id :return: 价格 """ url = 'http://p.3.cn/prices/mgets' payload = { 'type': 1, 'pduid': int(time.time() * 1000), 'skuIds': 'J_' + sku_id, } resp = self.sess.get(url=url, params=payload) return parse_json(resp.text).get('p')
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) resp_text = self.session.get(url='https:' + reserve_url).text resp_html = etree.HTML(resp_text) result_msg = "".join([ t.strip() for t in resp_html.xpath( "//div[@class='bd-right']/./*[@class='bd-right-result']/text()" ) ]) if len( resp_html.xpath( "//div[@class='bd-right']/./*[@class='bd-right-result']/text()" )) > 0 else "未匹配到预约消息" if "预约成功" in resp_text: logger.info('预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约') logger.info(result_msg) self.reserve_statue = True if global_config.getRaw('messenger', 'enable') == 'true': success_message = "预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约" send_wechat(success_message) break elif "预约失败" in resp_text: logger.info('预约失败,超过最大购买数量/已经预约过!') logger.info(result_msg) self.reserve_statue = True break else: logger.info('预约返回其他未知提示!') logger.info(result_msg) self.reserve_statue = True break except Exception as e: logger.error('预约失败正在重试...', e)
def _get_reserve_url(self, sku_id): url = 'https://yushou.jd.com/youshouinfo.action' payload = { 'callback': 'fetchJSON', 'sku': sku_id, } headers = { 'User-Agent': USER_AGENT, 'Referer': 'https://item.jd.com/{}.html'.format(sku_id), } resp = self.sess.get(url=url, params=payload, headers=headers) resp_json = parse_json(resp.text) # {"type":"1","hasAddress":false,"riskCheck":"0","flag":false,"num":941723,"stime":"2018-10-12 12:40:00","plusEtime":"","qiangEtime":"","showPromoPrice":"0","qiangStime":"","state":2,"sku":100000287121,"info":"\u9884\u7ea6\u8fdb\u884c\u4e2d","isJ":0,"address":"","d":48824,"hidePrice":"0","yueEtime":"2018-10-19 15:01:00","plusStime":"","isBefore":0,"url":"//yushou.jd.com/toYuyue.action?sku=100000287121&key=237af0174f1cffffd227a2f98481a338","etime":"2018-10-19 15:01:00","plusD":48824,"category":"4","plusType":0,"yueStime":"2018-10-12 12:40:00"}; reserve_url = resp_json.get('url') return 'https:' + reserve_url if reserve_url else None
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
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('预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约') requests.post( "https://sc.ftqq.com/SCU67992Tb6d106e75a7e8fa6f00c53c9bf7f7bb05de8bce100ce2.send", data={ "text": "茅台预约成功啦", "desp": """茅台预约成功啦 ![image](https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1601019829813&di=f40ea308a5fb36b99d793cd74785b24c&imgtype=0&src=http%3A%2F%2Fpic.feizl.com%2Fupload%2Fallimg%2F170704%2F4881tnxkewt5mq.jpg) """ }) if global_config.getRaw('messenger', 'enable') == 'true': success_message = "预约成功,已获得抢购资格 / 您已成功预约过了,无需重复预约" send_wechat(success_message) requests.post( "https://sc.ftqq.com/SCU67992Tb6d106e75a7e8fa6f00c53c9bf7f7bb05de8bce100ce2.send", data={ "text": "茅台预约成功啦", "desp": """茅台预约成功啦 ![image](https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1601019829813&di=f40ea308a5fb36b99d793cd74785b24c&imgtype=0&src=http%3A%2F%2Fpic.feizl.com%2Fupload%2Fallimg%2F170704%2F4881tnxkewt5mq.jpg) """ }) break except Exception as e: logger.error('预约失败正在重试...')
def submit_seckill_order(self, sku_id, num=1): """提交抢购(秒杀)订单 :param sku_id: 商品id :param num: 购买数量,可选参数,默认1个 :return: 抢购结果 True/False """ url = 'https://marathon.jd.com/seckillnew/orderService/pc/submitOrder.action' payload = { 'skuId': sku_id, } if not self.seckill_order_data.get(sku_id): self.seckill_order_data[sku_id] = self._gen_seckill_order_data( sku_id, num) headers = { 'User-Agent': USER_AGENT, 'Host': 'marathon.jd.com', 'Referer': 'https://marathon.jd.com/seckill/seckill.action?skuId={0}&num={1}&rid={2}' .format(sku_id, num, int(time.time())), } resp = self.sess.post(url=url, params=payload, data=self.seckill_order_data.get(sku_id), headers=headers) 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.get('success'): order_id = resp_json.get('orderId') total_money = resp_json.get('totalMoney') pay_url = 'https:' + resp_json.get('pcUrl') print( get_current_time(), '抢购成功,订单号: {0}, 总价: {1}, 电脑端付款链接: {2}'.format( order_id, total_money, pay_url)) return True else: print(get_current_time(), '抢购失败,返回信息: {}'.format(resp_json)) return False
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', } resp = self.session.post(url=url, data=data, headers=headers) return parse_json(resp.text)
def parse_cli(self, args=None): # explicitly set cmd-line options, parsed according to default parser; # result stored in self.config self.preparse_cli(args) # handle positionals here because we need to find input_file self.parse_positionals('input_file') self.parse_positionals('root_dir') # deal with options set in user-specified defaults file, if present config_path = self.config.get('INPUT_FILE', None) config_str = '' if config_path: try: with open(config_path, 'r') as f: config_str = f.read() except Exception: print( "ERROR: Can't read input file at {}.".format(config_path)) if config_str: try: file_input = util.parse_json(config_str) # overwrite default case_list and pod_list, if given if 'case_list' in file_input: self.case_list = file_input.pop('case_list') if 'pod_list' in file_input: self.pod_list = file_input.pop('pod_list') # assume config_file a JSON dict of option:value pairs. self.partial_defaults = [{ self.canonical_arg_name(k): v for k, v in file_input.iteritems() }] except Exception: if 'json' in os.path.splitext('config_path')[1].lower(): print("ERROR: Couldn't parse JSON in {}.".format( config_path)) raise # assume config_file is a plain text file containing flags, etc. # as they would be passed on the command line. config_str = util.strip_comments(config_str, '#') self.partial_defaults = [ vars(self.parser.parse_args(shlex.split(config_str))) ] # CLI opts override options set from file, which override defaults super(FrameworkCLIHandler, self).parse_cli(args)
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: if datetime.now().strftime("%H:%M:%S") >= "10:08:00": logger.info("时间到10:08了,放弃吧") requests.post( "https://sc.ftqq.com/SCU67992Tb6d106e75a7e8fa6f00c53c9bf7f7bb05de8bce100ce2.send", data={ "text": "茅台抢购失败,时间到了", "desp": """茅台抢购失败,时间到了 ![image](https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1601019829813&di=f40ea308a5fb36b99d793cd74785b24c&imgtype=0&src=http%3A%2F%2Fpic.feizl.com%2Fupload%2Fallimg%2F170704%2F4881tnxkewt5mq.jpg) """ }) break 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()
def __init__(self, circuits): circuits = util.parse_json(circuits) self.name = circuits["name"] self.circuits = [] for circuit in circuits["circuits"]: garbled_circuit = yao.GarbledCircuit(circuit) pbits = garbled_circuit.get_pbits() entry = { "circuit": circuit, "garbled_circuit": garbled_circuit, "garbled_tables": garbled_circuit.get_garbled_tables(), "keys": garbled_circuit.get_keys(), "pbits": pbits, "pbits_out": {w: pbits[w] for w in circuit["out"]}, } self.circuits.append(entry)
def _get_seckill_init_info(self, sku_id, num=1): """获取秒杀初始化信息(包括:地址,发票,token) :param sku_id: :param num: 购买数量,可选参数,默认1个 :return: 初始化信息组成的dict """ url = 'https://marathon.jd.com/seckillnew/orderService/pc/init.action' data = { 'sku': sku_id, 'num': num, 'isModifyAddress': 'false', } headers = { 'User-Agent': USER_AGENT, 'Host': 'marathon.jd.com', } resp = self.sess.post(url=url, data=data, headers=headers) return parse_json(resp.text)
def run_tcp(self): try: # if self.use_ssl: self.s.do_handshake() message = "" while self.is_connected: try: timeout = False msg = self.s.recv(1024) except socket.timeout: timeout = True except ssl.SSLError: timeout = True except socket.error, err: if err.errno == 60: timeout = True elif err.errno in [11, 10035]: print_error("socket errno", err.errno) time.sleep(0.1) continue else: traceback.print_exc(file=sys.stdout) raise if timeout: # ping the server with server.version, as a real ping does not exist yet self.send([("server.version", [ELECTRUM_VERSION, PROTOCOL_VERSION])], self.on_version) continue message += msg self.bytes_received += len(msg) if msg == "": self.is_connected = False while True: response, message = parse_json(message) if response is None: break self.process_response(response) except Exception: traceback.print_exc(file=sys.stdout) self.is_connected = False
def check_stock(checksession, skuids, area): start = int(time.time() * 1000) 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", "Host": "c0.3.cn" } # 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) inStockSkuid = [] nohasSkuid = [] unUseSkuid = [] for sku_id, info in parse_json(resp.text).items(): sku_state = info.get('skuState') # 商品是否上架 stock_state = info.get('StockState') # 商品库存状态 if sku_state == 1 and stock_state in (33, 40): inStockSkuid.append(sku_id) if sku_state == 0: unUseSkuid.append(sku_id) if stock_state == 34: nohasSkuid.append(sku_id) logger.info('检测[%s]个口罩有货,[%s]个口罩无货,[%s]个口罩下柜,耗时[%s]ms', len(inStockSkuid), len(nohasSkuid), len(unUseSkuid), int(time.time() * 1000) - start) if len(unUseSkuid) > 0: logger.info('[%s]口罩已经下柜', ','.join(unUseSkuid)) return inStockSkuid
def get_username(self): """获取用户信息""" url = 'https://passport.jd.com/user/petName/getUserInfoForMiniJd.action' payload = { 'callback': 'jQuery'.format(random.randint(1000000, 9999999)), '_': str(int(time.time() * 1000)), } headers = { 'User-Agent': self.default_user_agent, 'Referer': 'https://order.jd.com/center/list.action', } try: resp = self.session.get(url=url, params=payload, headers=headers).enconde("utf-8","ignore").decode("latin1") print(resp.text) resp_json = parse_json(resp.text) # 响应中包含了许多用户信息,现在在其中返回昵称 # jQuery2381773({"imgUrl":"//storage.360buyimg.com/i.imageUpload/xxx.jpg","lastLoginTime":"","nickName":"xxx","plusStatus":"0","realName":"xxx","userLevel":x,"userScoreVO":{"accountScore":xx,"activityScore":xx,"consumptionScore":xxxxx,"default":false,"financeScore":xxx,"pin":"xxx","riskScore":x,"totalScore":xxxxx}}) return resp_json.get('nickName') or 'jd' except Exception: return 'jd'
def get_user_info(self): """获取用户信息 :return: 用户名 """ url = 'https://passport.jd.com/user/petName/getUserInfoForMiniJd.action' payload = { 'callback': 'jQuery{}'.format(random.randint(1000000, 9999999)), '_': str(int(time.time() * 1000)), } headers = { 'User-Agent': USER_AGENT, 'Referer': 'https://order.jd.com/center/list.action', } try: resp = self.sess.get(url=url, params=payload, headers=headers) resp_json = parse_json(resp.text) # many user info are included in response, now return nick name in it # jQuery2381773({"imgUrl":"//storage.360buyimg.com/i.imageUpload/xxx.jpg","lastLoginTime":"","nickName":"xxx","plusStatus":"0","realName":"xxx","userLevel":x,"userScoreVO":{"accountScore":xx,"activityScore":xx,"consumptionScore":xxxxx,"default":false,"financeScore":xxx,"pin":"xxx","riskScore":x,"totalScore":xxxxx}}) return resp_json.get('nickName') or 'jd' except Exception: return 'jd'
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') # 从api设定预约和抢购开始时间 reserve_stime = resp_json.get('yueStime') buy_stime = resp_json.get('qiangStime') self.timers.init_time(reserve_stime) self.timers.start('预约') while self.timers.enabled(): try: res = self.session.get(url='https:' + reserve_url) # 从api设定抢购开始时间 self.timers.init_time(buy_stime) if res.text.find("预约成功,已获得抢购资格") > 0: message = '预约成功,已获得抢购资格' if self.wechat_enable == 'true': send_wechat(message) if self.bark_enable == 'true': send_bark(message, 'detail') else: message = '您已成功预约过了,无需重复预约' logger.info(message) break except Exception as e: logger.error('预约失败正在重试...') wait_some_time()
def run(self): # read responses and trigger callbacks message = '' while self.is_running(): try: data = self.socket.recv(1024) except socket.timeout: continue except: data = '' if not data: break message += data while True: response, message = parse_json(message) if response is not None: self.process(response) else: break # fixme: server does not detect if we don't call shutdown self.socket.shutdown(2) self.socket.close() print_error("NetworkProxy thread terminating")