博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python图片爬取方法总结
阅读量:6937 次
发布时间:2019-06-27

本文共 5688 字,大约阅读时间需要 18 分钟。

1. 最常见爬取图片方法

对于图片爬取,最容易想到的是通过urllib库或者requests库实现。具体两种方法的实现如下:

1.1 urllib

使用urllib.request.urlretrieve方法,通过图片url和存储的名称完成下载。

'''Signature: request.urlretrieve(url, filename=None, reporthook=None, data=None)Docstring:Retrieve a URL into a temporary location on disk.Requires a URL argument. If a filename is passed, it is used asthe temporary file location. The reporthook argument should bea callable that accepts a block number, a read size, and thetotal file size of the URL target. The data argument should bevalid URL encoded data.If a filename is passed and the URL points to a local resource,the result is a copy from local file to new file.Returns a tuple containing the path to the newly createddata file as well as the resulting HTTPMessage object.File:      ~/anaconda/lib/python3.6/urllib/request.pyType:      function'''
  • 参数 finename 指定了保存本地路径(如果参数未指定,urllib会生成一个临时文件保存数据。)

  • 参数 reporthook 是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度。

  • 参数 data 指 post 到服务器的数据,该方法返回一个包含两个元素的(filename, headers)元组,filename 表示保存到本地的路径,header 表示服务器的响应头。

使用示例:

request.urlretrieve('https://img3.doubanio.com/view/photo/photo/public/p454345512.jpg', 'kids.jpg')

但很有可能返回403错误(Forbidden),如:。Stack Overflow指出原因:This website is blocking the user-agent used by urllib, so you need to change it in your request.

给urlretrieve加上User-Agent还挺麻烦,方法如下:

import urllibopener = request.build_opener()headers = ('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0')opener.addheaders = [headers]request.install_opener(opener)request.urlretrieve('http://www.qnong.com.cn/uploadfile/2016/0416/20160416101815887.jpg', './dog.jpg')

1.2 requests

使用requests.get()获取图片,但要将参数stream设为True

import requestsreq = requests.get('http://www.qnong.com.cn/uploadfile/2016/0416/20160416101815887.jpg', stream=True)with open('dog.jpg', 'wb') as wr:    for chunk in req.iter_content(chunk_size=1024):        if chunk:            wr.write(chunk)            wr.flush()

requests添加User-Agent也很方便,使用headers参数即可。


2. Scrapy 支持的方法

2.1 ImagesPipeline

Scrapy 自带 ImagesPipeline 和 FilePipeline 用于图片和文件下载,最简单使用 ImagesPipeline 只需要在 settings 中配置。

# settings.pyITEM_PIPELINES = {    'scrapy.pipelines.images.ImagesPipeline': 500}IMAGES_STORE = 'pictures'  # 图片存储目录IMAGES_MIN_HEIGHT = 400  # 小于600*400的图片过滤IMAGES_MIN_WIDTH = 600
# items.pyimport scrapyclass PictureItem(scrapy.Item):    image_urls = scrapy.Field()
# myspider.pyfrom scrapy.linkextractors import LinkExtractorfrom scrapy.spiders import CrawlSpider, Rulefrom ..items import BeePictureclass PicSpider(CrawlSpider):    name = 'pic'    allowed_domains = ['qnong.com.cn']    start_urls = ['http://www.qnong.com.cn/']    rules = (        Rule(LinkExtractor(allow=r'.*?', restrict_xpaths=('//a[@href]')), callback='parse_item', follow=True),    )    def parse_item(self, response):        for img_url in response.xpath('//img/@src').extract():            item = PictureItem()            item['image_urls'] = [response.urljoin(img_url)]            yield item

2.2 自定义 Pipeline

默认情况下,使用ImagePipeline组件下载图片的时候,图片名称是以图片URL的SHA1值进行保存的。

如:

图片URL:
SHA1结果:3afec3b4765f8f0a07b78f98c07b83f013567a0a
则图片名称:3afec3b4765f8f0a07b78f98c07b83f013567a0a.jpg

想要以自定义图片文件名需要重写 ImagesPipeline 的file_path方法。参考:。

