1

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.htmlmore_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张图片。

clipboard.png

3. 后续

有心的朋友能够看到,在这两个爬虫实例中,我始终没有去写pipeline,一直使用scrapy自带的pipeline模块。但是默认的pipeline模块下载的图片名称不可读,下一步,我将重写pipeline组件,实现文件命名和分目录存储的功能。

最后,发一个我自己理解的这个爬虫的运行流程图,由于scrapy框架比较大,高端应用(如调度器、规则等)还没有用到,也没在这个图里体现出来,仅供新手学习。

clipboard.png


MrOriole
29 声望6 粉丝