PS: 爬虫不进入img_url函数的小伙伴儿 请尝试将将代码复制到你新建的py文件中。 2017/8/30 更新解决了网站防盗链导致下载图片失败的问题 这几天一直有小伙伴而给我吐槽说,由于妹子图站长把www.mzitu.com/all这个地址取消了。导致原来的那个采集爬虫不能用啦。 正好也有小伙伴儿问Scrapy中的图片下载管道是怎么用的。 就凑合在一起把mzitu.com给重新写了一下。
首先确保你的Python环境已安装 Scrapy!!!!!!!! 命令行下进入你需要存放项目的目录并创建项目: 比如我放在了D:\PycharmProjects
1 |
D: |
我是Windows!其余系统的伙伴儿自己看着办哈。 这都不会的小伙伴儿,快去洗洗睡吧。养足了精神从头看一遍教程哈! 在PyCharm中打开我们的项目目录。 在mzitu_scrapy目录创建run.py。写入以下内容:
1 |
from scrapy.cmdline import execute |
其中的 mzitu 就为待会儿spider.py文件中的name属性。这点请务必记住哦!不然是跑不起来的。 在mzitu_scrapy\spider目录中创建spider.py。文件作为爬虫文件。 好了!现在我们来想想,怎么来抓mzitu.com了。 首先我们的目标是当然是全站的妹子图片!!! 但是问题来了,站长把之前那个mzitu.com\all 这个URL地址给取消了,我们没办法弄到全部的套图地址了! 我们可以去仔细观察一下站点所有套图的地址都是:http://www.mzitu.com/几位数字结尾的。 这种格式地址。 有木有小伙伴儿想到了啥? CrawlSpider !!!就是这玩儿!! 有了它我们就能追踪“http://www.mzitu.com/几位数字结尾的”这种格式的URL了。 Go Go Go Go!开始搞事。
首先在item.py中新建我们需要的字段。我们需要啥?我们需要套图的名字和图片地址!! 那我们新建三个字段:
1 |
import scrapy |
第一步完成啦!开始写spider.py啦! 首先导入我们需要的包:
1 |
from scrapy import Request |
都是干啥的我不说了哈!不知道的小伙伴儿自己去翻翻官方文档。 接下来是:
1 |
class Spider(CrawlSpider): |
第五行的img_urls=[] 这个列表是我们之后用来存储每个套图的全部图片的URL地址的。 rules中的语句是:匹配http://www.mzitu.com/1至6位数的的URL(\\d:数字;{1,6}匹配1至6次。就能匹配出1到6位数) 但是我们会发现网页中除了http://www.mzitu.com/XXXXXXX 这种格式的URL之外;还有 http://www.mzitu.com/XXXX/XXXX 这个格式的URL。所以我们需要设置 deny来不匹配http://www.mzitu.com/XXXX/XXXX这种格式的URL。 然后将匹配到的网页交给parse_item来处理。并且持续追踪 看这儿敲黑板!!划重点!!:::
重点说明!!!!不能parse函数!!这是CrawlSpider进行匹配调用的函数,你要是使用了!rules就没法进行匹配啦!!!
现在spider.py是这样的:
1 |
from scrapy import Request |
来跑一下试试 别忘了怎么测试的哈!!上面新建的那个run.py! Good!!真棒!全是我们想要的!!! 现在干啥?啥?你不知道?EXM你没逗我吧!
当然是解析我们拿到的response了!从里面找我们要的套图名称和所有的图片地址了! 我们随便打开一个URL。 首先用xpath取套图名称: 啥?你不知道怎么用xpath??少年少女 你走吧。出去别说看过我的博文。 ./*//div[@class=’main’]/div[1]/h2/text() 这段xpath就是套图名称的xpath了!看不懂的少年少女赶快去http://www.w3school.com.cn/看看xpath的教程! 当然你直接用Chrome拷贝出来的那个xpath也行。(有一定的概率不能使) 现在来找图片地址了,怎么找我在 小白爬虫第一弹中已经写过了哈!这就不详细赘述了! 首先找到每套图有多少张图片:
就是红框中的那个东东。 Xpath这样写:
1 |
descendant::div[@class='main']/div[@class='content']/div[@class='pagenavi']/a[last()-1]/span/text() |
意思是选取根节点下面所有后代标签,在其中选取出 div[@class=’main’]下面的div[@class=’content’]下面的/div[@class=’pagenavi’]下面的倒数第二个a标签 下面的span标签中的文本。(有点长哈哈哈哈哈!其实还可以短一些,我懒就不改了) 然后循环拼接处每张图片的的网页地址,现在spider.py是这样:
1 |
from scrapy import Request |
extract_first(default=”N/A”)的意思是:取xpath返回值的第一个元素。如果xpath没有取到值,则返回N/A 然后调用函数img_url来提取每个网页中的图片地址。img_url长这样:
1 |
def img_url(self, response,): |
descendant::div[@class=’main-image’]/descendant::img/@src这段xpath取出div[@class=’main-image’]下面所有的img标签的src属性(有的套图一个页面有好几张图) .extract()不跟上[0]返回的是列表 完整的spider.py如下:
1 |
from scrapy import Request |
下面开始把图片弄回本地啦!! 开写我们的pipelines.py 首先根据官方文档说明我们如果需要使用图片管道 则需要使用ImagesPipeline: 我们可以依葫芦画瓢写一个。但是这样有一个很麻烦的问题就是,这样下载下来的图片没有分类,很是难看啊! 所以 我们需要重写一下ImagesPipeline中的file_path方法! 具体如下:
1 |
# -*- coding: utf-8 -*- |
写一个中间件来处理图片下载的防盗链:
1 |
class MeiZiTu(object): |
最后一步设置ImagesPipeline的存储目录! 在settings.py中写入:
1 |
IMAGES_STORE = 'F:\mzitu\\' |
则ImagesPipeline将所有下载的图片放置在此目录下! 设置图片实效性: 图像管道避免下载最近已经下载的图片。使用 FILES_EXPIRES
(或 IMAGES_EXPIRES
) 设置可以调整失效期限,可以用天数来指定: 在settings.py中写入以下配置。
1 |
# 30 days of delay for images expiration |
settings.py中开启item_pipelines:
1 |
ITEM_PIPELINES = { |
settings.py中开启DOWNLOADER_MIDDLEWARES
1 |
DOWNLOADER_MIDDLEWARES = { |
如果你需要缩略图之类的请参考官方文档: 将其写入settings.py文件中。 至此完毕!!! 来看看效果:
下载速度简直飞起!!友情提示:请务必配置代理哦! 可以参考大才哥的http://cuiqingcai.com/3443.html做一个代理,就不需要重写Scrapy中间件啦!更能避免费代理总是不能用的坑爹行为。 总之省事省时又省心啊! github地址:https://github.com/thsheep/mzitu_scrapy