欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用 Scrapy 的 ImagesPipeline 下载图片

程序员文章站 2022-06-13 08:02:12
下载 百度贴吧 动漫壁纸吧 所有图片 定义item Spider spider 只需要得到图片的url,必须以列表的形式给管道处理 ImagesPipeline from scrapy.pipelines.images import ImagesPipeline 继承ImagesPipeline,重 ......

下载 百度贴吧-动漫壁纸吧 所有图片

定义item

使用 Scrapy 的 ImagesPipeline 下载图片

spider

spider 只需要得到图片的url,必须以列表的形式给管道处理

class picturespiderspider(scrapy.spider):
    name = 'picture_spider'
    allowed_domains = ['tieba.baidu.com']
    start_urls = ['https://tieba.baidu.com/f?kw=%e5%8a%a8%e6%bc%ab%e5%a3%81%e7%ba%b8']

    def parse(self, response):

        #   贴吧中一页帖子的id和标题
        theme_urls = re.findall(r'<a rel="noreferrer" href="/p/(\d+)" title="(.*?)" target="_blank" class="j_th_tit ">',
                                response.text, re.s)

        for theme in theme_urls:
            #   帖子的url
            theme_url = 'https://tieba.baidu.com/p/' + theme[0]
            #   进入各个帖子
            yield scrapy.request(url=theme_url, callback=self.parse_theme)

        #   贴吧下一页的url
        next_url = re.findall(
            r'<a href="//tieba.baidu.com/f\?kw=%e5%8a%a8%e6%bc%ab%e5%a3%81%e7%ba%b8&ie=utf-8&pn=(\d+)" class="next pagination-item " >下一页&gt;</a>',
            response.text, re.s)
        if next_url:
            next_url = self.start_urls[0] + '&pn=' + next_url[0]
            yield scrapy.request(url=next_url)

    # 下载每个帖子里的所有图片
    def parse_theme(self, response):
        item = postbaritem()
        #   每个贴子一页图片的缩略图的url
        pic_ids = response.xpath('//img[@class="bde_image"]/@src').extract()
        #   用列表来装图片的url
        item['pic_urls'] = []

        for pic_url in pic_ids:
            #   取出每张图片的名称
            item['pic_name'] = pic_url.split('/')[-1]
            #   图片url
            url = 'http://imgsrc.baidu.com/forum/pic/item/' + item['pic_name']
            #   将url添加进列表
            item['pic_urls'].append(url)

        #   将item交给pipelines下载
        yield item

        #   下完一页图片后继续下一页
        next_url = response.xpath('//a[contains(text(),"下一页")]/@href').extract_first()
        if next_url:
            yield scrapy.request('https://tieba.baidu.com' + next_url, callback=self.parse_theme)


imagespipeline

  • from scrapy.pipelines.images import imagespipeline
  • 继承imagespipeline,重写get_media_requests()和file_path()方法
from scrapy.pipelines.images import imagespipeline
import scrapy


class postbarpipeline(imagespipeline):
    #   需要headers的网站,再使用
    headers = {
        'user-agent': '',
        'referer': '',
    }

    def get_media_requests(self, item, info):
        for pic_url in item['pic_urls']:
            # 为每个url生成一个request
            yield scrapy.request(pic_url)
            # 需要请求头的时候,添加headers参数
            # yield scrapy.request(pic_url, headers=self.headers)

    def file_path(self, request, response=none, info=none):
        # 重命名(包含后缀名),若不重写这函数,图片名为哈希
        pic_path = request.url.split('/')[-1]
        return pic_path


settings文件

  • 激活管道
    使用 Scrapy 的 ImagesPipeline 下载图片

  • 设置图片保存地址
    使用 Scrapy 的 ImagesPipeline 下载图片

运行结果

使用 Scrapy 的 ImagesPipeline 下载图片