Python爬虫5.9 您所在的位置:网站首页 cbnertvirtul框架下载 Python爬虫5.9

Python爬虫5.9

2024-07-16 13:22| 来源: 网络整理| 查看: 265

Python爬虫5.9 — scrapy框架下载文件和图片 综述下载文件和图片使用Scrapy框架内置方法的好处下载文件的`File Pipeline`下载图片的`Images Pipeline`实例说明传统下载方式使用`Scrapy`框架自带`ImagesPipeline`进行下载图片 其他博文链接

综述

本系列文档用于对Python爬虫技术的学习进行简单的教程讲解,巩固自己技术知识的同时,万一一不小心又正好对你有用那就更好了。 Python 版本是3.7.4

本篇文章主要pipeline模块下载文件和图片的使用。

下载文件和图片

Scrapy为下载item中包含的文件(比如再爬取到产品时,同时也想保存到对应图片)提供了一个可重用的item pipeline。这些pipeline有些共同的方法和结构(我们称之为media Pipeline),一般来说我们会使用到File Pipeline和Images Pipeline。

使用Scrapy框架内置方法的好处

我们为什么要选择用Scrapy内置的下载文件的防范:

避免重复下载最近已经下载过的数据。可以方便的指定文件存储的路径。可以将下载的图片转存成通用的格式,比如png或jpg可以方便的生成缩略图。可以方便的检测图片的宽和高,确保他们满足最小限制。异步下载,效率非常高。 下载文件的File Pipeline

当使用File Pipeline下载文件的时候,按照以下步骤来完成:

定义好一个Item,然后再这个Item中定义两个属性,分别为file_urls以及files。file_urls是用来存储需要下载的文件的url链接,需要给一个列表。当文件下载完成后,会把文件下载相关的信息存储到item的files属性中。比如下载路径、下载的url和文件的校验码等。在配置文件setting.py中配置FILES_STORE,这个配置时用来设置文件下载下来的路径。启动pipeline:在ITEM_PIPELINES中设置scrapy.pipelines.files.FilesPipeline:1。 下载图片的Images Pipeline

当使用Images Pipeline下载文件的时候,按照以下步骤来完成:

定义好一个Item,然后再这个Item中定义两个属性,分别为image_urls以及images。image_urls是用来存储需要下载的图片的url链接,需要给一个列表。当文件下载完成后,会把图片下载相关的信息存储到item的images属性中。比如下载路径、下载的url和图片的校验码等。在配置文件setting.py中配置IMAGES_STORE,这个配置时用来设置文件下载下来的路径。启动pipeline:在ITEM_PIPELINES中设置scrapy.pipelines.images.ImagesPipeline:1。 实例说明

我们就以爬取汽车之家中的图片为例。

传统下载方式

传统的下载方式在这里就简单说下步骤:

使用scrapy命令创建项目;使用命令创建爬虫;更改setting.py文件配置信息;编写items.py代码;编写spider模块下代码(爬取网页中需要下载的图片链接);编写pipelines.py代码(进行数据处理,图片的保存等)。

pipelines.py代码如下:

import os import urllib.request class BmwPipeline(object): def __init__(self): # 创建文件保存文件夹 self.image_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images') if not os.path.exists(self.image_path): os.mkdir(self.image_path) def process_item(self, item, spider): category = item['category'] img_urls = item['img_urls'] # 创建图片类别文件夹 category_path = os.path.join(self.image_path, category) if not os.path.exists(category_path): os.mkdir(category_path) # 根据图片url进行下载保存图片 for url in img_urls: img_name = url.split('_')[-1] urllib.request.urlretrieve(url=url, filename=os.path.join(category_path, img_name)) print(img_name) return item

通过上述代码我们就可以将爬取的图片url进行处理保存图片到本地。但是这种处理方式一个很大的缺点就是图片只能一个一个下载不能进行异步下载。下面我们使用Scrapy框架中自带的图片下载进行下载图片。

使用Scrapy框架自带ImagesPipeline进行下载图片

按照上述的步骤进行编写相应的代码:

