上周老师让我做一个爬虫,刚开始就是说下载一个网站里的图片,可以跳转到其他页面继续下载,于是花了两三天时间做了出来。还好二月在家学习了一点爬虫的基础知识,上手工作还是比较顺利的,经过几天的实践,感觉python水平有所提高,爬虫也有了更多了解。
这里需要做的爬虫任务比较地具体了,首先,从一个网址为起点,先把html下载下来,然后解析它里面的a和img标签,把他们的url存起来。对于a标签,还要记录一下哪些去过了,哪些没有去过;对于img标签,由于图像会很多,把他们放到多线程里下载。整体的处理流程还是比较简单的。
后面就是测试了,随便找了几个网站进行测试,增加了一些细节,比如较小的图片不保存,增加用关键词过滤a和img标签的url等等。代码放到github了,有需要的话可以使用一下,代码比较丑陋哈,python用的还不是特别多。
好啦,终于完成了!发给老师。
哈哈哈哈哈哈。。。
???不会吧???怎么会出问题呢?于是我打开这个网站。图片是在这个里面的,查看代码,是在一个iframe标签里,嵌入了另外一个html。而且这部分是运行了某些js之后加载出来的,并且由于是国外网站,网站加载特别慢。
这样啊,那就把iframe里面的这部分html手动存到一个文件再去读呗。嘿嘿嘿,完事儿代码发给老师喽
???大图???
再次检查这个网页,发现有这么一个选项:
原来我下载的是上面四个的那种缩略图,真正需要的是最后一个,IIIF格式的。大概类似于地图那样,一块一块拼起来的大图。那,我之前做的工作就完全不适用于这个喽?!
然后老师发我几个代码,其中有一个是下面这个
Dezoomigy
它是一个开源的工具,可以把博物馆里的那种拼接起来的大图一块一块下载下来,然后拼接再存储。源码在这里:
Dezoomify源码
后来我又找到一个Rust做的dezoomify工具,它提供了exe可以直接使用:
dezoomify工具
但是在用的过程中,我发现前者会在大概90%的进度时卡住,不能继续进行,原因未知(github issues里看到有人提问了,但是没有解决方法)。而后者,在下载图块的过程中,常常会timeout,如下图所示,于是一张大图就不能完整地下载下来(测的一张图是由176块组成的),虽然增加重连次数可以减少图块的缺失,但是只要有一小块不能下载下来,这个图就是不完整的。
所以现在看来现有的东西都不能直接拿来用了呀。然鹅,在上面这个图,我注意到timeout提示的URL是非常有规律的,比如图中最后一个是https:XXXXX/21159013/8192,0,1024,1024/1024,1024/XXXXXX.jpg,于是我在浏览器输入URL,打开,惊喜地看到图片块加载出来了,所以我猜测中间的四个数是图块的左上角坐标加图块长宽,后面两个数是图块长宽,于是我把数字换了一下,发现确实是可以显示出其他位置的图块的。
所以我考虑可以利用这个来把图片块的URL构造出来下载,如果下载失败,可以把该块的位置记录到一个文件中,后面再单独下载。下载完图块之后,按照位置信息把他们拼接即可。
处理流程与前面的图片爬虫相似。如下图所示,这里使用N个线程下载图片,下载成功的图在一个拼接线程进行拼图,失败的送到log线程中存储到一个文件中。
这里的info.json的url是用来获取大图的一些信息,这里我只需要用到大图的长和宽,这个URL也是根据缩略图URL构造出来的。
每个大图的图块会放到一个文件夹下面,图块用它的位置信息命名:
每当有一个图块信息送到拼图线程后,拼图线程就会进行拼接,最后得到下图,它有大概70MB:(这里有一个问题,每当有一张图下载下来,就会去读取,保存,由于图块比较多,会有大量的图片读取保存过程,这个我担心对性能有影响,不知道大家对这个怎么看?可以改成什么样的?我考虑过全部下载下来再一起拼图,但是担心会出现下一个大图图块下载下来了,前一张图还有一两张正在下载的情况出现)
这是最后拼出来的效果图:
最后,代码放在这里。有需要的话大家可以试用一下。
HarvardDownloader