Scrapy爬取妹子图

2018-04-27 14:27:31 浏览数 (1)

本来呢,一开始想爬取的是这个网站,http://www.mzitu.com/,但是呢?问题发现比较多,所以先爬取了http://www.meizitu.com/这个网站,下一步再去爬取第一个。 GitHub地址:https://github.com/zhangpu1211/scrapy/tree/master/MeiZitu 首先看一下爬取结果

是不是很激动。。。下面开始正式工作

创建项目

这个就很简单啦,scrapy startproject MeiziTu

创建模板

也是我们之前提到了,用genspider创建一个basic模板 scrapy genspider image http://www.meizitu.com/tag/keai_64_1.html

建立main文件方便调试

和自动生成的scrapy.cfg在同一层,写入下面代码

代码语言:javascript复制
from scrapy.cmdline import execute
import sys,os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
execute(['scrapy','crawl','image'])
创建item

我们要爬取的内容,就是图集的地址,名称,以及图片的地址

代码语言:javascript复制
class MeizituItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field()
    imgs_url = scrapy.Field()
    url = scrapy.Field()
分析页面,确定爬取逻辑

目标是爬取可爱目录下的所有图集的图片,并把图片按名称归档,方便查看。 剩下的内容就是简单的用css提取名称和地址了

代码语言:javascript复制
class MeiZituSpider(scrapy.Spider):
    name = 'image'
    allowed_domains = ['meizitu.com']
    start_urls = ['http://www.meizitu.com/tag/keai_64_1.html']

    def parse(self, response):
        nodes = response.css('.wp-list .tit a')
        for node in nodes:
            url = node.css('::attr(href)').extract_first().strip()
            yield Request(url=parse.urljoin(response.url, url), callback=self.parse_detail)

        index = response.css('#wp_page_numbers li a::text').extract()
        if '下一页' in index:
            next_urls = response.css('#wp_page_numbers li a')[-2].css('a::attr(href)').extract_first()
            yield Request(url=parse.urljoin(response.url, next_urls),callback=self.parse)

    def parse_detail(self, response):
        item = MeizituItem()

        name = response.css('.postmeta h2 a::text').extract_first()
        imgs_url = response.css('.postContent p img::attr(src)').extract()
        item['name'] = name
        item['imgs_url'] = imgs_url
        item['url'] = response.url
        yield item
编辑pipeline实现图片归档

本来呢,我们可以用scrapy自己的'scrapy.pipelines.images.ImagesPipeline': 1,实现图片下载,但是这样下载下来乱糟糟的,没有美感,对于轻微的强迫症或者那就接受不了了。必须要按图集名字分个类 下面的代码继承自ImagesPipeline,通过重写file_path方法实现了图片分类,一开始只重写这个方法,发现不行,图片没有下载,后来发现必须要加上get_media_requests这个方法才可以。

代码语言:javascript复制
class ArticleImagePipeline(ImagesPipeline):
    def file_path(self, request, response=None, info=None):
        item = request.meta['item']
        title = item['name']
        image_guid = request.url.split('/')[-1]
        filename = 'full/{0}/{1}'.format(title, image_guid)
        return filename

    def get_media_requests(self, item, info):
        """
        :param item: spider.py中返回的item
        :param info:
        :return:
        """
        for img_url in item['imgs_url']:
            referer = item['url']
            yield Request(img_url, meta={'item': item,
                                         'referer': referer})
编辑setting文件
  • 设置遵循爬虫协议为False ROBOTSTXT_OBEY = False
  • 设置item图片字段为imgs_url,设置保存路径为同级目录下images
代码语言:javascript复制
IMAGES_URLS_FIELD = "imgs_url"
project_dir = os.path.abspath(os.path.dirname(__file__))
IMAGES_STORE = os.path.join(project_dir, 'images')
  • 增加浏览器头 USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'
  • 开启pipeline
代码语言:javascript复制
ITEM_PIPELINES = {
   'MeiZitu.pipelines.ArticleImagePipeline': 1,
   #'scrapy.pipelines.images.ImagesPipeline': 1,
}

至此,爬取结束,下一步就是爬取http://www.mzitu.com/,代码会更新在GitHub上!

0 人点赞