您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)如何解決Python3抓取微信賬單信息問題的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
一、采用傳統(tǒng)模擬http抓取
抓取的主要URL:https://wx.tenpay.com/userroll/userrolllist,其中后面帶上三個參數(shù),具體參數(shù)見代碼,其中exportkey這參數(shù)是會過期的,userroll_encryption和userroll_pass_ticket 這兩個參數(shù)需要從cookie中獲得,應該是作為獲取數(shù)據(jù)的標識,通過抓包也看不出端倪,應該是微信程序內(nèi)部生成的,如果使用微信開發(fā)著工具登錄后直接訪問網(wǎng)址有的時候可以訪問返回數(shù)據(jù),但是只是在較短的時間內(nèi)有效,而且當返回會話超時后,繼續(xù)使用網(wǎng)頁訪問就會被限制,一直提示會話超時,應該是在網(wǎng)頁和移動端中exportkey有不同的時間和訪問次數(shù)的限制。
之后想通過破解seesion的方式,研究了一下,發(fā)現(xiàn)這是不可能的,想要破解session需要搞定wx.login,而wx.login是微信提供的,想要破解難度應該不用我說了。
二、解決exportkey 這個key和Cookie的獲取
需要的工具:
1、安卓/蘋果手機
2、Fiddler(抓包工具)
搞過爬蟲的都知道Fiddler,具體操作就不多說了,設置好代理和開啟Fiddler后,抓取url中的exportkey和相應的Cookie,用于接下來的數(shù)據(jù)抓取。
三、上代碼
代碼寫的不是很好,若有錯誤還望各位大大指正。
# coding:utf-8 import datetime import time import urllib import urllib.request import json import sys import io import ssl from DBController import DBController #數(shù)據(jù)庫 #設置系統(tǒng)編碼格式 sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030') #解決訪問Https時不受信任SSL證書問題 ssl._create_default_https_context = ssl._create_unverified_context class MainCode: def __init__(self, url=""): self.url = url self.dbController = DBController() # 數(shù)據(jù)庫控制 self.userroll_encryption = "uoxQXsCenowxj0G0ppRKBg8iHRPZwZKaUZB0ka1Y5apUuQnKkZTsA/2RMhBPGyMdiHS8QXk8y2JeLgqTPqZPU9fkrCUp+TIQPkHH/uExAwKeBFLute0ztdHaC6GJUJ2+/R8NGWGe16hSKc6L1+LvAw==" self.userroll_pass_ticket = "V7oum4glDbdaAwibC8mcuTizGIKmC9A/Y/V12qASuDALdRMveHcRHv1QXamFk27Z" # self.last_bill_id = "" # self.last_bill_type = "" # self.last_create_time = "" # self.last_trans_id = "" self.last_item = {} self.num= 0 #獲取網(wǎng)頁信息 def get_html(self, url, maxTryNum=5): goon = True # 網(wǎng)絡中斷標記 obj = {} for tryNum in range(maxTryNum): try: # print(self.token) header = { "Accept": 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', "Accept-Encoding":'gzip, deflate, br', "Accept-Language":'zh-CN,zh;q=0.8', "Cache-Control":'max-age=0', "Connection": "keep-alive", "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Mobile/14C92 Safari/601.1 wechatdevtools/1.02.1810240 MicroMessenger/6.5.7 Language/zh_CN webview/15415760070117398 webdebugger port/32594", "Cookie":"userroll_encryption="+self.userroll_encryption+"; userroll_pass_ticket="+self.userroll_pass_ticket, "Host":"wx.tenpay.com", "Upgrade-Insecure-Requests":"1", } req = urllib.request.Request(url=url, headers=header) # 訪問網(wǎng)址 result = urllib.request.urlopen(req, timeout=5).read() break except urllib.error.HTTPError as e: if tryNum < (maxTryNum - 1): print("嘗試連接請求" + str(tryNum + 1)) # host = self.host2 time.sleep(5) else: print('Internet Connect Error!', "Error URL:" + url) goon = False break if goon: page = result.decode('utf-8') obj = json.loads(page) #print(obj) #print(page) else: print("--------------------------") return obj #保存到數(shù)據(jù)庫 def save_info_to_db(self, item): select_sql = "SELECT count(*)as num FROM wx_order2 where trans_id = '%s'" % (item["trans_id"]) results = self.dbController.ExecuteSQL_Select(select_sql) if int(results[0][0]) == 0: sql = "INSERT INTO wx_order2 (bill_id, bill_type, classify_type, fee, fee_type, out_trade_no, pay_bank_name, payer_remark, remark, order_time, title, total_refund_fee, trans_id,fee_attr) VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s')" % ( str(item['bill_id']), str(item['bill_type']), str(item['classify_type']), str(item['fee']), str(item['fee_type']) , str(item['out_trade_no']), str(item['pay_bank_name']), str(item['payer_remark']), str(item['remark']), str(item['order_time']), str(item['title']), str(item['total_refund_fee']), str(item['trans_id']), str(item['fee_attr']) ) # print(sql) try: self.dbController.ExecuteSQL_Insert(sql) # self.log.info("插入數(shù)據(jù)成功") except Exception as e: print("save_info_to_db:",e) return #從獲取的網(wǎng)頁信息中過濾所需要的信息 def get_data(self,url): res_obj = self.get_html(url) this_page_num = 0 #若返回的ret_code== 0 則說明獲取數(shù)據(jù)成功 if res_obj['ret_code'] == 0: record_list = res_obj['record'] self.last_bill_id = res_obj['last_bill_id'] self.last_bill_type = res_obj['last_bill_type'] self.last_create_time = res_obj['last_create_time'] self.last_trans_id = res_obj['last_trans_id'] num = 1 this_page_num = len(record_list) # order = record_list[i] for order in record_list: bill_id = order['bill_id'] bill_type = order['bill_type'] classify_type = order['classify_type'] fee = order['fee'] #賬單金額 fee = fee * 0.01 fee = round(fee, 2) #對金額保留兩位小數(shù) fee_type = order['fee_type'] #金額類型 out_trade_no = order['out_trade_no'] #賬單編號 pay_bank_name = order['pay_bank_name'] #支付的銀行 payer_remark =order['payer_remark'] #支付說明 remark = order['remark'] #賬單說明 order_time = datetime.datetime.fromtimestamp(order['timestamp']) #將時間戳轉(zhuǎn)為時間 title = order['title'] #賬單標題 title = title.replace(',','').replace('.','').replace("'",'') #去除英文逗號和單引號 total_refund_fee = "0" trans_id = order['trans_id'] fee_attr = order['fee_attr'] #title = self.remove_emoji(title) fee_attr = order['fee_attr'] pay_type = "" if bill_type == 1: pay_type= "支付" elif bill_type == 2: pay_type = "充值" elif bill_type == 4: pay_type = "轉(zhuǎn)賬" elif bill_type == 6: pay_type="紅包" else: pay_type = str(bill_type) if fee_attr == "positive": fee_attr = "收入" elif fee_attr == "negtive": fee_attr = "支出" elif fee_attr == "neutral": fee_attr = "提現(xiàn)" item = {} item['bill_id'] = bill_id item['bill_type'] =bill_type item['classify_type'] = classify_type item['fee'] = fee item['fee_type'] = fee_type item['out_trade_no'] = out_trade_no item['pay_bank_name'] = pay_bank_name item['payer_remark'] = payer_remark item['remark'] = remark item['order_time'] = order_time item['title'] = title item['total_refund_fee'] = total_refund_fee item['trans_id'] = trans_id item['fee_attr'] = fee_attr # title = self.remove_emoji(title) if bill_id != '': self.last_item['last_bill_id'] = bill_id self.last_item['last_bill_type'] = bill_type self.last_item['last_create_time'] = order['timestamp'] self.last_item['last_trans_id'] = trans_id try: print(str(self.num),self.last_item,end='\n') self.num += 1 time.sleep(0.2) self.save_info_to_db(item) #print(str(num)+" 時間:" + str(order_time) + " 賬單標題:" + title + " 說明:"+ str(remark)+ " " +str(pay_type) +"金額:" + str(fee) + " 支付方式:"+ str(pay_bank_name)+" 類型:" + str(pay_type) +" fee_attr:"+str(fee_attr)+ '\n',end='') except Exception as e: print(e,end='\n') num = num+1 else:#若獲取數(shù)據(jù)不成功,打印原因 print(res_obj) return this_page_num #實例化 maincode = MainCode(); #設置Cookie參數(shù) maincode.userroll_encryption = "6Ow68aKrAz70mEczqeevA2gOXbr9H2a7+2ite6uuyWFdB6j1+SLhlaCNpYA6RjmaOI7IfCi9PXjQsrZPFIs1SMn38Uxr04GJsxMuSO/9wG+eBFLute0ztdHaC6GJUJ2+vmo+JIw351su8RiFxSagwA==" maincode.userroll_pass_ticket = "i0Co+55KSEjmFjfFZqMG14hasW4qtKFtbj0FiErcSzHY0afkFqHGib3YfsAZWcaG" #用于非第一頁的數(shù)據(jù)抓取 #maincode.last_item['last_bill_id'] = "2ce3d65b20a10700b2048d68" #maincode.last_item['last_bill_type'] = "4" #maincode.last_item['last_create_time'] = "1540809516" #maincode.last_item['last_trans_id'] = "1000050201201810290100731805325" #設置每次返回的數(shù)量 count = "20" #exportkey 需要從Fiddler 抓包獲取,有一定的時間限制 exportkey ="A%2BsIJaTGZksgZWPLtSKiyos%3D" #抓取的URL url ="https://wx.tenpay.com/userroll/userrolllist?classify_type=0&count="+count+"&exportkey="+exportkey+"&sort_type=1" for page in range(0,10): #記錄當前頁返回的數(shù)據(jù)數(shù)量 this_page_num = 0 #第一頁 if page == 0: this_page_num = maincode.get_data(url) #從第二頁開始需要增加上一頁最后一個item的部分參數(shù),進行下一頁的數(shù)據(jù)的抓取 else: url = "https://wx.tenpay.com/userroll/userrolllist?classify_type=0&count="+count+"&exportkey="+exportkey+"&sort_type=1"+"&last_bill_id="+str(maincode.last_item['last_bill_id'])+"&last_bill_type="+str(maincode.last_item['last_bill_type'])+"&last_create_time="+str(maincode.last_item['last_create_time'])+"&last_trans_id="+str(maincode.last_item['last_trans_id'] + "&start_time="+str(maincode.last_item['last_create_time'])) print(url) this_page_num = maincode.get_data(url) #如果數(shù)量少于20個則跳出循環(huán),抓取結(jié)束 if this_page_num < 20: break time.sleep(0.5) print(maincode.last_item)
因為是幫朋友抓取的,能實現(xiàn)就可以了。之后若有需要再繼續(xù)優(yōu)化代碼吧!
感謝各位的閱讀!關(guān)于“如何解決Python3抓取微信賬單信息問題”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。