上一篇文章提到了使用Selenium模擬操作進(jìn)行下載的一些缺點(diǎn)砰粹,包括文本框輸入令人抓狂等等唧躲,這一篇文章將介紹使用Cookies免登錄、抓包分析來進(jìn)行下載碱璃、查詢等功能弄痹。
喂喂!你丫這也算司機(jī)嵌器?肛真??爽航?蚓让?
且慢且慢,這一條下載成功看似軟弱無力宛若咸魚讥珍,實(shí)則大智若愚历极,是通過Python發(fā)送數(shù)據(jù)包下載而來,并不是常人的操作衷佃,可大有所為趟卸!
本文分為以下幾個(gè)部分
-
自動(dòng)登錄——Cookies
自動(dòng)登錄的原理與抓包分析 -
Python自動(dòng)登錄網(wǎng)盤
自動(dòng)登錄部分的測試 -
查詢磁力鏈接、下載與狀態(tài)查詢抓包
后續(xù)部分的抓包分析 -
整體實(shí)現(xiàn)與缺點(diǎn)
整體代碼及需要改進(jìn)的地方
自動(dòng)登錄——Cookies
Cookie,有時(shí)也用其復(fù)數(shù)形式 Cookies,指某些網(wǎng)站為了辨別用戶身份、進(jìn)行 session 跟蹤而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)锄列。
這是百度登錄界面图云,勾選之后我們每次輸入pan.baidu.com都能自動(dòng)進(jìn)入到自己的網(wǎng)盤界面,都是Cookies
的功勞啦邻邮。所以我們只要拿到登錄之后的Cookies竣况,不就直接告訴網(wǎng)站“就是你大爺我!”饶囚,進(jìn)而實(shí)現(xiàn)免登錄了嗎帕翻?
Cookies的獲取
登陸之后F12控制臺切換至Network開始抓包,新建一個(gè)磁力鏈接并下載萝风,我們來觀察一下抓到的包嘀掸。
嘿嘿,右下角的數(shù)據(jù)(上面的Query String Parameters則是從POST的URL中提取出來的)已經(jīng)告訴我們這個(gè)query_magnetinfo是如何查詢磁力鏈接信息的了规惰,構(gòu)造一個(gè)包睬塌,包含磁力鏈接和保存地址save_path即可。然而上面的bdstoken和logid需不需要呢歇万?我實(shí)驗(yàn)的過程中費(fèi)了好大的周折給搞出來揩晴,最后卻發(fā)現(xiàn)并不需要這兩個(gè)玩意兒QAQ!所以大家測試其他網(wǎng)站的時(shí)候只加上自己覺得必要的贪磺,失敗再接著加參數(shù)就好硫兰。
接著看上面的信息,
我們就把這一大段文本給復(fù)制下來備用。
(為什么非要是這個(gè)包的Cookies呢刹前?……因?yàn)榘l(fā)現(xiàn)后續(xù)抓的包Cookies都是它……)
Python自動(dòng)登陸網(wǎng)盤
先構(gòu)造一個(gè)Header
然后發(fā)送出去查看效果
# 登錄需要POST一個(gè)包泳赋,其中包含帳號信息的Cookie
def login(self):
self.loginurl="http://pan.baidu.com/disk/home"
try:
req = urllib.request.Request(self.loginurl, headers=self.headers)
sourcecode = urllib.request.urlopen(req)
except Exception as e:
print('Error ', str(e))
else:
#如果出現(xiàn)該字眼說明登錄成功
htmlcode=(sourcecode.read().decode())
print(htmlcode)
if(htmlcode.find('initPrefetch')!=-1):
print('OK!')
顯示的是登錄成功之后的網(wǎng)盤部分的Html代碼,說明登錄成功啦喇喉。
查詢磁力鏈接祖今、下載與狀態(tài)查詢抓包
我們接著來抓包了哈。和上面一小節(jié)是同樣的方法拣技,需要關(guān)注的地方包括:
- POST的URL(即圖中的Query String Parameters)
- 包的數(shù)據(jù)(Form Data)
- 網(wǎng)頁的回應(yīng)
依次查看自己覺得可疑的包千诬,下面我們逐個(gè)來分析啦。
query_magnetinfo 查詢磁力鏈接
上一小節(jié)query_magnetinfo的Response如下:
還有文件大小呢膏斤!
Add_task 添加下載任務(wù)
比較重要的信息已經(jīng)用紅框標(biāo)注出來嘞
主要需要確定selected_index徐绑,我們需要下載哪些文件呢?
嘿嘿掸绞,上面不是有size返回給我們了嗎泵三!大的就是視頻文件了!
添加任務(wù)成功的情況:
添加失斚蔚А:
總之,返回task_id就是成功了敞映!
list_task和query_task
這兩個(gè)感覺是差不多的包较曼,返回的信息都是關(guān)于任務(wù)進(jìn)度的信息。
于是我找了不同類型的任務(wù)觀察query_task(list_task也行)返回的信息振愿。
嗯捷犹!就是說Status為0就是成功了!
整體實(shí)現(xiàn)與缺點(diǎn)
整體代碼在這里冕末!
baidudisk_github
不想點(diǎn)開的就看下面啦萍歉。
#! -*- coding:utf-8 -*-
# 本模塊用來離線下載資源到網(wǎng)盤
import urllib.request
import urllib.parse
import json
import execjs
class bdsaver:
def __init__(self,cookie):
self.cookie = cookie
self.headers = {
'Host': 'pan.baidu.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Referer': 'http://pan.baidu.com/',
'Cookie': self.cookie,
'Connection': 'keep-alive'
}
# 登錄需要POST一個(gè)包,其中包含帳號信息的Cookie
def login(self):
self.loginurl="http://pan.baidu.com/disk/home"
try:
req = urllib.request.Request(self.loginurl, headers=self.headers)
sourcecode = urllib.request.urlopen(req)
except Exception as e:
print('Error ', str(e))
else:
#如果出現(xiàn)該字眼說明登錄成功
htmlcode=(sourcecode.read().decode())
print(htmlcode)
if(htmlcode.find('initPrefetch')!=-1):
print('OK!')
def query(self,magneturl):
self.magneturl=magneturl
self.headers = {
'Host': 'pan.baidu.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'http://pan.baidu.com/disk/home?errno=0&errmsg=Auth%20Login%20Sucess&&bduss=&ssnerror=0',
'Cookie': self.cookie,
'Connection': 'keep-alive',
'Pragma': 'no - cache',
'Cache - Control': 'no - cache',
}
self.queryurl = 'http://pan.baidu.com/rest/2.0/services/cloud_dl?channel=chunlei&web=1&app_id=250528&clienttype=0'
self.data ={
'method': 'query_magnetinfo',
'app_id': '250528',
'source_url':self.magneturl ,
'save_path': '/',
'type': '4'
}
req = urllib.request.Request(self.queryurl, headers=self.headers, data=urllib.parse.urlencode(self.data).encode(encoding='UTF8') )
sourcecode = urllib.request.urlopen(req)
result=(sourcecode.read().decode('unicode_escape'))
print(result)
result=json.loads(result)['magnet_info']
download_list=''
for i in range(len(result)):
#文件大于50MB
if (int(result[i]['size'])>1024*1024*50):
download_list=download_list+str(i+1)+','
if download_list!='':
return download_list
else:
return '1'
def save(self,selidx):
# self.queryurl = 'http://pan.baidu.com/rest/2.0/services/cloud_dl?channel=chunlei&web=1&app_id=250528&bdstoken=efbd0c8c5eb658ea804bea857c9ad213&clienttype=0'
self.queryurl = 'http://pan.baidu.com/rest/2.0/services/cloud_dl?channel=chunlei&web=1&app_id=250528&clienttype=0'
self.data = {
'method': 'add_task',
'app_id': '250528',
'save_path': '/',
'selected_idx': selidx,
'task_from': '1',
'source_url':self.magneturl ,
# 't':'1501251100480'
}
req = urllib.request.Request(self.queryurl, headers=self.headers,
data=urllib.parse.urlencode(self.data).encode(encoding='UTF8'))
sourcecode = urllib.request.urlopen(req)
print(sourcecode.read().decode('unicode_escape'))
if __name__ == '__main__':
#填入自己截獲到的cookies
bdtest = bdsaver(cookie='')
bdtest.login()
dllist=bdtest.query(magneturl='magnet:?xt=urn:btih:459E0DD6DCE56845BE3C72368797481F0B8C0216&xl=3391547763&dn=%E7%94%9F%E5%8C%96%E5%8D%B1%E6%9C%BA%E7%B3%BB%E5%88%97%E4%B8%89%E9%83%A8+%E7%94%9F%E5%8C%964%E9%A2%84%E5%91%8A%E7%89%87')
bdtest.save(dllist)
相比上一部分文章的Selenium档桃,優(yōu)點(diǎn)自然是再也不用那么慢的輸入文本了枪孩,也不用管它頁面有沒有跟上速度,但缺點(diǎn)卻依然還在藻肄!那就是萬惡的驗(yàn)證碼蔑舞!
不過!似乎百度網(wǎng)盤的客戶端并不需要驗(yàn)證碼嘹屯,于是又一個(gè)大膽的想法萌生了……
歡迎關(guān)注下一篇文章:
Python實(shí)現(xiàn)電影排行榜自動(dòng)網(wǎng)盤下載(番外)Pywinauto操縱網(wǎng)盤客戶端批量離線下載
(番外篇)Python操縱網(wǎng)盤客戶端批量離線下載小電影
過往文章
網(wǎng)易云音樂評論抓取實(shí)驗(yàn)(1)接口獲取
Python自動(dòng)生成簡書過往文章鏈接Markdown格式文本
Python實(shí)現(xiàn)電影排行榜自動(dòng)網(wǎng)盤下載(4)Cookies免登錄+抓包下載
Python實(shí)現(xiàn)電影排行榜自動(dòng)網(wǎng)盤下載(3)Selenium離線下載
Python實(shí)現(xiàn)電影排行榜自動(dòng)網(wǎng)盤下載(2)Scrapy深入 “打包員”“快遞員”
Python實(shí)現(xiàn)電影排行榜自動(dòng)網(wǎng)盤下載(1)Scrapy爬蟲框架