*本文作者:过客匆匆打酱油,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。
看到首页上一种绕过限制下载论文的思路的文章,刚好笔者前几天给小学妹做了一个下载器,也凑热闹来讨论一下。
“一种绕过限制下载论文的思路”一文中,作者采用的是使用脚本操作浏览器,然后获取图片的链接的方式,可以说是简单粗暴有效。但是问题也很明显,就是效率低,在作者基础上进行提高的一个思路就是直接获取到图片的链接,可以从网站本身的显示逻辑来下手。
先放代码吧,页面有一个百度云的下载链接,下载后可以直接使用,需要先按安装JRE。
https://github.com/wxynihao/book118-downloader
以下面的链接为例:
https://max.book118.com/html/2017/0504/104201745.shtm
一、分析页面的js
1.1 预览框的显示逻辑
预览的时候会弹一个框出来,然后显示前几页,可以顺着弹出的代码找到获取链接的代码。
查看页面源代码可以找到show.js,其中包含一个openfull函数,这个函数中间又包含一段ajax请求的代码,如下:
$.ajax({
url : '/index.php?g=Home&m=View&a=viewUrl',
type : 'GET',
data : {
cid:tmp_doc_aid,
flag:1
},
async : false,
success : function(data){
openUrl = data;
}
});
构造一个请求测试一下 :
https://max.book118.com/index.php?g=Home&m=View&a=viewUrl&cid=104201745&flag=1
可以看到返回:
//view46.book118.com/?readpage=63pU7jqloamXmUqHxeARYw==&furl=YOQStEpojXDVWEMEMy2zbvH4iMigQCjbdHMZ8zyLAF6JTE93kuMR3Q26RVkJZ6jdR5Oiuypy9hB0x@nksHt6wRqyluwxwSyCHFm5r3rbGmboJpu3Y7iugg==&n=1
打开这个链接可以看到正是纯粹的预览页面。
1.2 加载的逻辑
查看获取到的预览页面的源代码,可以看到一个内嵌的js函数getNextPage,这个函数也包含一个ajax请求。
$.ajax({
type: "get",
url: "GetNextPage/",
data: {
f: $("#Url").val(),
img: $("#Img").val(),
isMobile: $("#IsMobi").val(),
isNet: $("#IsNet").val(),
readLimit: $("#ReadLimit").val(),
furl: $("#Furl").val()
},
dataType: "json",
success: function (data) {
$("#loading").hide();
switch (data.NextPage) {
case "!":
return false;
break;
case "Over":
nextpage = -1;
return false;
break;
case "Error":
alert(data.ErrorMsg);
break;
case "Response":
location.href = data.ErrorMsg;
nextpage = -1;
return false;
break;
case "ReadLimit":
var insertPos = $("#Url");
insertPos.after("<divstyle='text-align:center;margin:30px auto 100px auto'>-- 试读结束只能查看 " + data.ErrorMsg + " 页。继续阅读,请关闭本窗口,再点击付费阅读按钮。 --</div>");
nextpage = -1;
return false;
break;
}
上半部是请求,后半部是对返回结果的处理。根据上半部可以获取每一个下一页的链接,根据后半部可以作为获取到最后一页或出错的判断。
请求中的页全部在页面中,为hidden的input
<input type="hidden"id="Url"value="QzpcT2ZmaWNlV2ViMzY1XE9mZmljZVdlYlxjYWNoZVxQREZcMTE3MDUwNDA2MjQzNDEzNjMwMjEwMTU1ODRfNTQ3ODRcMjgyMjQyMC01OTBhNThhMjNlZmJjLmRvYy50ZW1w"autocomplete="off" />
<input type="hidden"id="Img" value="Hs92T42xAvvI2Q9XNLpZjPD2G_91o9mUfZ0TmOh2aZwu_A@FsflB5o41TClbHy2D"autocomplete="off" />
<input type="hidden"id="IsMobi" value="false" autocomplete="off"/>
<input type="hidden"id="IsNet" value="True" autocomplete="off" />
<input type="hidden"id="Furl" value="YOQStEpojXDVWEMEMy2zbvH4iMigQCjbdHMZ8zyLAF6JTE93kuMR3Q26RVkJZ6jdR5Oiuypy9hB0x@nksHt6wRqyluwxwSyCHFm5r3rbGmboJpu3Y7iugg=="autocomplete="off" />
<input type="hidden"id="ReadLimit" value="63pU7jqloamXmUqHxeARYw=="autocomplete="off" />
构造请求测试一下(注意furl要使用URLEncoder编码):
https://view46.book118.com//pdf/GetNextPage/
?f=QzpcT2ZmaWNlV2ViMzY1XE9mZmljZVdlYlxjYWNoZVxQREZcMTE3MDUwNDA2MjQzNDEzNjMwMjEwMTU1ODRfNTQ3ODRcMjgyMjQyMC01OTBhNThhMjNlZmJjLmRvYy50ZW1w
&img=Hs92T42xAvvI2Q9XNLpZjPD2G_91o9mUfZ0TmOh2aZwu_A%40FsflB5o41TClbHy2D
&isMobile=false
&isNet=True&readLimit=yTkhuLJ4vjF8dah5bBrJrw%3D%3D
&furl=YOQStEpojXDVWEMEMy2zbvH4iMigQCjbdHMZ8zyLAF6JTE93kuMR3Q26RVkJZ6jdR5Oiuypy9hB0x%40nksHt6wRqyluwxwSyCHFm5r3rbGmboJpu3Y7iugg%3D%3D
获取到如下json
{
NextPage: "Hs92T42xAvvI2Q9XNLpZjPD2G_91o9mUfZ0TmOh2aZwu_A@FsflB5nLMusDqiT9avqCPgOtUecY=",
PageCount: 4,
ErrorMsg: "",
PageIndex: 1,
PageWidth: 792,
Width: 792,
Height: 1120
}
拼接前缀可以得到图片地址:
http://view46.book118.com/img/?img=Hs92T42xAvvI2Q9XNLpZjPD2G_91o9mUfZ0TmOh2aZwu_A@FsflB5nLMusDqiT9avqCPgOtUecY=
替换请求中的img则可以继续向后获取图片。
直到最后json中不再包含正确的NextPage值则表示到了末尾。
二、实现
实现部分主要讲讲技术选型吧,我使用java开发。
2.1 页面的请求
最直接的当然还是使用httpclient,因为不需要处理中文,乱码问题可不考虑。
2.2 页面的解析
原本打算使用jsoup,想着倒也不多,直接使用正则撸完了。
2.3 pdf的生成
使用了itex,唯一的坑就是构造时指定了页面大小后,再修改第一次是不起作用的。
2.4 ocr
这部分功能我打算有空补上,目前测试了腾讯优图的在线OCR,识别率还可以。tesseract原生的识别率实在是太差。
三、后话
这里提供的是一种下载思路,说不上破解,我理解的破解是直接把原本的文件而不是预览图下载下来,希望有大神指指路。
*本文作者:过客匆匆打酱油,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。
来源:freebuf.com 2018-04-04 10:30:17 by: 过客匆匆打酱油
请登录后发表评论
注册