定义好一个Item,然后再这个Item中定义两个属性,分别为image_urls以及images。编写items.py代码如下:import scrapy class BmwItem(scrapy.Item): category = scrapy.Field() image_urls = scrapy.Field() images = scrapy.Field() 在配置文件setting.py中配置IMAGES_STORE。增加代码如下:# 图片下载路径,供image pipeline使用 IMAGES_STORE = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images') 启动pipeline:在ITEM_PIPELINES中设置scrapy.pipelines.images.ImagesPipeline:1。修改代码如下:ITEM_PIPELINES = { # 'bmw.pipelines.BmwPipeline': 300, 'scrapy.pipelines.images.ImagesPipeline': 1 } 编写spider模块代码如下:import scrapy from bmw.items import BmwItem class Bmw5Spider(scrapy.Spider): name = 'bmw5' allowed_domains = ['car.autohome.com.cn'] start_urls = ['https://car.autohome.com.cn/pic/series/65.html'] def parse(self, response): uiboxs = response.xpath('//div[@class="uibox"]')[1:] for uibox in uiboxs: category = uibox.xpath('.//div[@class="uibox-title"]/a/text()').get() img_urls_tmp = uibox.xpath('.//ul/li/a/img/@src').getall() img_urls = list(map(lambda url:response.urljoin(url),img_urls_tmp)) item = BmwItem(category=category,image_urls=img_urls) yield item

运行代码你会发现其能很快的将图片下载完成。下载完成后你会在你定义的图片保存文件夹images下多了一个full文件夹,这个里面就是所下载下来的所有图片。有的想问如果我还想要根据分类继续保存图片需要怎么办呢?这就需要我们去重写ImagesPipeline类中的一些方法了。通过读ImagesPipeline类的代码我们可以知道,类中有两个方法分别是get_media_requests和file_path。

get_media_requests : 这个方法是在发送下载请求之前调用,其实这个方法本身就是去发送下载请求的。file_path : 这个方式是在图片将要被存储时候调用,来获取这个图片的存储路径。

优化方案如下:

在pipelines.py中重写声明定义一个类,继承ImagesPipeline;在此子类中重新这两个方法代码如下:import os import urllib.request from scrapy.pipelines.images import ImagesPipeline from bmw import settings class BmwImagesPipeline(ImagesPipeline): # 重写get_media_requests方法 def get_media_requests(self, item, info): # 这个方法是在发送下载请求之前调用 # 其实这个方法本身就是去发送下载请求的 request_objs = super(BmwImagesPipeline, self).get_media_requests(item, info) # 将item数据加入到请求中 for requests_obj in request_objs: requests_obj.item = item return request_objs # 重写file_path方法 def file_path(self, request, response=None, info=None): # 这个方式是在图片将要被存储时候调用,来获取这个图片的存储路径 # 获取父类返回的保存地址 path = super(BmwImagesPipeline, self).file_path(request, response, info) category = request.item.get('category') images_store = settings.IMAGES_STORE # 创建图片分类文件夹 category_path = os.path.join(images_store, category) if not os.path.exists(category_path): os.mkdir(category_path) # 重新返回新的图片保存路径 image_name = path.replace('full/', '') image_path = os.path.join(category_path, image_name) return image_path 重新修改setting.py中的ITEM_PIPELINES配置如下:ITEM_PIPELINES = { # 'bmw.pipelines.BmwPipeline': 300, # 'scrapy.pipelines.images.ImagesPipeline': 1 'bmw.pipelines.BmwImagesPipeline': 300, }

之后运行代码即可。

其他博文链接 Python爬虫1.1 — urllib基础用法教程Python爬虫1.2 — urllib高级用法教程Python爬虫1.3 — requests基础用法教程Python爬虫1.4 — requests高级用法教程Python爬虫2.1 — BeautifulSoup用法教程Python爬虫2.2 — xpath用法教程Python爬虫3.1 — json用法教程Python爬虫3.2 — csv用法教程Python爬虫3.3 — txt用法教程Python爬虫4.1 — threading(多线程)用法教程Python爬虫4.2 — ajax(动态网页数据抓取)用法教程Python爬虫4.3 — selenium基础用法教程Python爬虫4.4 — selenium高级用法教程Python爬虫4.5 — tesseract(图片验证码识别)用法教程Python爬虫5.1 — scrapy框架简单入门Python爬虫5.2 — scrapy框架pipeline模块的使用Python爬虫5.3 — scrapy框架spider[Request和Response]模块的使用Python爬虫5.4 — scrapy框架items模块的使用Python爬虫5.5 — scrapy框架logging模块的使用Python爬虫5.6 — scrapy框架setting模块的使用Python爬虫5.7 — scrapy框架Shell命令的使用Python爬虫5.8 — scrapy框架CrawlSpider模块的使用


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有