# settings.pyITEM_PIPELINES = {    'qnong.pipelines.MyImagesPipeline': 500,}
# items.pyimport scrapyclass PictureItem(scrapy.Item):    image_urls = scrapy.Field()    images = scrapy.Field()    image_paths = scrapy.Field()
# myspider.pyfrom scrapy.linkextractors import LinkExtractorfrom scrapy.spiders import CrawlSpider, Rulefrom ..items import BeePictureclass PicSpider(CrawlSpider):    name = 'pic'    allowed_domains = ['qnong.com.cn']    start_urls = ['http://www.qnong.com.cn/']    rules = (        Rule(LinkExtractor(allow=r'.*?', restrict_xpaths=('//a[@href]')), callback='parse_item', follow=True),    )    def parse_item(self, response):        for img_url in response.xpath('//img/@src').extract():            item = PictureItem()            item['image_urls'] = [response.urljoin(img_url)]            yield item
# pipelines.pyfrom scrapy.exceptions import DropItemfrom scrapy.pipelines.images import ImagesPipelineimport scrapyclass MyImagesPipeline(ImagesPipeline):    def get_media_requests(self, item, info):        for img_url in item['image_urls']:            yield scrapy.Request(img_url)    def item_completed(self, results, item, info):        image_paths = [x['path'] for ok, x in results if ok]        if not image_paths:            raise DropItem('Item contains no images')        item['image_paths'] = image_paths        return item    def file_path(self, request, response=None, info=None):        image_guid = request.url.split('/')[-1]        return 'full/%s' % (image_guid)

2.3 FilesPipeline 和 ImagesPipeline 工作流程

FilesPipeline

  1. 在一个爬虫里,你抓取一个项目,把其中图片的URL放入 file_urls 组内。

  2. 项目从爬虫内返回,进入项目管道。

  3. 当项目进入 FilesPipeline,file_urls 组内的 URLs 将被 Scrapy 的调度器和下载器(这意味着调度器和下载器的中间件可以复用)安排下载,当优先级更高,会在其他页面被抓取前处理。项目会在这个特定的管道阶段保持“locker”的状态,直到完成文件的下载(或者由于某些原因未完成下载)。

  4. 当文件下载完后,另一个字段(files)将被更新到结构中。这个组将包含一个字典列表,其中包括下载文件的信息,比如下载路径、源抓取地址(从 file_urls 组获得)和图片的校验码(checksum)。 files 列表中的文件顺序将和源 file_urls 组保持一致。如果某个图片下载失败,将会记录下错误信息,图片也不会出现在 files 组中。

ImagesPipeline

  1. 在一个爬虫里,你抓取一个项目,把其中图片的 URL 放入 images_urls 组内。

  2. 项目从爬虫内返回,进入项目管道。

  3. 当项目进入 Imagespipeline,images_urls 组内的URLs将被Scrapy的调度器和下载器(这意味着调度器和下载器的中间件可以复用)安排下载,当优先级更高,会在其他页面被抓取前处理。项目会在这个特定的管道阶段保持“locker”的状态,直到完成文件的下载(或者由于某些原因未完成下载)。

  4. 当文件下载完后,另一个字段(images)将被更新到结构中。这个组将包含一个字典列表,其中包括下载文件的信息,比如下载路径、源抓取地址(从 images_urls 组获得)和图片的校验码(checksum)。 images 列表中的文件顺序将和源 images_urls 组保持一致。如果某个图片下载失败,将会记录下错误信息,图片也不会出现在 images 组中。

Scrapy 不仅可以下载图片,还可以生成指定大小的缩略图。

Pillow 是用来生成缩略图,并将图片归一化为 JPEG/RGB 格式,因此为了使用图片管道,你需要安装这个库。

转载地址:http://zjbnl.baihongyu.com/

你可能感兴趣的文章
正则表达式校验IP地址
查看>>
Exchange 常见问题之二----5
查看>>
Linux学习网站
查看>>
CentOS防火墙iptables的配置方法详解
查看>>
puppet客户端取消主动更新
查看>>
redis 3.0.7 安装部署
查看>>
微软职位内部推荐-Sr. SE - Office incubation
查看>>
如何查看mysql的用户及授权
查看>>
有趣的指针
查看>>
<Power Shell>新的征程
查看>>
使用FFmpeg新解码API解封装解码音视频(代码实例)
查看>>
【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!...
查看>>
Windows 服务器系统的服务概述和网络端口要求
查看>>
SQLite操作
查看>>
安装Gogs及简单配置(使用默认数据库)
查看>>
Linux 常用命令
查看>>
奔向新纪元,Vista安装经历
查看>>
Centos7无法使用ssh登陆及解决方案
查看>>
应用强制访问控制管理网络服务
查看>>
RedisLive监控Redis服务
查看>>