这个文章是延续以前《爬取妹子图 Lv1》的延续,以前的爬虫能够爬取一个页面的图片,爬取一次大概400张图片的样子,按照以前的计划,本次要进一步完善爬虫,爬取妹子图全网图片。因为以前已经有了爬虫的雏形,因此本篇文章仅对增改内容进行说明。html
System Version:Ubuntu 16.04
Python Version:3.5.2
Scrapy Version:1.5.0正则表达式
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
为了定位下一页的跳转连接,因此加入了正则表达式。segmentfault
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
。cookie
接下来就将获得的next_url 与主连接合并成完整连接,输出给parse函数继续处理。并发
作完以前的改动后,我开始爬取页面图片,爬取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张图片。scrapy
有心的朋友可以看到,在这两个爬虫实例中,我始终没有去写pipeline,一直使用scrapy自带的pipeline模块。可是默认的pipeline模块下载的图片名称不可读,下一步,我将重写pipeline组件,实现文件命名和分目录存储的功能。ide
最后,发一个我本身理解的这个爬虫的运行流程图,因为scrapy框架比较大,高端应用(如调度器、规则等)尚未用到,也没在这个图里体现出来,仅供新手学习。函数