百度文库文档下载分析
今天要在百度文库下一个文档,由于之前测试,清掉了cookies,所以下载文档时突然提示登陆(之前一直都是自动登陆,记不住密码啊……),试了半天才想起来密码,就打算在分析下。
要说自己对百度文库也算缘分不浅,当年大二的时候我们工作室接到一个项目,就是采集互联网的各类电子文档,以供某公司建立文库。当时百度虽说还上线不到一年,但是却已经很有名气,因此也是我们的重点关注对象。下边开始分析(只看下载分析直接看(二)就行了):
一、文档在线展示的实现方式和采集策略
在线文库普遍采用的技术有两大类:一是将文档转为swf文件,然后页面用flash展示;二是按照文档原有结构,生成html结构展示。就我们用户而言,多数时候更喜欢第二种,给人感觉更直观一点,但是就实现难度而言,第二种也比较麻烦,原因不多说,想想就知道。
当时在线文库主要采用的都是flash方式,这种方式既实现方便,又能够有效的防止文档被恶意抓取,虽说生成的swf文件很容易拿到,但是对于采集者而言,想得到的往往是文档内容。那么就真的没办法了吗?其实不然,我们了解下这种方式的实现原理就会发现,绝大多数swf展示文档都是将文档每页生成图片,然后再生成swf的,那么我们只要通过工具将swf中图片提取出来(这个自己查资料吧),再通过ocr将文字识别出来就行了。
好吧,我想你看到ocr就没啥心情在看下去了,这玩意目前免费的还没几个靠谱的,那么我们来看下第二种方法。第二种就比较简单了,因为文档内容直接嵌入网页,我们直接提取出来就行了呗,小娃娃都会呢。可是我要说这连第一种都不如,因为有两个关键问题:一是采用这一方式的不多,就百度文库来说只有一部分文档是这么实现的,杜宇PPT这一类富文本元素较多的,还是flash实现;二是你即使内容提取出来了,想要按原样式生成文档,也很难的。
这也不行,那也不行,那咋着行呢?其实上边都是废话,想要文档,直接下载不就行了。
二、百度文库文档下载分析
1、准备好装备
需要准备好以下装备:
- 百度账号
- chrome/firefox
- fiddler2(不是必备,但是用过你就爱不释手)
- 新建一个txt文件方便记录信息
2、找到文档下载链接
我们先找个账号登录,随便打开一个不要财富值的文档(最好大一点,1M以上),F12打调试工具,然后下载文档,可以看到Network出现很多请求,那么哪个请求时下 载链接呢?直接将请求按照Siz e大小排序,你会发现最大的那个请求返回内容特别大,这个就是下载链接,请求详情如下:
请求链接:
http://bs.baidu.com/wenku41/%2F1a34b536b85dec92517f7ef702e577b4?sign=MBOT:y1jXjmMD4FchJHFHIGN4z:wL%2Bt8HZ%2B9z7YjU2vGwjLZAJH868%3D&time=1393158775&response-content-disposition=attachment;%20filename=%22%B4%BA%CD%ED%B2%BB%CD%EA%C8%AB%BD%DA%C4%BF%B5%A5.doc%22&response-content-type=application%2foctet-stream
多下载几个就会发下这三部分是变化的,第一部分搜索文档页源码就能找到,filename后的一眼就能看出来是文件名的url编码,而第两部分在原页面却找不到,可以想到应该是从服务器返回的,那么我们再来看看其他请求。可以很容易发现有个叫download的请求,这名字很明显了,我们看下这个请求:
![](http://static.oschina.net/uploads/space/2014/0223/212715_I6Xj_1183145.jpg)
激动人心的时刻来了,在response中,Location就是文档下载链接。那么这个请求有事怎么发起的呢?首先看下请求参数,除了doc_id,其他几项都找不到,在看下referer,链接就是之前的文档页,我们在这个页面搜一下“ downloadToken ”,会惊喜的发现下边这个表单:
<form name="downloadForm" action="/user/submit/download" method="post" target="runDown"><input name="ct" value="20008" type="hidden" /><input name="doc_id" value="b732f1ee240c844769eaee90" type="hidden" /><input name="retType" value="newResponse" type="hidden" /><input name="sns_type" type="hidden" /> <input type="hidden" name="storage" value="0" /><input type="hidden" name="useTicket" value="0" /> <input type="hidden" name="downloadToken" value="e1de787724d82b8c18c1be98438782eb" /> <input type="hidden" name="sz" value="15872"></form>
到此真相大白:在文档也点击下载后,首先用词表单向download页发起请求,服务器则会返回文档的下载地址并跳转,然后返回文档流。
3、模拟请求
到这里就用到fiddler2了,我们如下构造请求(这里特地找了一个未下载过需要财富值的,):
执行......然后发现返回code:200,response中没有Location。那么哪里出问题了呢?我们模拟求情和浏览器操作哪一点不一样呢?登 录!模拟请求中我们没有登 录,直接把浏览器中已登录的cookies贴过来,然后在执行......:
成功!请求download也需要登陆信息,那么如何登陆呢?请参见 模拟百度登录
此次分析到此结束,代码就不贴了,照着贴吧登陆改了一个最后请求cookies总是空的,不知道是不是因为跨域需要手动设置cookies,但是按照以上的分析肯定能实现下载的。