Python爬虫(二十一)scrapy图片爬取

141 阅读2分钟

我们现在可以使用scrapy框架熟练的爬取贝壳网全站的数据。但这里也只是爬取文本。我这里我想爬取一下每条数据的经纪人图,这里我们该如何操作呢?

 

爬取图片这个属于老生常谈了。对爬取图片原理不了解的同学,请移步《Python爬虫(三)图片数据爬取》当然,这里说的是基于request请求的图片爬取。

 

scrapy爬取图片只需要将img的src属性值进行解析,提交到管道,管道就会对图片的src请求发送获取图片的二进制类型的数据,且还会帮我们进行持久化存储。

 

重点说明一下,我这里爬取的是列表页每条数据详情页里边的经纪人的图片,对,没错,还是深度爬取。

 

那都深度爬取了,之前的代码就能用上了,这个好~

 

新建一个文件:

imgBeike.py:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2022/3/31 18:01
# @Author  : camellia
# @Email   : 805795955@qq.com
# @File    : beike.py
# @Software: PyCharm

import time

import scrapy
import asyncio
import requests
import random
from scrpayProject.items import ScrpayprojectItem

# 解析贝壳二手房页面的房源图片及标题
class TotalBeikeSpider(scrapy.Spider):
    name = 'imgBeike'
    # allowed_domains = ['www.beike.com']
    start_urls = ['https://dl.ke.com/ershoufang/']
    # start_urls = ['https://dl.ke.com/ershoufang/102105500760.html']

    page_num = 1

    def parse_detail(self,response):
        """
        爬取深一层的页面的数据
        """
        item = response.meta['item']
        src = response.xpath('//*[@id="zuanzhan"]/div[2]/div/div[1]/div[1]/a/img/@src').extract()
        item['src'] = src[0]
        print(src)
        yield item  # 将item提交给管道

    def parse(self, response):
        divList = response.xpath('/html/body/div[1]/div[4]/div[1]/div[4]/ul/li[1]')
        title = []
        for div in divList:
            title = div.xpath('//ul[@class="sellListContent"]//img[@class="lj-lazy"]/@title').extract()
            hreflist = div.xpath('//ul[@class="sellListContent"]//div[@class="title"]//a[@data-click-event="SearchClick"]/@href').extract()
            for ind, it in enumerate(title):
                item = ScrpayprojectItem()
                detail_url = hreflist[ind]
                # 爬取深一层的页面的数据
                yield scrapy.Request(url=detail_url, callback=self.parse_detail, meta={'item': item})
                yield item  # 将item提交给管道

            if self.page_num <= 1:
                new_url = 'https://dl.ke.com/ershoufang/pg'+str(self.page_num)+'/'
                self.page_num += 1
                # 手动请求发送:callback回调函数是专门用作与数据解析
                yield scrapy.Request(url=new_url,callback=self.parse)

在管道文件中自定义一个基于ImagesPipeline的一个管道类

pipelines.py

from scrapy.pipelines.images import ImagesPipeline
import scrapy

class imgsPipeline(ImagesPipeline):
    # 就是可以根据图片地址进行图片数据请求
    def get_media_requests(self,item,info):
        yield scrapy.Request(item['src'])

    # 指定图片存储路径
    def file_path(self,request,response=None,info=None):
        imgName = request.url.split('/')[-1]
        return imgName

    def item_completed(self,results,item,info):
        return item # 返回给下一个即将被执行的管道类

 

定义一下items中的字段:

Items.py

import scrapy
class ScrpayprojectItem(scrapy.Item):
    # define the fields for your item here like:
    src = scrapy.Field()
    pass

 

我们还需要定义一下爬取图片的存储位置:

Setting.py

# 爬取图片存储位置
IMAGES_STORE = './imgs'

 

这里我们来测试一下,打开终端执行命令:

scrapy crawl imgBeike

 

打开项目根目录发现生成了一个新目录imgs,打开目录,发现图片爬取成功:

11111111111.png

 

以上大概就是基于scrapy框架爬取图片的一个小例子。

 

水平有限,如有错误的地方,请指出,勿喷。

 

有好的建议,请在下方输入你的评论。