scrapy 分文件夹爬取所有的图片
在之前的博客中,我们使用了requests模块爬取了bobopic所有的壁纸图片,但是requests是单进程单线程的, 当我们要爬取的图片量一大就会很慢
现在我们使用scrapy 分模块下载图片
首先我们需要在items.py中定义自己 需要的字段 ,这里有些东西需要注意
首先是里面有一些字段必须这么写,这是在源码里面规定的
所以我们需要至少得在items.py中定义这两个字段
# items.py
class BobopicItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
image_urls = scrapy.Field() # 图片的下载地址, 该字段是存储图片的列表
image_path = scrapy.Field() # 图片本地存储路径(相对路径)
title = scrapy.Field() # 图片名字
group = scrapy.Field() # 图片属于哪一个小分组
imgs_href = scrapy.Field() # 专题下载地址
file_name = scrapy.Field() # 专题下载地址
images = scrapy.Field() # 图片集合
# image_title = scrapy.Field() # 图片名称
l另外需要设置一下下载图片的文件夹的名称 在settings中设置
IMAGES_STORE = './bobopicimgs'
好比如我的路径这样设置,那么我的图片存储位置如图
这里的重点是 如何处理图片名并且分文件夹保存,因为图片在scrapy中会默认的使用哈希十六进制进行加密,看起来像是乱七八糟的符号,没有标识性,那么我们就需要自己在pipeline中自己写一个类并且继承ImagePipline并且重写两个方法,分别是get_media_requests和file_path
# get_media_requests这个方法接受返回的url 这个url是你自己在爬虫中自己提取并且使用yield返回的我们需要模仿源码写,需要修改的是返回 一个meta 带上我们提取到的文件夹名和图片名,我是直接将整个item传过去了
# file_path 见名知意,用来处理图片的路径, 不重写就会使用哈希对request.url进行加密 是一堆乱七八糟的文字, 我们只需接受从get_media_requests传递过来的数据,返回图片的路径 比如 天空之境/魔法少女.png
这样图片就会自动的被下载到天空之境这个文件夹中
那么还有需要注意的点 我在爬取bobopic的时候不加下载延迟会被识别 , 对方不给数据给我 我们需要在settings中添加一个下载延迟,这里我试过了 最快是0.5 秒 低于0.5数据给不全
DOWNLOAD_DELAY = 0.5
# 数据提取代码我放一下
# -*- coding: utf-8 -*-
import random
from pprint import pprint
import scrapy
from copy import deepcopy
import time
from ..items import BobopicItem
class BbpSpider(scrapy.Spider):
name = 'bbp'
allowed_domains = ['bobopic.com']
start_urls = ['https://bobopic.com/']
def parse(self, response):
article_list = response.xpath(".//div[@class='row posts-wrapper']/article")
for article in article_list:
item = BobopicItem()
item["file_name"] = article.xpath('./div/div[2]//h2[@class="entry-title"]/a/text()').extract_first()
item["imgs_href"] = article.xpath('./div/div[2]//h2[@class="entry-title"]/a/@href').extract_first()
pprint(item["imgs_href"])
yield scrapy.Request(
item["imgs_href"],
callback=self.detail_imgs,
meta={"item":deepcopy(item)},
dont_filter=True
)
def detail_imgs(self, response):
item = response.meta["item"]
images = response.xpath('.//div[@class="entry-content u-clearfix"]/p[position()>2]/img/@src').extract()
# item["image_urls"] = response.xpath('.//div[@class="entry-content u-clearfix"]/p[position()>2]/img/@src').extract()
# pprint(item["src"])
for img in images:
item = deepcopy(item)
item["image_urls"] = []
item["image_urls"].append(img)
item["title"] = images.index(img) + 1
# pprint(item)
yield item
代码我放到git上了, 朋友们可以自行下载, 有什么问题也欢迎联系我邮箱 zh15270924273@163.com
git地址: https://gitee.com/hanzhou521/pachongxiangmu/tree/master/spider_items