Python爬虫 - scrapy - 爬取妹子图 Lv2
0. 前言
这个文章是延续之前《爬取妹子图 Lv1》的延续,之前的爬虫可以爬取一个页面的图片,爬取一次大概400张图片的样子,按照之前的计划,本次要进一步完善爬虫,爬取妹子图全网图片。由于之前已经有了爬虫的雏形,所以本篇文章仅对增改内容进行说明。
系统环境
System Version:Ubuntu 16.04
Python Version:3.5.2
Scrapy Version:1.5.0
1. 爬虫文件
1.1. 完整文件
from scrapy import Request from scrapy.spiders import Spider from spider_meizitu.items import SpiderMeizituItem import re class MeizituSpider(Spider): name = 'meizitu' start_urls = { 'http://www.meizitu.com/a/more_1.html', } def parse(self, response): meizi_pic_lists = response.xpath('//ul[@class="wp-list clearfix"]/li') for i, meizi_item in enumerate(meizi_pic_lists): meizi_item_url = meizi_item.xpath('.//h3[@class="tit"]/a/@href').extract()[0] print('===== 当前爬取页面共有图片%s组,正在抓取第%s组图片,页面链接:: %s ====='% (len(meizi_pic_lists),i+1,meizi_item_url)) yield Request(meizi_item_url,callback=self.parse_meizi_pic) next_url = re.findall('<a href="(.*)">下一页</a>',response.xpath('//*[@id="wp_page_numbers"]').extract()[0]) print('next_url:::::',next_url) #print('response:::::',response.xpath('//*[@id="wp_page_numbers"]').extract()[0]) if next_url: next_url = 'http://www.meizitu.com/a/' + next_url[0] print('========== Request Next Url :: %s ==========' % next_url ) yield Request(next_url,callback=self.parse) def parse_meizi_pic(self,response): print('========== parse_meizi_pic response::: %s =========='% response) item = SpiderMeizituItem() meizitu_pics = response.xpath('//div[@id="picture"]/p/img') for i, meizitu_pic in enumerate(meizitu_pics): item['images'] = meizitu_pic.xpath('.//@alt').extract()[0].split(',')[0] item['image_urls'] = meizitu_pic.xpath('.//@src').extract() print('===== 当前页面共有图片%s张,正在抓取第%s张图片,图片链接:: %s ====='% (len(meizitu_pics),i+1,item['image_urls'])) yield item
1.2. 增改项目说明
1.2.1. import re
为了定位下一页的跳转链接,所以加入了正则表达式。
1.2.2. next_url
next_url = re.findall('<a href="(.*)">下一页</a>',response.xpath('//*[@id="wp_page_numbers"]').extract()[0])
利用正则表达式来提取下一页
的链接地址,re.findall
的第一个参数是正则表达式,第二个参数是要匹配的字符串。利用response.xpath
将页面中分页菜单部分的html代码提取出来用于正则匹配,返回的结果就是下一页
按钮中的超链接。如果当前页面是http://www.meizitu.com/a/more_1.html
,得到的url就是more_2.html
。
接下来就将得到的next_url 与主链接合并成完整链接,输出给parse函数继续处理。
2. settings
做完之前的改动后,我开始爬取页面图片,爬取more_1.html
页面之后可以正常跳转到more_2.html
,之后到more_3.html
、more_4.html
。但是出现一个问题就是在爬取到后期的时候,每个页面的39个项目中只能爬取到最后一个,有时候一个也爬不到,最终爬虫运行完毕后,我只得到了900+的图片。由于本人基础知识还不够扎实,只是有两方面怀疑,一是网站对请求做了限制,规定时间内如果请求过多则爬不到页面,二是scrapy的download队列有数量限制,爬取到大概50个页面的时候,好像队列就满了,无法再新增项目,只有前面的队列完成后,才能有新的项目进入队列。不论是哪个原因,我对setting做了些修改,打开或者增加了一些setting设置,具体如下:
配置Scrapy执行的最大并发请求 默认16
CONCURRENT_REQUESTS = 128
设置下载延迟 默认 0
DOWNLOAD_DELAY = 5
禁用cookies
COOKIES_ENABLED = False
日志输出基本,默认: 'DEBUG',log的最低级别。可选的级别有: CRITICAL、 ERROR、WARNING、INFO、DEBUG。
LOG_LEVEL = 'INFO'
做完上述改动后,爬虫运行基本正常,但是爬取的速度有点慢,12个小时大概爬取了9000张图片。
3. 后续
有心的朋友能够看到,在这两个爬虫实例中,我始终没有去写pipeline,一直使用scrapy自带的pipeline模块。但是默认的pipeline模块下载的图片名称不可读,下一步,我将重写pipeline组件,实现文件命名和分目录存储的功能。
最后,发一个我自己理解的这个爬虫的运行流程图,由于scrapy框架比较大,高端应用(如调度器、规则等)还没有用到,也没在这个图里体现出来,仅供新手学习。