Scrapy实战(爬取图片并保存在本地)

学习了Scrapy,那就先爬点图片看看。

 

首先明确目标,要爬取什么?

 

我们爬取“孔夫子旧书网”所有书籍的图片及信息

 

上面标注的就是我们要爬取的信息,确定了目标,就可以编写items.py

import scrapy


class MyscrapyItem(scrapy.Item):

    # 普通字段
    title = scrapy.Field()
    author = scrapy.Field()
    time = scrapy.Field()
    new_price = scrapy.Field()
    old_price = scrapy.Field()

    # 爬取图片并保存需要的字段
    image_urls = scrapy.Field()
    images = scrapy.Field()
    image_paths = scrapy.Field()

 

分析页面,查看我们要获取的信息的存放位置

 

这是一个页面的信息,当前页面存在下一页的话,我们要获取下一页的信息

 

编写spider.py

import scrapy

import re
from scrapy import Request
from ..items import MyscrapyItem


class KongfzSpider(scrapy.Spider):
    name = 'kongfz'
    allowed_domains = ['kongfz.com']
    start_urls = ['http://item.kongfz.com/Cjisuanji/']

    def parse(self, response):
        divs = response.xpath("//div[@id='listBox']/div")
        for div in divs:

            item = MyscrapyItem()
            item['title'] = div.xpath("./div[@class='item-info']//a/text()").get()
            item['author'] = div.xpath("./div[@class='item-info']//span[1]/text()").get()
            item['time'] = div.xpath("./div[@class='item-info']//span[3]/text()").get()
            item['new_price'] = div.xpath("./div[@class='item-other-info']/div[1]//span[@class='price']/text()").get()
            item['old_price'] = div.xpath("./div[@class='item-other-info']/div[2]//span[@class='price']/text()").get()
            item['image_urls'] = [div.xpath(".//div[@class='big-img-box']/img/@src").get()]

            print(item)
            yield item

        # 翻页
        next_url = response.xpath("//a[@class='next-btn']/@href").get()
        if next_url is not None:
            yield response.follow(next_url, callback=self.parse)

 

编写middlewares.py,在请求每个页面时,需要做反反爬操作

    def process_request(self, request, spider):
        # 在请求页面时伪装成站内请求,用以反 反爬虫
        referer = request.url
        if referer:
            request.headers['referer'] = referer
        return None

 

编写pipelines.py,自定义图片下载设置

from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
from scrapy import Request
# from scrapy import log
import hashlib
from scrapy.utils.python import to_bytes


class MyscrapyPipeline:
    def process_item(self, item, spider):
        # print(item)
        return item


class KongfzImgDownloadPipeline(ImagesPipeline):

    # 设置下载文件请求的请求头
    default_headers = {
        'accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'zh-CN,zh;q=0.9',
        'referer': 'http://item.kongfz.com/Cjisuanji/',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0',
    }

    # 伪装成站内请求,反反爬
    def get_media_requests(self, item, info):
        for image_url in item['image_urls']:
            self.default_headers['referer'] = image_url
            yield Request(image_url, headers=self.default_headers)

    # 自定义 文件路径 和 文件名
    def file_path(self, request, item, response=None, info=None):
        image_guid = hashlib.sha1(to_bytes(request.url)).hexdigest()
        return f'full/{item["title"]}/{image_guid}.jpg'

    # 获取文件的存放路径
    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

 

最后配置settings.py

import os

BOT_NAME = 'myscrapy'

SPIDER_MODULES = ['myscrapy.spiders']
NEWSPIDER_MODULE = 'myscrapy.spiders'


FEED_EXPORT_ENCODING = 'utf-8'

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False     # false 表示不遵循robot.txt 协议

# 注释:表示没有开启cookie, false:表示使用setting里设置的cookie, true: 表示使用自定义的cookie
COOKIES_ENABLED = True

# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
   'myscrapy.middlewares.MyscrapyDownloaderMiddleware': 543,   # 启用下载中间件,在请求页面时伪装成站内请求,用以反 反爬虫
}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'myscrapy.pipelines.KongfzImgDownloadPipeline': 300,
}

IMAGES_STORE = 'D:\\images'  # 设置保存图片的根目录

 

各个步骤均已完成,那就开始让你的爬虫表演吧

scrapy crawl kongfz -o kongfz.json

 

 

......,,......,去喝了杯水后

看下Kongfz.json

 

再看下

 

灰常完美,一大波美图正等着你去细品。

做下总结,一个scrapy项目通常需要编写了五个文件,按顺序

items.py --> spider.py --> middlewares.py --> pipelines.py --> settings.py

 

孔夫子旧书网的图片都爬下来了,还怕爬取不到其他图片吗

有想法的person可以开始你的表演了

  • 10
    点赞
  • 92
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
您好!对于使用Scrapy爬取图片保存的问题,您可以按照以下步骤进行操作: 1. 首先,确保您已经安装了Scrapy库。如果没有安装,可以通过以下命令进行安装: ``` pip install scrapy ``` 2. 创建一个新的Scrapy项目。在命令行中使用以下命令: ``` scrapy startproject project_name ``` 这将在当前目录下创建一个名为 "project_name" 的新项目文件夹。 3. 进入项目文件夹,并创建一个新的Spider。在命令行中使用以下命令: ``` cd project_name scrapy genspider spider_name example.com ``` 这将在项目中创建一个名为 "spider_name" 的新Spider,用于定义爬取网页的规则。 4. 打开生成的Spider代码文件(位于 "project_name/spiders/spider_name.py"),并添加以下代码: ```python import scrapy class MySpider(scrapy.Spider): name = 'spider_name' start_urls = ['http://www.example.com'] # 要爬取的起始URL def parse(self, response): # 在这里编写解析响应数据的代码 # 提取图片URL并发送请求进行下载 for img_url in response.css('img::attr(src)').getall(): yield scrapy.Request(url=response.urljoin(img_url), callback=self.save_image) def save_image(self, response): # 获取图片保存路径 image_path = 'path/to/save/image.jpg' # 根据需求自定义保存路径和文件名 # 保存图片 with open(image_path, 'wb') as f: f.write(response.body) ``` 在上述代码中,我们定义了一个Spider类,包含了起始URL和解析响应数据的方法。在parse方法中,我们使用CSS选择器提取图片的URL,并使用scrapy.Request发送请求进行下载。下载后的图片会通过save_image方法保存到本地。 5. 运行爬虫。在命令行中使用以下命令: ``` scrapy crawl spider_name ``` 这将启动爬虫并开始爬取网页上的图片。下载的图片将保存在您指定的路径下。 请注意,上述代码只是一个简单示例,您可能需要根据具体的网页结构和需求进行相应的修改。另外,确保您遵守网站的爬取规则并尊重版权。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值