如何实现“漫画村”漫画下载器

漫画村是一家由日本人开设的日本免费漫画网站,可以看做日本版的DMZJ。然而,在漫画的发源地日本开设这样的网站(尽管运营方不选择在日本而是在他国登记网站信息,但是网站使用日语界面),自然会成为众矢之的。类似于“请于24小时内删除”和“计算机管理条例”之类的常用辞令,漫画村运营方也原引日本某些法律条文(见下图)以表示自己的行为并不违法。但是随着漫画村浏览量的极速增加(由此可见即使在日本也有众多用户),日本政府已于近日要求相关网络运营商协助封锁此网站。(但是也有人对此表示抗议:“日本互联网提供商协会发表反对声明,认为这等同于“侵犯通信秘密”,即使政府提出请求,原则上也不会配合。”)目前,漫画村已经无法访问,推测是运营方规避风头自行关闭了网站。前些日子漫画村还准备推出会员制度,会员能享受更快的服务器和更高清晰度的画质,但是现在也不了了之。详情请查阅维基百科“漫画村”。

最近还有一则关于漫画村的新闻:日本亚马逊Kindle上架的某部漫画作品的第13卷,其漫画预览图上竟然出现了“漫画村”的水印。这一现象所暗示的事实可以从侧面表现出漫画村在日本的影响力。

前些日子我想要找一部老漫画中的老图,可是这部老漫画无人翻译,也没有图源,最终只发现漫画村有这部作品。然而类似于其他在线漫画网站,漫画村也采取多种措施防止爬虫下载图片。只不过,不知是技术实力不足(应该不会)还是开放的态度,其防护措施虽然与其他站点类似,但力度远远弱于其他站点。接下来描述我搓的工具MangaGet的原理。由于漫画村已关站,具体代码也就不放出来了,但是对于实现类似的工具或者是研究爬虫技术而言,这应该可以作为参考。

漫画村(以下简称MM)有两种阅读方式:旧版阅读器和新版阅读器,其中旧版较为简单,类似于图片新闻网站,每页显示N幅图,通过上一页和下一页切换页面;新版则是每页显示一幅图,具有缩放等功能,点击屏幕左右区域翻页。我选择旧版作为研究对象。查看旧版的网页源码,通过JS代码可分析出其运作模式。

首先,MM用WebSocket进行客户端与服务器的控制连接,客户端随机连接42个服务器中的一个(这42个服务器的稳定性有差异)。客户端向一个固定的地址按照ID请求图片列表,返回的列表仅包含这一本作品中每张图片的文件名(数字编号,1.jpg~N.jpg)。 随后客户端可向服务器请求下载单张图片,需要提交文件名和cookie。此时,服务器可能会有多种不同的返回:

返回图片:这是最简单的一种模式,生成一个有时限的临时地址,访问这个地址即可直接下载此张图片,对于客户端和服务器来讲都是最节省的。MM的多数图片以这种方式返回。

返回blob(二进制大对象):以Base64编码的HTML形式(data:image/开头)返回图片。此时需取出其中的Base64部分并转为二进制后保存。MM对于*00(*>0)编号的图片以这种方式返回。

返回拼图(Jigsaw):MM中叫做返回iframe,因为它使用iframe嵌入拼图页面。尽管你从页面上看这张“图片”与上一张、下一张没有任何不同,但实际上这是一个内嵌的网页而非图片。拼图是日本在线漫画最常用、效果最好的防爬虫技术,它的原理是将一张图片打碎成许多小方块,提供给客户端时,要么每个小方块都随机生成临时的文件名,要么小方块临时组成一个乱序的整图传输过来,总之只有验证客户身份之后才会告诉客户端正确的顺序,让客户端的JS渲染出正确的图片,否则你直接爬到的就只有乱序或是破碎的图片。MM的拼图手段相较于其他专业网站而言并不复杂,只分为9块(其他网站大都分为64块以上)。我们只需访问iframe的页面,通过正则表达式匹配出每张小方块图的URL地址以及它所对应的实际位置(x,y)∈[0,2],然后在程序中使用诸如using System.Draw; Graphics.DrawImage();的语句将图片重新绘制为完整图片保存即可。MM对于*23和*75(*均大于0)编号的图片以这种方式返回。

要求验证:MM会在请求的图片编号>=110时要求一次recaptcha验证。这个验证结果会反馈到服务器,随后服务器给客户端设置正确的cookie(有效期1天),只有具有此cookie,才能继续请求访问剩下的图片。由上所述,这个流程是无法从客户端绕过的,我们所能做的是预先准备好可用的cookie。自动突破recaptcha超出了本文的范围,我们认为这种可以用一天的cookie是值得手动获取的。因此MangaGet会要求你先触发recaptcha并通过测试,在下载流程开始之前将cookie输入到程序。同一个cookie可以用于下载不同的作品,只要没有超时或被禁用。

运行截图如下:

添加评论

Loading