目录
基于 Python 的 Scrapy 爬虫入门:环境搭建
基于 Python 的 Scrapy 爬虫入门:页面提取
基于 Python 的 Scrapy 爬虫入门:图片处理
上篇文章中讲解了如何从网站页面抓取所需要的数据,很幸运范例中所需的数据是通过 Ajax 请求返回的 JSON 结构化数据,处理起来很简单,图片内容也只取了一个链接,对于我最初的目标“把这些图集添加到自己的博客站点中”这已经够了,说白了就是“盗链”嘛,如果有一天网站做了防盗链措施,那这些抄来的图集就都作废了,保险的方法就是把图片也下载到本地,再把图片链接替换为本地图片。
下载图片下载图片有两种方式,一种是通过 Requests 模块发送 get 请求下载,另一种是使用 Scrapy 的 ImagesPipeline 图片管道类,这里主要讲后者。
安装 Scrapy 时并没有安装图像处理依赖包 Pillow,需手动安装否则运行爬虫出错。
首先在 settings.py 中设置图片的存储路径:
IMAGES_STORE = "D:/"
图片处理相关的选项还有:
# 图片最小高度和宽度设置,可以过滤太小的图片 IMAGES_MIN_HEIGHT = 110 IMAGES_MIN_WIDTH = 110 # 生成缩略图选项 IMAGES_THUMBS = { "small": (50, 50), "big": (270, 270), }
更多选项请参考:https://doc.scrapy.org/en/lat...
之前已经存在提取内容的 TuchongPipeline 类,如果使用 ImagePipeline 可以将提取内容的操作都合并过来,但是为了更好的说明图片管道的作用,我们再多带带创建一个 ImagePipeline 类,加到 pipelines.py 文件中,同时重载函数 get_media_requests:
class PhotoGalleryPipeline(object): ... class PhotoPipeline(ImagesPipeline): def get_media_requests(self, item, info): for (id, url) in item["images"].items(): yield scrapy.Request(url)
上篇文章中我们把图片的URL保存在了 item["images"] 中,它是一个字典类型的数组,形如:[{img_id: img_url}, ...],此函数中需要把 img_url 取出并构建为 scrapy.Request 请求对象并返回,每一个请求都将触发一次下载图片的操作。
到 settings.py 中注册 PhotoPipeline,并把优先级设的比提取内容的管道要高一些,保证图片下载优先于内容处理,目的是如果有图片下载未成功,通过触发 DropItem 异常可以中断这一个 Item 的处理,防止不完整的数据进入下一管道:
ITEM_PIPELINES = { "Toutiao.pipelines.PhotoGalleryPipeline": 300, "Toutiao.pipelines.PhotoPipeline": 200, }
执行爬虫 scrapy crawl photo ,如无错误,在设定的存储目录中会出现一个 full 目录,里面是下载后的图片。
文件名处理下载的文件名是以图片URL通过 sha1 编码得到的字符,类似 0a79c461a4062ac383dc4fade7bc09f1384a3910.jpg 不是太友好,可以通过重载 file_path 函数自定义文件名,比如可以这样保留原文件名:
... def file_path(self, request, response=None, info=None): file_name = request.url.split("/")[-1] return "full/%s" % (file_name) ...
上面这样处理难免会有重名的文件被覆盖,但参数 request 中没有过多的信息,不便于对图片分类,因此可以改为重载 item_completed 函数,在下载完成后对图片进行分类操作。
函数 item_completed 的定义:
def item_completed(self, results, item, info)
参数中包含 item ,有我们抓取的所有信息,参数 results 为下载图片的结果数组,包含下载后的路径以及是否成功下载,内容如下:
[(True, {"checksum": "2b00042f7481c7b056c4b410d28f33cf", "path": "full/0a79c461a4062ac383dc4fade7bc09f1384a3910.jpg", "url": "http://www.example.com/files/product1.pdf"}), (False, Failure(...))]
重载该函数将下载图片转移到分类目录中,同时关联文件路径到 item 中,保持内容与图片为一个整体:
def item_completed(self, results, item, info): image_paths = {x["url"].split("/")[-1]: x["path"] for ok, x in results if ok} if not image_paths: # 下载失败忽略该 Item 的后续处理 raise DropItem("Item contains no files") else: # 将图片转移至以 post_id 为名的子目录中 for (dest, src) in image_paths.items(): dir = settings.IMAGES_STORE newdir = dir + os.path.dirname(src) + "/" + item["post_id"] + "/" if not os.path.exists(newdir): os.makedirs(newdir) os.rename(dir + src, newdir + dest) # 将保存路径保存于 item 中(image_paths 需要在 items.py 中定义) item["image_paths"] = image_paths return item
接下来在原 TuchongPipeline 类中写入数据库的操作中,通过 item["image_paths"] 路径信息写入本地图片链接。
除了 ImagesPipeline 处理图片外,还有 FilesPipeline 可以处理文件,使用方法与图片类似,事实上 ImagesPipeline 是 FilesPipeline 的子类,因为图片也是文件的一种。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/44518.html
摘要:目录基于的爬虫入门环境搭建基于的爬虫入门页面提取基于的爬虫入门图片处理下面创建一个爬虫项目,以图虫网为例抓取图片。 目录 基于 Python 的 Scrapy 爬虫入门:环境搭建 基于 Python 的 Scrapy 爬虫入门:页面提取 基于 Python 的 Scrapy 爬虫入门:图片处理 下面创建一个爬虫项目,以图虫网为例抓取图片。 一、内容分析 打开 图虫网,顶部菜单发现...
摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...
摘要:一基础环境由于不是职业的开发者,因此环境是基于的。二安装打开命令行工具创建虚拟环境,默认情况下会创建目录,所有的虚拟环境都会产生一个子目录保存在此,里面包含基本程序文件以及库文件。 目录 基于 Python 的 Scrapy 爬虫入门:环境搭建 基于 Python 的 Scrapy 爬虫入门:页面提取 基于 Python 的 Scrapy 爬虫入门:图片处理 作为一个全栈工程师(...
摘要:楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,。本文来源知乎作者路人甲链接楚江数据提供网站数据采集和爬虫软件定制开发服务,服务范围涵盖社交网络电子商务分类信息学术研究等。 楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,http://www.chujiangdata.com。 第一:Python爬虫学习系列教程(来源于某博主:htt...
阅读 2135·2021-10-08 10:15
阅读 1160·2019-08-30 15:52
阅读 495·2019-08-30 12:54
阅读 1510·2019-08-29 15:10
阅读 2668·2019-08-29 12:44
阅读 2986·2019-08-29 12:28
阅读 3325·2019-08-27 10:57
阅读 2185·2019-08-26 12:24