Scrapy学习第七课

Posted helenandyoyo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scrapy学习第七课相关的知识,希望对你有一定的参考价值。

python爬虫框架scrapy学习第七课

目标:爬取网页图片并保存

爬取网页中的图片,将图片下载到本地。

执行:爬取简书7日热门文章的图片

目标网页:简书7日热门文章图片

图片管道ImagesPipeline

爬虫结果基于管道pipeline进行处理,针对爬取的图片数据,scrapy提供图片管道ImagesPipeline进行处理。

1.其特性如下:

  • 将所有下载的图片转换成通用的格式(JPG)和模式(RGB)
  • 避免重新下载最近已经下载过的图片
  • 缩略图生成
  • 检测图像的宽/高,确保它们满足最小限制

这个管道也会为那些当前安排好要下载的图片保留一个内部队列,并将那些到达的包含相同图片的项目连接到那个队列中。 这可以避免多次下载几个项目共享的同一个图片。

2.工作流如下:

  • 在一个爬虫(自定义的爬虫类/文件),你抓取一个项目,把其中图片的URL放入 image_urls 组内(items文件定义)。
  • 项目从爬虫内返回,进入项目管道(pipeline文件)。
  • 当项目进入 ImagesPipeline,image_urls组内的URLs将被Scrapy的调度器和下载器(这意味着调度器和下载器的中间件可以复用)安排下载,当优先级更高,会在其他页面被抓取前处理。项目会在这个特定的管道阶段保持“locker”的状态,直到完成图片的下载(或者由于某些原因未完成下载)。
  • 当图片下载完,另一个组(images)将被更新到结构中。这个组将包含一个字典列表,其中包括下载图片的信息,比如下载路径、源抓取地址(从image_urls 组获得)和图片的校验码。 images 列表中的图片顺序将和源 image_urls组保持一致。如果某个图片下载失败,将会记录下错误信息,图片也不会出现在 images 组中。

图片存储

图片存储主要在settints.py文件中设置2个字段IMAGES_STORE和IMAGES_THUMBS。

  • 当设置了IMAGES_STORE的值后,图片自动保存路径如下。其中,3afec3b4765f8f0a07b78f98c07b83f013567a0a为图片的URL的 SHA1 hash 值。

<IMAGES_STORE>/full/3afec3b4765f8f0a07b78f98c07b83f013567a0a.jpg

  • 当设置了IMAGES_THUMBS的值之后,生成图片的缩略图。该字典值设置方式如下:

IMAGES_THUMBS =
‘small’: (50, 50),
‘big’: (270, 270),

  • 当生成缩略图时,需使用Pillow类库,将图片归一化为JPEG/RGB格式。执行如下命令安装。若没有提前安装,则在进行爬取保存图片时报“ ModuleNotFoundError: No module named ‘PIL’”错误。

pip install pillow

图片管道关键函数get_media_requests和item_completed

1.get_media_requests(self, item, info)

在工作流程中可以看到,管道会得到图片的URL并从项目中下载。当它们完成下载后,结果将以2-元素的元组列表形式传送到 item_completed() 方法。

2.2-元素的元组列表形式

[(True,
  'checksum': '2b00042f7481c7b056c4b410d28f33cf',
   'path': 'full/7d97e98f8af710c7e7fe703abc8f639e0ee507c4.jpg',
   'url': 'http://www.example.com/images/product1.jpg'),
 (True,
  'checksum': 'b9628c4ab9b595f72f280b90c4fd093d',
   'path': 'full/1ca5879492b8fd606df1964ea3c1e2f4520f076f.jpg',
   'url': 'http://www.example.com/images/product2.jpg'),
 (False,
  Failure(...))]
  • success 是一个布尔值,当图片成功下载时为True,因为某个原因下载失败为False
  • image_info_or_error 是一个包含下列关键字的字典(如果成功为 True )或者出问题时为 Twisted Failure。
  • url - 图片下载的url。这是从 get_media_requests() 方法返回请求的url。
  • path - 图片存储的路径(类似 IMAGES_STORE)。
  • checksum - 图片内容的 MD5 hash。

3.item_completed(self, results, item, info)

接收的元组列表与 get_media_requests() 方法返回请求的顺序相一致。results即为上述返回的2-元组列表。

示例

1.jian.py

# -*- coding: utf-8 -*-
import scrapy
from jiandan.items import JiandanItem

class JianSpider(scrapy.Spider):
    name = 'jian'
    allowed_domains = ['jianshu.com']
    start_urls = ['https://www.jianshu.com/trending/weekly?utm_medium=index-banner-s&utm_source=desktop']

    def parse(self, response):
        item = JiandanItem()
        #提取图片链接
        item['image_urls'] = response.xpath('//img//@src').extract()
        yield item

2.items.py

import scrapy


class JiandanItem(scrapy.Item):
    image_urls = scrapy.Field()
    images = scrapy.Field()

3.settings.py

DEFAULT_REQUEST_HEADERS = 
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  'Accept-Language': 'en',
  'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",

....
ITEM_PIPELINES = 
   'jiandan.pipelines.JiandanPipeline': 300,

IMAGES_STORE = 'D:\\SunWork\\python\\jiandan'
IMAGES_THUMBS = 
    'small': (50, 50),
    'big': (200, 200)

4.pipelines.py

import scrapy
from scrapy.exceptions import DropItem
from scrapy.pipelines.images import ImagesPipeline

class JiandanPipeline(ImagesPipeline):
    #重定义
    def get_media_requests(self, item, info):
        for image_url in item['image_urls']:
            image_url = "http://" + image_url
            yield scrapy.Request(image_url)

    #重定义
    def item_completed(self, results, item, info):
        images_paths = [x['path'] for ok, x in results if ok]
        if not images_paths:
           raise DropItem("Item contains no images")
        return item

其中

images_paths = [x['path'] for ok, x in results if ok]

的写法可以看做是如下写法的简写,参考https://www.python.org/dev/peps/pep-0202/ 的示例。

for ok, x in results:
    if ok:
        print(x['path'])

结果:图片保存结果展示

以上是关于Scrapy学习第七课的主要内容,如果未能解决你的问题,请参考以下文章

第七课 课程学习小问答

学习linux第七课!

学习linux第七课!

Python学习第七课-MOOC嵩天

Struts2学习第七课 ActionSupport

Linux学习第七课-文本处理工具及正则表达式