Scrapy爬虫框架之———— 多页爬取图片的信息

ok, 接下来我们要将怎样多页爬取图片的信息,以及如何下载图片。

知识点涉及到:

  1.    自动的翻页爬取

  2. 多个parse 之间的request 传递

  3. 构建图片爬取的通道

さあ!始めようぜ!

首先我们要爬取的网站是这个: 知名的动漫壁纸网 Konachan.net

确定了目标之后,我们的第一个任务是创建一个爬虫项目以及一个爬虫

scrapy startproject konachan

scrapy genspider kona konachan.net

然后就是我们要解析这个网页,主页给的都是缩略图,我们要高清大图,就像点开这样:

 所以我们还需要一个内置的网页的url, 我们可以在主页中进行爬取

那么我们任务开始,首先确定要爬取的内容,在items.py规定:(item.py文件如下)

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class KonachanItem(scrapy.Item):
    # define the fields for your item here like:
    #由于我们使用的是scrapy 自带的图片下载通道,所以url 和图片名称必须按照配置文件设置
    # 即 Item里面 url 信息设置为 image_urls, 图片名称信息 设置为images
     image_urls = scrapy.Field()  # 即 Item里面 url 信息设置为 image_urls
     images=scrapy.Field()        # 图片名称信息 设置为images
     detailed=scrapy.Field()      # 高清页面的url

    #由于我们使用的是scrapy 自带的图片下载通道,所以url 和图片名称必须按照配置文件设置
    # 即 Item里面 url 信息设置为 image_urls, 图片名称信息 设置为images

然后是观察我们爬取信息的元素,使用F12(鼠标右键——检查) 进行元素的查看:

 

