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