你好,老司机:种子爬虫企划

在老司机的安利之下,学会了从琉璃神社找各种神奇的资源。于是萌生了造这个轮子的欲望。国内这种福利站不知还能维持多久,所以将资源大量扒下来存档是有点卵用的。

GitHub repo

https://github.com/Chion82/hello-old-driver

开发笔记

为了兼容多个站点,我的爬虫脚本并没有针对某个特定的网站进行抓取逻辑定制,而是采取递归遍历网站全部页面+正则匹配磁力链hash的方式抓取整站的磁力链资源。磁力链的hash协议大多数时候是BTIH,hash值为40位的hex字符串,匹配的正则如下:

1
[^0-9a-fA-F]([0-9a-fA-F]{40})[^0-9a-fA-F]

注意,为了保证hash串长度为40字节,在其前后应加上非hex的匹配,即[^0-9a-fA-F]

这样将可能导致一个问题,网站页面源码中可能还存在磁力链以外的SHA-1值,比如琉璃神社在每条用户评论后在一个标签属性内有40字节长的一段hash值,目前的解决方法是忽略HTML标签<>内的属性内容:

1
2
if (ignore_html_label): #为了增强扩展性,这类fix逻辑应该可控
result_text = re.sub(r'<.*?>', '', result_text)

每个磁力链资源应当要有对应的标题以方便查找,这里以网页的标题作为资源标题,匹配正则如下:

1
<title>(.+?)</title>

经测试发现,每轮抓取结束后,抓取到的资源数量可能不一样,可能的原因是网站方对访问频次做了限制或者是本地网络质量问题,就算通过连接失败重试、服务器返回5XX后重试等方法也不能解决。于是决定:每次抓取不覆盖上次抓取的结果,而是保留上次的结果,并新增本次抓取到的、上次结果中没有的新磁力链资源。

其他的一些必需属性:

1
2
3
4
5
6
cookie = '' #每次请求需要带上的Cookie。由于琉璃神社目前不需要登录,暂为空串
max_depth = 40 #递归最大深度,即从一个网页查找全部链接并依次往下递归访问,最大的深度为40
viewed_urls = [] #访问过的URL,避免重复访问
found_magnets = [] #查找出来的磁力链资源,避免重复抓取
ignore_url_param = True #是否忽略URL中的参数,比如"index.html?xxx=11"将被替换为"index.html"
ignore_html_label = True #是否忽略HTML标签内属性

需要定时执行抓取脚本以保证与原网站同步。写了一个shell脚本,sync.sh,作用如下:

  • 测试目标网站是否可访问
  • 复制上次的抓取结果magnet_outputresource_list.jsonarchives目录下存档,以当前时间重命名
  • 复制上次的抓取日志lastsync.loglasterror.loglog目录下存档,以当前时间重命名
  • 运行Python抓取脚本,这将覆盖项目根目录下的上述抓取结果文件和抓取日志文件
  • 将本次的抓取结果梗概(是否成功、新增几条记录以及一些简单统计数据)添加到README.md
  • 推送到GitHub