def _get_mobile_bills_sms_captcha(args): """移动发送账单短信验证码""" ret_data = {} username = args["username"].strip() form_data = {"callback": "jQuery1830" + str(randint(1E16, 1E17 - 1)) + "_" + get_js_time(), "_": get_js_time(), } url = "https://shop.10086.cn/i/v1/fee/detbillrandomcodejsonp/" + username + "?" + urlencode(form_data) key = username + ACCOUNT_CRAWLING_SMS_HEADERS_SSDB_SUFFIX + args["account_type"] try: ssdb_conn = get_ssdb_conn() headers = ssdb_conn.get(key) if headers is not None: sms_content = http_get(url, headers=eval(headers), verify=False).content.decode() if '"retCode":"000000"' in sms_content: # 成功 add_ajax_ok_json(ret_data) elif '"retCode":"570007"' in sms_content: # 系统繁忙! add_ajax_error_json(ret_data, "系统繁忙,请重试。") else: add_ajax_error_json(ret_data, sms_content) else: add_ajax_error_json(ret_data, "无法获取短信验证码,请刷新页面重试!") except Exception: add_ajax_error_json(ret_data, "获取短信验证码失败,请重试。") return JsonResponse(ret_data)
def _get_msgDetail_request(self, response, this_month, start_curor=1): """ 返回短信记录请求 """ meta = response.meta meta["last_msg_month"] = this_month if start_curor == 1: meta["msg_count"] += 1 form_data = { "curCuror": str(start_curor), "step": str(self.call_detail_step), "qryMonth": this_month.strftime("%Y%m"), "billType": "03", "msgback": "jQuery1830" + str(randint(1E16, 1E17 - 1)) + "_" + get_js_time(), "_": get_js_time(), } return Request("https://shop.10086.cn/i/v1/fee/detailbillinfojsonp/" + meta["item"]["username"] + "?" + urlencode(form_data), self.parse_msgDetail, dont_filter=True, meta=meta, errback=self.err_callback)
def parse(self, response): item = response.meta["item"] username = item["username"] password = item["password"] url = self.login_url + get_js_time() + "?returnURL=account%2Findex%2FtransferList" driver = self.load_page_by_webdriver(url, "//div[@id='pwdObject1-btn-pan']") try: try: if driver.find_element_by_id("verifyCode").is_displayed(): url = "https://bank.pingan.com.cn/ibp/portal/pc/getVcode2.do?" + get_js_time() cookiejar = get_cookies_dict_from_webdriver(driver) capcha_body = get_content_by_requests(url, headers=self.headers, cookie_jar=cookiejar) captcha_code = self.ask_image_captcha(capcha_body, username) driver.execute_script('document.getElementById("verifyCode").value="' + captcha_code + '";') except CaptchaTimeout: raise except Exception: self.logger.exception("平安银行---图片验证码") # 填写用户名和密码 driver.execute_script('document.getElementById("pwdObject1-btn-pan").click();' 'document.getElementById("userName").value="%s";' 'document.getElementById("pwdObject1-input").value="%s";' 'document.getElementById("login_btn").click();' % (username, password)) try: self.wait_xpath(driver, "//li[@id='safe_logout']", raise_timeout=True, timeout=6) except TimeoutException: page_source = driver.page_source if "密码错" in page_source: yield from self.error_handle(username, "平安银行---登录", driver.find_element_by_xpath("//span[@id='errorLoginMsg']").text) elif "证码错" in page_source: yield from self.error_handle(username, "平安银行---登录", driver.find_element_by_xpath("//span[@id='verifyError']").text) else: yield from self.error_handle(username, "平安银行---登录异常(%s)" % page_source, "登录失败") else: item["balance"], item["trade_records"] = self._login_success(driver) yield from self.crawling_done(item) except CaptchaTimeout: yield from self.error_handle(username, "平安银行---等待验证码超时", tell_msg="等待验证码超时,请刷新页面重试。。") except Exception: yield from self.except_handle(username, "平安银行---爬取", "爬取异常") finally: driver.quit()
def get_req_data(self, method, loginacc=None, loginpwd=None, year=None, loancode=None): data = dict() if method == self.user_login: data["loginacc"] = loginacc data["loginpwd"] = loginpwd elif method == self.user_queryRepayRecord: data["loanConNo"] = loancode elif method in [ self.user_getPerDepRecord, self.user_getPerFetchRecord, self.user_queryRepayRecord ]: data["year"] = year data["method"] = method data["v"] = "1.0" data["appkey"] = self.app_key data["timestamp"] = get_js_time() # 获取当前系统时间戳 data["sign"] = self.get_sign(data) return data
def get_logout_request(self, meta): return Request("http://shop.10086.cn/i/v1/auth/userlogout?_=" + get_js_time(), self.parse_logout, dont_filter=True, meta=meta, errback=self.parse_logout)
def get_img_captcha(request): """ 获取登录图片验证码 :param request: :return: """ ret_data = {} args = request.POST username = args["username"].strip() account_type = args["account_type"] if not username: add_ajax_error_json(ret_data, "用户名为空") return JsonResponse(ret_data) key = username + ACCOUNT_CRAWLING_IMG_HEADERS_SSDB_SUFFIX + account_type try: ssdb_conn = get_ssdb_conn() headers_data = ssdb_conn.get(key) if headers_data is not None: headers_data_dic = json_loads(headers_data) tmp_headers = headers_data_dic.get("headers") uuid = headers_data_dic.get("uuid") captcha_url = "https://authcode.jd.com/verify/image?a=1&acid={uuid}&" \ "yys={stime}".format(uuid=uuid, stime=get_js_time()) img_content = http_get(captcha_url, headers=tmp_headers, verify=False).content ret_data["img_data"] = bytes.decode(b64encode(img_content)) else: add_ajax_error_json(ret_data, "无法获取验证码") except Exception: add_ajax_error_json(ret_data, "无法获取验证码") else: add_ajax_ok_json(ret_data) return JsonResponse(ret_data)
def _get_unicom_bills_sms_captcha(args): """联通发送一般短信验证码""" ret_data = {} username = args["username"].strip() the_time = get_js_time() form_data = {'mobile': username, 'req_time': the_time, '_': int(the_time) + 1, 'callback': "jQuery1720" + str(randint(1E16, 1E17 - 1)) + "_" + the_time } # url = "https://uac.10010.com/portal/Service/SendMSG?" + urlencode(form_data) url = "https://uac.10010.com/portal/Service/SendMSG" key = username + ACCOUNT_CRAWLING_SMS_HEADERS_SSDB_SUFFIX + args["account_type"] try: ssdb_conn = get_ssdb_conn() headers = ssdb_conn.get(key) if headers is not None: sms_content = http_get(url, headers=eval(headers), params=form_data, verify=False).text if 'resultCode:"0000"' in sms_content: add_ajax_ok_json(ret_data) elif 'resultCode:"7096"' in sms_content: # 验证码请求过快 add_ajax_error_json(ret_data, "验证码请求过快,请稍后再试。") elif 'resultCode:"7098"' in sms_content: # 7098谁请求达到上限 add_ajax_error_json(ret_data, "请求短信验证码达到上限,请明天再试!") else: add_ajax_error_json(ret_data, "发送失败:" + sms_content) else: add_ajax_error_json(ret_data, "无法获取短信验证码,请刷新页面重试!") except Exception: add_ajax_error_json(ret_data, "无法获取短信验证码,请重试。") return JsonResponse(ret_data)
def post_login(self, response): meta = response.meta try: pp = self.ask_extra_captcha(meta['item']['username']) data = { 'org_errtype': '6', 'tfcont': '', 'delegate_url': '', 'f': 'html', 'starttime': '', 'chg': '0', 'ept': '0', 'ppp': '', 'ts': get_js_time(), 'vt': 'secondpwd', 'clientaddr': '', 'ignore_me': 'ignore_me', 'pp': pp, # 独立密码 'p': pp, 'btlogin': unquote('%204%20%B5%C7%C2%BC') } yield FormRequest('https://mail.qq.com/cgi-bin/login?sid=,2,zh_CN', callback=self.login, formdata=data, meta=meta, dont_filter=True, errback=self.err_callback) except Exception: yield from self.except_handle(meta['item']['username'], '登录解析失败', tell_msg="邮箱登录失败,请刷新页面重试")
def user_login_two(self, response): meta = response.meta try: login_url = 'http://mail.sina.com.cn/cgi-bin/sla.php?a={0}&b={1}&c=0' \ '&ssl=1'.format(get_js_time(), get_js_time()) yield Request(login_url, callback=self.find_sla, meta=meta, dont_filter=True, errback=self.err_callback) except Exception: yield from self.except_handle( response.meta['item']["username"], msg="user_login_two解析异常", tell_msg="邮箱登录失败,请刷新重试", logout_request=self.get_logout_request(meta))
def get_img_captcha_find_password(request): """ 获取找回密码图片验证码 :param request: :return: """ ret_data = {} try: uuid = request.session.get("request_data", {}).get("uuid") code_url = "https://authcode.jd.com/verify/image?acid=%s&srcid=%s&_t=%s" \ % (uuid, sourceId, get_js_time()) captcha_headers = HEADERS.copy() captcha_headers.update({ "Host": "authcode.jd.com", "Referer": "https://safe.jd.com/findPwd/index.action", "Accept": "image/webp,image/*,*/*;q=0.8" }) code_content = http_get(code_url, headers=captcha_headers, verify=False).content ret_data["img_data"] = bytes.decode(b64encode(code_content)) except Exception: add_ajax_error_json(ret_data, "无法获取验证码") else: add_ajax_ok_json(ret_data) return JsonResponse(ret_data)
def _get_captcha_body(request): cookies = request.session["req_cookie"] headers = DEFAULT_REQUEST_HEADERS.copy() headers['User-Agent'] = USER_AGENT headers["Referer"] = "https://ipcrs.pbccrc.org.cn/page/login/loginreg.jsp" return http_get("https://ipcrs.pbccrc.org.cn/imgrc.do?a=" + get_js_time(), headers=headers, cookies=cookies.get_dict(), verify=False).content
def parse_BindnumInfo(self, response): """ 解析号码信息 """ text = response.text meta = response.meta item = meta["item"] try: if '"result_code":"0000"' in text: # 成功 datas = json_loads(text)["defBindnumInfo"] balance = datas["costInfo"].get("balance") item["balance"] = float( balance) if balance is not None else None elif '"result_code":"0001"' not in text: # 0001是不允许短信验证码查询余额 self.logger.error( "联通---获取号码信息失败:(username:%s, password:%s) %s" % (item["username"], item["password"], text)) # 获取身份证信息 yield Request( "http://iservice.10010.com/e3/static/check/checklogin?_=" + get_js_time(), self.parse_checklogin, dont_filter=True, meta=meta, method="POST", errback=self.err_callback) except Exception: yield item yield from self.except_handle(item["username"], "联通---解析号码信息失败: %s" % text)
def get_page_request(self): parse = self.parse for i in range(101): the_time = get_js_time() form_data = { "resource_id": "6899", "query": "全国法院失信被执行人名单", "pn": str(i * 10), "rn": "10", "ie": "utf-8", "oe": "utf-8", "format": "json", 't': the_time, '_': int(the_time) + 2, 'callback': "jQuery1102" + str(randint(1E16, 1E17 - 1)) + "_" + the_time } yield Request( "https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?" + urlencode(form_data), parse, dont_filter=True)
def _get_payment_request(self, response, this_month): """ 返回交费记录请求 """ meta = response.meta meta["last_payment_month"] = this_month meta["payment_count"] += 1 form_data = { "pageNo": "1", "pageSize": str(self.CALL_PAGE_SIZE_LIMIT), "beginDate": this_month.strftime("%Y%m01"), "endDate": min(date.today().strftime("%Y%m%d"), get_month_last_date_by_date(this_month).replace("-", "")) } # sleep(0.6) return FormRequest( "http://iservice.10010.com/e3/static/query/paymentRecord?_=" + get_js_time(), self.parse_payment, dont_filter=True, meta=meta, formdata=form_data, errback=self.err_callback)
def _get_search_request(self, name, pn): the_time = get_js_time() form_data = { "resource_id": "6899", "query": "失信被执行人名单", "cardNum": "", "iname": name, "pn": str(pn), "rn": "10", "ie": "utf-8", "oe": "utf-8", "format": "json", 't': the_time, '_': int(the_time) + 2, 'callback': "jQuery1102" + str(randint(1E16, 1E17 - 1)) + "_" + the_time } return Request( "https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?" + urlencode(form_data), self.parse_search, dont_filter=True)
def _get_a_proxy(self): req_header = { 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0", 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh', 'Connection': 'close', } check_url = "http://shop.10086.cn/i/v1/fee/real/15928016431?_=" + get_js_time( ) for proxy in self.proxy_api.get_proxy_all(): if proxy in self.bad_proxy: continue try: resp = http_get(check_url, headers=req_header, timeout=3, proxies={'https': 'https://' + proxy}) if b'"retCode":"' in resp.content: resp = get_web_html_by_proxy( "https://login.10086.cn/captchazh.htm?type=12", proxies={'https': 'https://' + proxy}) if resp is not None: return proxy except Exception: self.logger.error("proxy error") self.bad_proxy.add(proxy) else: return rand_choice(list(self.good_proxy))
def qrcode_login(self, response): """ 京东扫描二维码登录 :param response: :return: """ meta = response.meta item = meta["item"] username = item["username"] try: qrcode_info = self._get_qrcode_info() if not qrcode_info: self.logger.error("获取二维码信息失败") yield from self.crawling_failed(username, "获取二维码信息失败,登录失败") # 扫描二维码 status = self.ask_scan_qrcode(qrcode_info.get("content"), username) if status != self.SCAN_QRCODE_SUCC: self.logger.error("扫描二维码登录失败") yield from self.crawling_failed(username, "扫描二维码登录失败") self.logger.info("验证扫描结果中------->") callback = "jQuery" + str(randint(1E6, 1E7 - 1)) check_url = ( "https://qr.m.jd.com/check?callback={callback}&appid={appid}&token={token}" "&_={timestamp}".format(appid=qrcode_info.get("appid"), token=qrcode_info.get("token"), timestamp=get_js_time(), callback=callback)) headers = qrcode_info.get("headers") page = self.http_request(check_url, headers=headers) res_json = self.str_to_json(page) self.logger.info(res_json) if res_json.get("code") == 200: self.logger.info("扫描成功") ticket = res_json.get("ticket") url = "https://passport.jd.com/uc/qrCodeTicketValidation?t={ticket}".format( ticket=ticket) headers.update({ "Host": "passport.jd.com", "Accept": "application/json, text/javascript, */*; q=0.01", "X-Requested-With": "XMLHttpRequest", "Referer": "https://passport.jd.com/uc/login?ltype=logout", }) yield Request(url=url, headers=headers, meta=meta, callback=self._parse_qrcode_login_result, errback=self.err_callback, dont_filter=True) else: msg = res_json.get("msg") yield from self.error_handle(username, msg) except Exception: yield from self.except_handle(username, "京东扫描二维码登录出错")
def parse_BindnumInfo(self, response): """ 解析号码信息 """ text = response.text meta = response.meta item = meta["item"] try: if '"retCode":"000000"' in text: # 成功 datas = json_loads(text)["data"] info_data = datas["custInfoQryOut"] inNetDate = info_data["inNetDate"] registration_time = "-".join( (inNetDate[:4], inNetDate[4:6], inNetDate[6:8])) item["registration_time"] = registration_time item["in_nets_duration"] = get_in_nets_duration_by_start_date( registration_time) item["status"] = UserStatus.Opened if info_data[ "status"] == "00" else UserStatus.Shutdown item["real_name"] = info_data["name"] item["is_real_name"] = (info_data["realNameInfo"] in ["2", "3"]) item["contact_addr"] = info_data.get("address") item["package"] = datas["curPlanQryOut"]["curPlanName"] elif '"retCode":"570007"' in text: # 系统繁忙! yield from self._retry_request(response) return elif '"retCode":"500003"' in text: # session信息为空,请先登录! yield from self.error_handle( item["username"], "移动---获取号码信息失败: (username:%s, password:%s) %s" % (item["username"], item["password"], text), "认证失败,请刷新页面重试。", logout_request=self.get_logout_request(meta)) return else: self.logger.error( "移动---获取号码信息失败:(username:%s, password:%s) %s" % (item["username"], item["password"], text)) # 获取余额信息 url = "http://shop.10086.cn/i/v1/fee/real/" + item[ "username"] + "?_=" + get_js_time() yield Request(url, self.parse_fee, dont_filter=True, meta=meta, errback=self.err_callback) except Exception: yield item yield from self.except_handle( item["username"], "移动---解析号码信息失败: %s" % text, logout_request=self.get_logout_request(meta))
def get_captcha_code(req_ses): captcha_code = "" headers = HEADERS.copy() while len(captcha_code) != 6: url = "https://ipcrs.pbccrc.org.cn/imgrc.do?" + get_js_time() captcha_body = req_ses.get(url, headers=headers, verify=False) captcha_code = parse_capatcha(captcha_body.content) return captcha_code
def _dangerous_verify_scrapy(self, username, verify_url, response): """ 登录安全校验(先发送短信验证码,再提交校验) :param username: :param verify_url: :param response: :return: """ try: headers_data = json_dumps({"url": verify_url}) self.set_sms_captcha_headers_to_ssdb(headers=headers_data, username=username) self.logger.info("等待获取用户输入短信验证码中...") sms_code_data = self.ask_sms_captcha(username) if not sms_code_data: msg = "获取用户输入短信验证码失败,登录失败" yield from self.error_handle(username, msg) else: tmp_data = sms_code_data.split("_") sms_code, ret_key = tmp_data if len(tmp_data) == 2 else ("", "") self.logger.info("%s ---> sms_code:%s" % (username, sms_code)) # 获取用户指纹信息eid,fp暂未实现,获取方式:https://payrisk.jd.com/js/td.js eid, fp = ("", "") valid_url = "https://safe.jd.com/dangerousVerify/checkDownLinkCode.action" \ "?code={code}&k={k}&t={stime}&eid={eid}" \ "&fp={fp}".format(code=sms_code, k=ret_key, stime=get_js_time(), eid=eid, fp=fp) my_headers = self.headers.copy() my_headers.update({ "Accept": "application/json, text/javascript, */*; q=0.01", "Referer": verify_url, "Host": "safe.jd.com", "Connection": "keep-alive", "X-Requested-With": "XMLHttpRequest", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36" }) yield Request(url=valid_url, headers=my_headers, callback=self._parse_verify_result, meta=response.meta, dont_filter=True, errback=self.err_callback) except CaptchaTimeout: yield from self.error_handle(username, "获取短信验证码超时,登录失败") except Exception: msg = "进行安全校验出错:%s" % username yield from self.except_handle(username, msg)
def get_captcha(self, response, username="", cookie_dict=None): """ 获取验证码并识别,返回识别的验证码, cookies """ # cookiejar = get_cookiejar_from_response(response) headers = get_headers_from_response(response) url = "http://uac.10010.com/portal/Service/CreateImage?t=" + get_js_time( ) resp = get_response_by_requests(url, headers=headers, cookie_jar=cookie_dict) return resp.content, resp.cookies.get_dict()
def _verify_callDetail_captcha(self, response, username, captcha_code): """ 返回是否正确 """ cookiejar = get_cookiejar_from_response(response) headers = get_headers_from_response(response) url = "http://shop.10086.cn/i/v1/res/precheck/" + username + "?captchaVal=" \ + captcha_code + "&_=" + get_js_time() info = get_content_by_requests(url, headers=headers, cookie_jar=cookiejar) return b'"retCode":"000000"' in info
def check_need_sms_captcha(self, response, username): cookiejar = get_cookiejar_from_response(response) headers = get_headers_from_response(response) form_data = { "accountType": "01", "account": username, "timestamp": get_js_time(), # "pwdType": "02", } info = get_content_by_requests( "https://login.10086.cn/needVerifyCode.htm?" + urlencode(form_data), headers=headers, cookie_jar=cookiejar) return b'"needVerifyCode":"1"' in info
def get_logout_request(self, meta): cookies_dict = meta["cookies_dict"] cookies_dict.update(meta["ppmdig_cookies"]) data = { 'appid': '101305', 'callback': 'passport403_cb%s' % get_js_time() } return FormRequest(url='https://v4.passport.sohu.com/i/logout/101305', callback=self.parse_logout, headers={}, formdata=data, cookies=cookies_dict, meta=meta, dont_filter=True, errback=self.parse_logout)
def _get_bill_records(self, driver, mail_list): detail_pattern = self.detail_pattern get_bill_record = self.get_bill_record bill_records = [] for it in mail_list: subject = it['subject'] bankname = check_email_credit_card_by_address(subject, it["from"]) if bankname: driver.get('https://mail.sohu.com/fe/getMail' '?id=%s&t=%s' % (it['id'], get_js_time())) sleep(0.2) detail = detail_pattern.search(driver.page_source).group(1) bill_record = get_bill_record(bankname, subject, detail) bill_records.append(bill_record) return bill_records
def parse(self, response): meta = response.meta try: su = self._enb64(self._url_encode( meta['item']["username"])).decode() prelogin_url = "https://login.sina.com.cn/sso/prelogin.php?entry=cnmail" \ "&callback=sinaSSOController.preloginCallBack&su=%s&rsakt=mod" \ "&client=ssologin.js(v1.4.19)&_=%s" % (su, get_js_time()) yield Request(prelogin_url, callback=self.prelogin, meta=meta, dont_filter=True, errback=self.err_callback) except Exception: yield from self.except_handle(meta['item']["username"], msg="登录入口解析异常", tell_msg="邮箱登录失败,请刷新重试")
def parse_captchazh(self, response): """ 解析验证码 """ meta = response.meta item = meta["item"] try: username = item["username"] password = item["password"] form_data = { "account": username, "password": self.pwd_encrypt(password), "accountType": "01", "pwdType": "01", "smsPwd": password, "backUrl": "http://shop.10086.cn/i/", "rememberMe": "0", "channelID": "12003", "protocol": "https:", "timestamp": get_js_time(), } if self.check_need_sms_captcha(response, username): self._set_sms_captcha_headers_to_ssdb(username, response) sms_uid = self.need_sms_captcha_type(username, type="login") form_data["smsPwd"] = self.ask_captcha_code(sms_uid) yield Request("https://login.10086.cn/login.htm?" + urlencode(form_data), self.parse_login, dont_filter=True, meta=meta, errback=self.err_callback) else: yield Request("https://login.10086.cn/login.htm?" + urlencode(form_data), self.parse_login, dont_filter=True, meta=meta, errback=self.err_callback) except CaptchaTimeout: yield from self.error_handle(item["username"], "移动---解析验证码失败,等待验证码超时", tell_msg="等待验证码超时,请刷新页面重试。") except Exception: yield from self.except_handle(item["username"], "移动---解析验证码失败")
def parse_loginfo(self, response): """ 解析登录跳转 """ meta = response.meta try: # 获取号码信息 url = "http://shop.10086.cn/i/v1/cust/mergecust/" \ + meta["item"]["username"] + "?_=" + get_js_time() yield Request(url, self.parse_BindnumInfo, dont_filter=True, meta=meta, errback=self.err_callback) except Exception: yield from self.except_handle( meta["item"]["username"], "移动---解析登录跳转失败: %s" % response.text, logout_request=self.get_logout_request(meta))
def _get_historyPayment_request(self, response): """ 返回获取交费记录的请求 """ meta = response.meta this_month = date.today() six_before_month = this_month - relativedelta( months=self.BILL_COUNT_LIMIT - 1) form_data = { "startTime": six_before_month.strftime("%Y%m01"), "endTime": this_month.strftime("%Y%m%d"), "_": get_js_time(), } return Request("http://shop.10086.cn/i/v1/cust/his/" + meta["item"]["username"] + "?" + urlencode(form_data), self.parse_historyPayment, dont_filter=True, meta=meta, errback=self.err_callback)
def _get_historyBill_request(self, response): """ 返回获取历史账单的请求 """ meta = response.meta this_month = date.today() six_before_month = this_month - relativedelta( months=self.BILL_COUNT_LIMIT - 1) form_data = { "bgnMonth": six_before_month.strftime("%Y%m"), # 指定开始月份(远) "endMonth": this_month.strftime("%Y%m"), # 指定结束月份(最近) "_": get_js_time(), } return Request("http://shop.10086.cn/i/v1/fee/billinfo/" + meta["item"]["username"] + "?" + urlencode(form_data), self.parse_queryHistoryBill, dont_filter=True, meta=meta, errback=self.err_callback)