前言

从上一年年末开始,我一直使用各种爬虫工具看漫画,这些爬虫工具引起了我浓厚的学习兴趣。于是脑海中产生了自己写爬虫工具的想法。后来我通过对tachiyomi,cimoc等开源项目以及各种博客的学习中了解到了基本的爬虫原理,然后着手实践起来。

声明

  1. 本人博文内容皆仅限用于学习和研究,部分敏感内容来源于互联网
  2. 如果侵犯了您的版权请通过我的邮箱B站账号与我获得联系,我会尽快删除相关内容

简单的漫画爬虫过程

  1. 使用抓包工具如Charles等截获浏览器或app的http和https请求
  2. 获取并分析截获的api接口,从中提取关键信息(漫画的搜索关键字、章节、每张图片等在URL中的位置)
  3. 从漫画关键字搜索api中获取精准漫画信息
  4. 从漫画信息中提取漫画id或漫画路径
  5. 使用漫画id等关键信息访问章节api获取当前漫画所有章节
  6. 从单个章节中获取其所有图片列表
  7. 使用IO流下载图片

爬虫实践过程

  1. 第一个爬虫项目:https://github.com/KBdog/crawler-comic-dmzj ,完成时间:2021-01-26
    这是我第一个爬虫项目,是通过分析dmzj网页版的标签来获取图片url下载,并不完全按以上顺序来进行。这个项目使用了selenium对网页进行模拟人工操作,通过ChromeDriver访问单点漫画首页获取所有章节标签链接,然后根据每个章节开多线程访问获得各章图片列表url。分析标签和下载使用了webmagic,在pipeline中使用io流对分析后的图片集合进行下载。(这次的项目还特意用javafx写了图形化界面,后面发现过于花里胡哨并不实用,因此在后续的爬虫项目中取消了写图形化界面的想法,直接改用命令行运行)
  2. 第二个爬虫项目:https://github.com/KBdog/crawler-comic-dmzj2,完成时间:2021-02-01
    分析dmzj的api接口一步步进行数据搜集
    该项目参考了@SavvyM大佬对dmzj的抓包接口,这也是我第一次了解到api接口。大佬给出的接口信息:
    动漫之家搜索api:
    http://sacg.dmzj.com/comicsum/search.php?s=${comic/author}
    小说详情api:
    http://v2.api.dmzj.com/novel/${id}.json (旧)
    http://v3api.dmzj.com/novel/${id}.json (新)
    漫画详情api:
    http://v2.api.dmzj.com/comic/${id}.json (旧)
    http://v3api.dmzj.com/comic/comic_${id}.json(新)
    漫画下载api:
    https://imgzip.dmzj.com/${first_character/number}/${comic_id}}/${chapter_id}.zip
    其中
    ${first_character/number}:漫画名称首字母或者数字
    ${comic_id}:漫画id
    ${chapter_id}:章节id
    漫画章节信息api:
    http://v3api.dmzj.com/chapter/${comic_id}/${chapter_id}.json
    漫画章节吐槽api:
    http://v3api.dmzj.com/viewPoint/0/${comic_id}/${chapter_id}.json
    简单漫画的三要素为漫画简介、漫画章节、漫画图片,通过访问接口的信息分析得到,通常漫画的属性是按关键字、单漫画的id、单章节的id这个顺序来进行的。因此在代码中,我们可以通过解析接口返回的json数据来获得以上属性再逐步往下解析json最终使用io流下载图片。
  3. 第三个爬虫项目:https://github.com/KBdog/crawler-comic-copymanga,完成时间:2021-02-10
    使用httpcanary抓包copymanga的api并下载其资源
    由于各种各样的原因,dmzj的部分漫画隐藏了起来,通过抓包抓到的api仅仅能访问可供普通用户浏览的漫画,许多隐藏漫画都无法浏览下载,为了能浏览更多的漫画本人必须扩展漫画源。最后我选择了copymanga,其接口数据简单清晰。此次的项目中,我遇到了防盗链与代理的问题。通常网站都会做防盗链的处理,简单理解就是服务端会对你的请求头进行验证,其中referer的头信息如果没有包含要求的服务端要求的信息,则服务端会判断你访问该链接的方式并不是从他们网站跳转过去的,然后禁止访问。解决方案:在访问头信息中添加相应referer
    connection.setRequestProperty("Referer","http://xxx.com/");
    然后就是代理问题,由于源站是域外的网站,访问不稳定且使用io流下载时使用的是tcp连接,影响更大,因此必须设置代理访问。这里使用快代理等免费代理即可解决。代理商提供的通常为Socket,在代码中建立连接时,使用代理连接服务商的socket进行代理访问即可。