通过检查我们可以发现,在每个class为inner的div下的一个class="thumb" 里面的href属性对应的 url地址(相对于http://kona.net的相对地址),我们可以通过xpath进行提取:

    def parse(self, response):
        #获得要爬取的url的相对地址
        url_list = response.xpath("//div[@class='inner']//a[@class='thumb']/@href").extract()
        # 获得url的绝对地址
        for url in url_list:
            item1=KonachanItem()
            item1["detailed"] = url
            item1["detailed"] = "http://konachan.net" + item1["detailed"]

然后我们还要爬取下一页信息,我们同样可以进行检查:

我们看到了,在这个里面 Next对应的网址是 在class="next_page"的a标签中。那么,我们同样可以通过xpath进行提取,

next_url= response.xpath("//a[@class='next_page']/@href").extract_first()
        next_url='http://konachan.net'+ next_url
        #这里仅仅是测试哈,考虑内存只爬取两页
        if(self.cnt<2):
            self.cnt+=1
            # 回调给自己,继续解析
            yield scrapy.Request(
                next_url,
                callback=self.parse
            )

然后,我们需要在写一个parse 函数爬取详情页的图片地址,我们将其命名为parse_detail

我们首先观察详情页:

对应的图片信息的url在class=content的div 下的 id为image的image标签里面的src属性,同样用xpath爬取。不过parse_detail函数必须首先获得parse里面爬取到detail 的url 的request请求,并且获得item里面的url信息,并且以此为爬取的网页。因此,我们补充parse函数的具体内容:

    def parse(self, response):
        #获得要爬取的url的相对地址
        url_list = response.xpath("//div[@class='inner']//a[@class='thumb']/@href").extract()
        # 获得url的绝对地址
        for url in url_list:
            item1=KonachanItem()
            item1["detailed"] = url
            item1["detailed"] = "http://konachan.net" + item1["detailed"]
            #将绝对地址给第二个解析函数 parse_detail 进行解析
            yield scrapy.Request(
                item1["detailed"],
                callback = self.parse_detail,
                meta={"item":item1}  #meta 以字典的形式传递item信息
            )

我们加入的如下部分,构造了一个Request请求,给pars_detail执行,并且把url信息用meta传递。

 yield scrapy.Request(
                item1["detailed"],
                callback = self.parse_detail,
                meta={"item":item1}  #meta 以字典的形式传递item信息
            )

结合上述所写,我们来写parse_detail 函数:

  #定义解析详情页的函数
    def parse_detail(self,response):
        #接受parse函数传递的请求,接受item信息
        item1=response.meta["item"]
        #解析网页
        item1["image_urls"] = response.xpath("//div[@class='content']//img/@src").extract()
        #确定每次都传一个url
        if len(item1["image_urls"])<2:
            item1["image_urls"] = item1["image_urls"]
        yield item1

ok,写完后,我们去写pipline.py

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html

import logging
logger= logging.getLogger(__name__)
class KonachanPipeline(object):
    def process_item(self, item, spider):
        logger.warning(item["inner_url"])
        return item

这里不过是让它把爬到的信息 以日志的形式输出而已(便于查看),可以不写不改。

接下来我们要使用scrapy自带的图片管道去下载图片,首先在spider中插入引用:

# -*- coding: utf-8 -*-
import scrapy
#引入定义的item
from  konachan.items import  KonachanItem
# 引入 scrapy 自带的图片爬取通道,注意在setting里面要进行注释。
from  scrapy.pipelines.images import ImagesPipeline

这个scrapy.pipelins.image.ImagePipeline需要在settings.py里面注册:

ITEM_PIPELINES = {
   'konachan.pipelines.KonachanPipeline': 300,
    # 对图片通道进行注册
    'scrapy.pipelines.images.ImagesPipeline':299

}

然后我们需要在settings.py 里面设置图片存取的文件名地址,以及用item的什么字段做需要下载的url.

我们可以看一个scrapy自带的ImagePiplines里面的source code:

MEDIA_NAME = 'image'

    # Uppercase attributes kept for backward compatibility with code that subclasses
    # ImagesPipeline. They may be overridden by settings.
    MIN_WIDTH = 0
    MIN_HEIGHT = 0
    EXPIRES = 90
    THUMBS = {}



    #这就是之前我们设置item属性为 image_urls以及images的原因:
    DEFAULT_IMAGES_URLS_FIELD = 'image_urls'
    DEFAULT_IMAGES_RESULT_FIELD = 'images'



    def __init__(self, store_uri, download_func=None, settings=None):
        super(ImagesPipeline, self).__init__(store_uri, settings=settings,
                                             download_func=download_func)

        if isinstance(settings, dict) or settings is None:
            settings = Settings(settings)

        resolve = functools.partial(self._key_for_pipe,
                                    base_class_name="ImagesPipeline",
                                    settings=settings)
        self.expires = settings.getint(
            resolve("IMAGES_EXPIRES"), self.EXPIRES
        )

        if not hasattr(self, "IMAGES_RESULT_FIELD"):
            self.IMAGES_RESULT_FIELD = self.DEFAULT_IMAGES_RESULT_FIELD
        if not hasattr(self, "IMAGES_URLS_FIELD"):
            self.IMAGES_URLS_FIELD = self.DEFAULT_IMAGES_URLS_FIELD

        self.images_urls_field = settings.get(
            resolve('IMAGES_URLS_FIELD'),
            self.IMAGES_URLS_FIELD
        )
        self.images_result_field = settings.get(
            resolve('IMAGES_RESULT_FIELD'),
            self.IMAGES_RESULT_FIELD
        )
        self.min_width = settings.getint(
            resolve('IMAGES_MIN_WIDTH'), self.MIN_WIDTH
        )
        self.min_height = settings.getint(
            resolve('IMAGES_MIN_HEIGHT'), self.MIN_HEIGHT
        )
        self.thumbs = settings.get(
            resolve('IMAGES_THUMBS'), self.THUMBS
        )

所以按照固定,我们还要在settings.py写图片的存储地址:

import  os
BOT_NAME = 'konachan'

SPIDER_MODULES = ['konachan.spiders']
NEWSPIDER_MODULE = 'konachan.spiders'
# 定义log等级,只显示warning
LOG_LEVEL="WARNING"

project_dir=os.path.abspath(os.path.dirname(__file__))  #获取当前爬虫项目的绝对路径
IMAGES_STORE = os.path.join(project_dir,'images')  #组装新的图片路径

IMAGES_URLS_FIELD='image_urls'  #图片使用的字段

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/66.0'

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

ok,完事大吉,我们可以运行我们的爬虫了!

scrapy crawl kona

结果 输出为:

 我们可以看懂,yield 返回了许多item ,并且都打印出来的item里面的url

我们查看我们保存图片的文件:

可以,看到图片被很好download了。

查看完全代码,可以查看我的github

https://github.com/Magicboomliu/ScrapyImage

 

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值