百度文庫下載需要券,或者vip才能下載
Vip價格高,偶爾下載一次不劃算。
不下載復(fù)制?不好意思復(fù)制也需要vip否則只能一次復(fù)制兩行。
如何才能以最低成本獲取到百度文庫里的文檔內(nèi)容呢?
當然是用Python啦!
接下來教大家如何使用Python免費下載百度文檔。
由于百度文庫的內(nèi)容是通過網(wǎng)頁展示的,那我們猜他是通過后臺加載進來的??梢韵韧ㄟ^Ctrl+u查看HTML源碼,看源碼里面是否有文檔數(shù)據(jù)。很遺憾HTML源碼里面并沒有文檔內(nèi)容。 確定不是通過HTML加載的之后,我們就可以大膽的猜測他是通過json異步加載。所以通過F12打開開發(fā)者管理工具network抓包,查看頁面加載過程請求的URL。這里會有大量的請求,但是我們仔細觀察會發(fā)現(xiàn)有一個0.json的URL返回的數(shù)據(jù)就是文檔的文本數(shù)據(jù)。
拿到請求文檔數(shù)據(jù)的URL后需要確定URL參數(shù)。通過查看headers確定請求方式為GET請求。請求參數(shù)里x-bce-range和token是變動的,其他都是固定不變。
token這個東西很多時候都會寫入到HTML頁面里去,用途是防csrf攻擊。但是百度文檔里面的token有什么用我們不用關(guān)心,重要的是這個token那里來。去HTML源代碼里查看這兩個變量能不能獲取到。
果然,在HTML源碼里有一段js代碼,其中就包含了所有請求文檔的URL。看起來有點像,但還是不一樣?。∑鋵嵾@里是包含了轉(zhuǎn)移符 \ ,還有一個比較奇怪的 \x22 其實是一個雙引號。把這段不規(guī)范的json數(shù)據(jù)提取出來替換掉 \ 和 \x22就是一個標準的json格式數(shù)據(jù)。
提取文檔數(shù)據(jù)URL代碼實現(xiàn)
def get_document(): # 文庫url url = "https://wenku.baidu.com/view/eefef92fa1116c175f0e7cd184254b35eefd1a97.html?from=search" sess = requests.Session() html = sess.get(url).content.decode("gbk") # 抓取到文檔標題 title = re.search('id="doc-tittle-0">(.*?)</span>', html).group(1) # 使用正則提取 文檔內(nèi)容的url res = re.search("WkInfo.htmlUrls = '(.*)'", html).group(1) # \\x22是linux中的引號,替換成Python中的引號 res = res.replace("\\x22", "\"") # 轉(zhuǎn)成字典 data = json.loads(res)
拿到URL之后繼續(xù)發(fā)送請求獲取文檔數(shù)據(jù),文檔數(shù)據(jù)是分段保存到j(luò)son里面的,json里面的數(shù)據(jù)如下圖所示。
字段解釋: c: 數(shù)據(jù) p: 位置 r: 暫時不確定作用 s: 字體樣式 t: 數(shù)據(jù)格式(word文本,pic圖片) ps: 樣式,_enter:1 表示換行,同一段的文本ps值為空
由于圖片加載比較特殊,有時候可能通過一個請求加載兩張圖片,不好確定圖片的位置,所以這里暫且不考慮圖片,我們只抓取文本。
def get_document():
# ....省略前面代碼
# 新建一個文檔 document = Document() string = "" for i in data["json"]: url = i["pageLoadUrl"] # 獲取到url url = url.replace("\\", "") # url中有轉(zhuǎn)義符\去掉 # 請求文檔內(nèi)容 data = requests.get(url).content.decode("utf-8") # 提取文本數(shù)據(jù) res = re.search("wenku_\d*\((.*)\)", data, re.S).group(1) # 將json對象數(shù)據(jù)轉(zhuǎn)成Python對象 data = json.loads(res) for i in data['body']: # 判斷數(shù)據(jù)是什么類型 if i["t"] == "word": # 獲取到文本 string += str(i["c"]) # ps中不為空并且_enter==1的時候是換行也就是一段內(nèi)容 if i["ps"] and i["ps"].get("_enter") == 1: document.add_paragraph(string) # 將一段內(nèi)容寫入到word string = "" # 重新復(fù)制 "" 表示新的一段文本 # 保存word document.save(title + ".docx")
到這里就已經(jīng)可以把一個百度文檔的文本內(nèi)容完整下載下來。 網(wǎng)上隨機選一篇文檔來測試效果,純文本的文檔效果賊好。缺點就是不能同時下載圖片插入到word里面去。
|
|