百度文库下载须要券,或者vip才能下载html
Vip价格高,偶尔下载一次不划算。linux
不下载复制?很差意思复制也须要vip不然只能一次复制两行。json
如何才能以最低成本获取到百度文库里的文档内容呢?异步
固然是用Python啦!工具
接下来教你们如何使用Python免费下载百度文档。测试
因为百度文库的内容是经过网页展现的,那咱们猜他是经过后台加载进来的。能够先经过Ctrl+u查看HTML源码,看源码里面是否有文档数据。很遗憾HTML源码里面并无文档内容。字体
肯定不是经过HTML加载的以后,咱们就能够大胆的猜想他是经过json异步加载。因此经过F12打开开发者管理工具network抓包,查看页面加载过程请求的URL。这里会有大量的请求,可是咱们仔细观察会发现有一个0.json的URL返回的数据就是文档的文本数据。url
拿到请求文档数据的URL后须要肯定URL参数。经过查看headers肯定请求方式为GET请求。请求参数里x-bce-range和token是变更的,其余都是固定不变。spa
token这个东西不少时候都会写入到HTML页面里去,用途是防csrf攻击。可是百度文档里面的token有什么用咱们不用关心,重要的是这个token那里来。去HTML源代码里查看这两个变量能不能获取到。3d
果真,在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里面去。