确定要抓取的数据内容
开始之前咱们先看一下要爬取的数据内容~
分析网站结构
通过鼠标选择器;选中文本之后在右侧的元素面板中可以看到数据是包含在p标签中的,我在想是否能够通过re正则表达式直接获取对应的text文本;~ 哈哈,想简单了🤓 ~ 因为在仔细对比之后发现,class所对应的属性是不规则的;就算将文本获取下来了,文字也是那种七拼八凑没有排好版的;这样的文章要来也没有任何用呀;所以继续分析呗......😂
一般像这种文章一类的;它的api确实很难逆向......自己埋得坑得给填平😂
经过一番查找;发现这个VIP文库好像是通过js文件然后生成了属于自己独有的api地址 ?
在不确定对不对的情况下,也没有其他数据验证的情况下;先解析排序一番 看是否能够拿到数据。
-实战
第一步:请求网络链接先获取到网站返回数据
import requests
import re
# 设置会话列表
session = requests.session()
# 请求网址
def get_content_url(url):
return session.get(url).content.decode('gbk')
def main():
url = input('请输入你要付费下载百度文库的url网址:')
content = get_content_url(url)
print(content)
我们在获取到该文章的url之后,查看该url对应的网页数据时,在这个网页数据中发现它同时蕴含着真正文章的地址
htmlUrls = '{\x22ttf\x22:[{\x22pageIndex\x22:1,\x22param\x22:\x22&md5sum=b1f8fa5aeb9b6fed68ad32e063bfb0e5&range=0-31101&sign=7515dbae11\x22},{\x22pageIndex\x22:2,\x22param\x22:\x22&md5sum=b1f8fa5aeb9b6fed68ad32e063bfb0e5&range=31102-55306&sign=7515dbae11\x22},{\x22pageIndex\x22:3,\x22param\x22:\x22&md5sum=b1f8fa5aeb9b6fed68ad32e063bfb0e5&range=55307-93048&sign=7515dbae11\x22},{\x22pageIndex\x22:4,\x22param\x22:\x22&md5sum=b1f8fa5aeb9b6fed68ad32e063bfb0e5&range=93049-132192&sign=7515dbae11\x22},{\x22pageIndex\x22:5,\x22param\x22:\x22&md5sum=b1f8fa5aeb9b6fed68ad32e063bfb0e5&range=132193-&sign=7515dbae11\x22}],\x22json\x22:[{\x22pageIndex\x22:1,\x22pageLoadUrl\x22:\x22https:\\\/\\\/wkbjcloudbos.bdimg.com\\\/v1\\\/docconvert5004\\\/\\\/wk\\\/b1f8fa5aeb9b6fed68ad32e063bfb0e5\\\/0.json?responseCacheControl=max-age%3D3888000&responseExpires=Sun%2C%2014%20Jun%202020%2014%3A46%3A09%20%2B0800&authorization=bce-auth-v1%2Ffa1126e91489401fa7cc85045ce7179e%2F2020-04-30T06%3A46%3A09Z%2F3600%2Fhost%2F9e582203d432a9f847b718dab571a08017108e768f72ade5237ff652a7155251&x-bce-range=0-10894&token=eyJ0eXAiOiJKSVQiLCJ2ZXIiOiIxLjAiLCJhbGciOiJIUzI1NiIsImV4cCI6MTU4ODIzMjc2OSwidXJpIjp0cnVlLCJwYXJhbXMiOlsicmVzcG9uc2VDYWNoZUNvbnRyb2wiLCJyZXNwb25zZUV4cGlyZXMiLCJ4LWJjZS1yYW5nZSJdfQ%3D%3D.ErP4NzQSHI7omb0fL0PCVfgvk0ze0w0JUfZLWMMYDlM%3D.1588232769\x22},{\x22pageIndex\x22:2,\x22pageLoadUrl\x22:\x22https:\\\/\\\/wkbjcloudbos.bdimg.com\\\/v1\\\/docconvert5004\\\/\\\/wk\\\/b1f8fa5aeb9b6fed68ad32e063bfb0e5\\\/0.json?responseCacheControl=max-age%3D3888000&responseExpires=Sun%2C%2014%20Jun%202020%2014%3A46%3A09%20%2B0800&authorization=bce-auth-v1%2Ffa1126e91489401fa7cc85045ce7179e%2F2020-04-30T06%3A46%3A09Z%2F3600%2Fhost%2F9e582203d432a9f847b718dab571a08017108e768f72ade5237ff652a7155251&x-bce-range=10895-28260&token=eyJ0eXAiOiJKSVQiLCJ2ZXIiOiIxLjAiLCJhbGciOiJIUzI1NiIsImV4cCI6MTU4ODIzMjc2OSwidXJpIjp0cnVlLCJwYXJhbXMiOlsicmVzcG9uc2VDYWNoZUNvbnRyb2wiLCJyZXNwb25zZUV4cGlyZXMiLCJ4LWJjZS1yYW5nZSJdfQ%3D%3D.9i8HdDDmUge8YbVEMtZAnelm%2FDSLDfBfgI2Jx7P16aE%3D.1588232769\x22},{\x22pageIndex\x22:3,\x22pageLoadUrl\x22:\x22https:\\\/\\\/wkbjcloudbos.bdimg.com\\\/v1\\\/docconvert5004\\\/\\\/wk\\\/b1f8fa5aeb9b6fed68ad32e063bfb0e5\\\/0.json?responseCacheControl=max-age%3D3888000&responseExpires=Sun%2C%2014%20Jun%202020%2014%3A46%3A09%20%2B0800&authorization=bce-auth-v1%2Ffa1126e91489401fa7cc85045ce7179e%2F2020-04-30T06%3A46%3A09Z%2F3600%2Fhost%2F9e582203d432a9f847b718dab571a08017108e768f72ade5237ff652a7155251&x-bce-range=28261-38549&token=eyJ0eXAiOiJKSVQiLCJ2ZXIiOiIxLjAiLCJhbGciOiJIUzI1NiIsImV4cCI6MTU4ODIzMjc2OSwidXJpIjp0cnVlLCJwYXJhbXMiOlsicmVzcG9uc2VDYWNoZUNvbnRyb2wiLCJyZXNwb25zZUV4cGlyZXMiLCJ4LWJjZS1yYW5nZSJdfQ%3D%3D.4SABpIpgQ%2BnueqTBSwfTo3nLieKfUcGU%2FZU9OZ%2F4nk0%3D.1588232769\x22},{\x22pageIndex\x22:4,\x22pageLoadUrl\x22:\x22https:\\\/\\\/wkbjcloudbos.bdimg.com\\\/v1\\\/docconvert5004\\\/wk\\\/b1f8fa5aeb9b6fed68ad32e063bfb0e5\\\/0.json?responseContentType=application%2Fjavascript&responseCacheControl=max-age%3D3888000&responseExpires=Sun%2C%2014%20Jun%202020%2014%3A46%3A09%20%2B0800&authorization=bce-auth-v1%2Ffa1126e91489401fa7cc85045ce7179e%2F2020-04-30T06%3A46%3A09Z%2F3600%2Fhost%2F5a356ec62775deff7aa1b5b5b4937945c319efe9126778be6254387b75ca1626&x-bce-range=38550-52301&token=eyJ0eXAiOiJKSVQiLCJ2ZXIiOiIxLjAiLCJhbGciOiJIUzI1NiIsImV4cCI6MTU4ODIzMjc2OSwidXJpIjp0cnVlLCJwYXJhbXMiOlsicmVzcG9uc2VDb250ZW50VHlwZSIsInJlc3BvbnNlQ2FjaGVDb250cm9sIiwicmVzcG9uc2VFeHBpcmVzIiwieC1iY2UtcmFuZ2UiXX0%3D.L5iFcYymhKwKiOA3dVRyBtUXFG9QRfohHiaIzS2MpQU%3D.1588232769\x22},{\x22pageIndex\x22:5,\x22pageLoadUrl\x22:\x22https:\\\/\\\/wkbjcloudbos.bdimg.com\\\/v1\\\/docconvert5004\\\/\\\/wk\\\/b1f8fa5aeb9b6fed68ad32e063bfb0e5\\\/0.json?responseCacheControl=max-age%3D3888000&responseExpires=Sun%2C%2014%20Jun%202020%2014%3A46%3A09%20%2B0800&authorization=bce-auth-v1%2Ffa1126e91489401fa7cc85045ce7179e%2F2020-04-30T06%3A46%3A09Z%2F3600%2Fhost%2F9e582203d432a9f847b718dab571a08017108e768f72ade5237ff652a7155251&x-bce-range=52302-&token=eyJ0eXAiOiJKSVQiLCJ2ZXIiOiIxLjAiLCJhbGciOiJIUzI1NiIsImV4cCI6MTU4ODIzMjc2OSwidXJpIjp0cnVlLCJwYXJhbXMiOlsicmVzcG9uc2VDYWNoZUNvbnRyb2wiLCJyZXNwb25zZUV4cGlyZXMiLCJ4LWJjZS1yYW5nZSJdfQ%3D%3D.9VimXbBUqMM9a8uJUhZFYjWxNzEnd0X485v%2FiCIHO24%3D.1588232769\x22}],\x22png\x22:[]}'
第二步:正则表达式进行数据解析
解析之后不知道大家有没有发现一个规律;这里面蕴含的数据内容; 哈哈哈 ~ 😎我们好像找到了! 噢耶🤞 ️这种感觉非常的神奇;跟探索新大陆似的。也许这就是爬虫的乐趣所在 Go Go Go !一鼓作气。。。
def get_content_type(content):
print(re.findall(r"docType.*?\:.*?\'(.*?)\'\,", content))
是不是没有任何发现;脑子有点懵~ 慢慢来!我已经标注出来了。既然我们发现了这个数据集,那么接下来尝试着解析一下呗;看看隐藏这么深的究竟是何方神圣。。。。。。
根据上面获取到的数据集经过再一次的解析;我们得到了一个链接;好像~貌似看到希望了呀;哈哈~
再解析一下;此时我们已经通过正则表达式取得该文章的地址了,这些地址不止一个;接下来让我们把代码先完善一下
[图片上传失败...(image-b384de-1600501959886)]
PS:因为每个文章的类型是不同的;看下图;所以这里只做了doc格式的解析;其他的思路都差不多;有心的同学可以参照着我这种方案自己动手试一下。
def get_content_type(content):
return re.findall(r"docType.*?\:.*?\'(.*?)\'\,", content)[0]
使用文章的地址再次向服务器发送请求时,获取到的文章数据,但是此时的数据还并不是文章的内容,而是一个json结构的数据集;这里大家看起来可能有点懵逼;我们稍微给他处理一下
经过解析之后;这样看起来就清晰了很多;大家看下图的左边👈~ 然后再看右边👉解析整理之后的;
[图片上传失败...(image-4dbdb8-1600501959886)]
不过看到这个数据集有些脑袋懵懵的,头皮发麻有没有;经过一番摸索之后;给大家整理一下结论;
这个数据集是基于百度文库自己的阅读器生成的,里面包含了非常多的信息,我们需要的文章内容就在其中,只不过它是以五维的位置参数,来标明内容出现的位置。
比如下面这样,内容就是 c 这一串的Unicode编码,p 就是其位置参数,什么高啊、宽啊等。
有种无从下手的感觉;经过一番实验;这里我们可以根据 y 的数值对整个文档进行简单排列,然后设置编解码。
不理解的同学可以根据代码。自己实践一下;这里就不细说了!
def get_content_doc(content):
result = ''
url_list = re.findall('(https.*?0.json.*?)\\\\x22}', content)
# print(url_list)
url_list = [addr.replace("\\\\\\/", "/") for addr in url_list]
for url in url_list[:-5]:
content = fetch_url(url)
y = 0
txtlists = re.findall('"c":"(.*?)".*?"y":(.*?),', content)
for item in txtlists:
if not y == item[1]:
y = item[1]
n = '\n'
else:
n = ''
result += n
result += item[0].encode('utf-8').decode('unicode_escape', 'ignore')
return result
解析完毕;打完收工
第三步:数据保存
到这一步,就比较简单了;
def save_file(filename, content):
with open(filename, 'w', encoding='utf-8') as f:
f.write(content)
print('已保存为:' + filename)
if __name__ == "__main__":
main()
效果展示
保存至txt文件中
上面的代码逻辑是直接保存在txt文件中的 比如这样的
保存至word文档中
经过再一次的处理;尝试保存至word文档中 效果是这样的