python爬虫十六:scrapy终章

1、scrapy下载中间件

中间件中有两个类一个用于爬虫,一个用于下载,爬虫几乎用spider就能实现,重要的是下载中间件
在这里插入图片描述

1.1下载中间件的含义

下载中间件是scrapy提供用于用于在爬虫过程中可修改Request和Response,用于扩展scrapy的功能

1.2下载中间件的内容

在这里插入图片描述主要用到request与response

1.2.1process_request(self, request, spider)

当每个request通过下载中间件时,该方法被调用,优先级越高的中间件,越先调用;该方法应该返回以下对象:None/Response对象/Request对象/抛出IgnoreRequest异常
None:scrapy会继续执行其他中间件相应的方法;
Response对象:scrapy不会再调用其他中间件的process_request方法,也不会去发起下载,而是直接返回该Response对象
Request对象:scrapy不会再调用其他中间件的process_request()方法,而是将其放置调度器待调度下载
如果这个方法抛出异常,则会调用process_exception方法

1.2.2process_response(self, request, response, spider)

当下载器完成http请求,传递Response经过下载中间件响应给引擎的时候调用,优先级越高的中间件,越晚被调用,与process_request()相反;该方法返回以下对象:Response对象/Request对象/抛出IgnoreRequest异常。
返回Response对象:scrapy会继续调用其他中间件的process_response方法;
返回Request对象:停止中间器调用,将其放置到调度器待调度下载;
抛出IgnoreRequest异常:Request.errback会被调用来处理函数,如果没有处理,它将会被忽略且不会写进日志。

2、设置随机请求头

请求头大全网址:所有的请求头点击查看
测试请求头网址:点击查看自己的请求头
测试请求头网址不仅可以测试ua还可以测试ip

2.1为什么要设置ua

在这里插入图片描述

2.1.1设置ua方式一

直接在setting当中设置
在这里插入图片描述

2.1.2通过下载中间件

自定义中间件,查看它当中内容
在这里插入图片描述

设置随机ua

在setting中定义一个ua列表,在下载中间件中通过random模块随机设置一个ua添加到request中,这样就完成了随机ua的添加

class RandomUseragent(object):

    def process_request(self, request, spider):
        ualist = spider.settings.get('USER_AGENTS')
        # print(ualist)
        user_agent = random.choice(ualist)
        # print(user_agent)
        request.headers['user-agent'] = user_agent

在这里插入图片描述

3、爬取汽车之家

3.1下载图片案例 爬取汽车之家图片

3.1.1spider代码

import scrapy


class AodiSpider(scrapy.Spider):
    name = 'aodi'
    allowed_domains = ['car.autohome.com.cn']
    start_urls = ['https://car.autohome.com.cn/photolist/series/43102/5304105.html#pvareaid=3454450']
    def parse(self, response):
        ul = response.xpath('//ul[@id="imgList"]/li')
        item = {}
        for li in ul:
            src = li.xpath('./a/img/@src').extract_first()
            # print(item)
            url = 'https:'+ src
            item['url'] = url
            yield item

3.1.2pipeline代码

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
from urllib import request
import os


class PicPipeline:
    def process_item(self, item, spider):
        name = 'images/' + item['url'].split('__')[-1]
        # D:\studyPC\text3\pic\images
        # __file__:具体到文件的位置,包含文件名
        # os.path.dirname(__file__):返回当前文件的上级目录路径,相当于cd ..,不包含文件名
        file_path = os.path.join(os.path.dirname(os.path.dirname(__file__)),name)
        request.urlretrieve(item['url'],file_path)
        return item

4、选择使用scrapy内置的下载文件的方法

优点:
1:避免重新下载最近已经下载过的数据
2:可以方便的指定文件存储的路径
3:可以将下载的图片转换成通用的格式。如:png,jpg
4:可以方便的生成缩略图
5:可以方便的检测图片的宽和高,确保他们满足最小限制
6:异步下载,效率非常高

4.1下载文件的步骤Files Pipeline

①:定义好一个Item,然后在这个item中定义两个属性,分别为file_urls以及files。files_urls是用来存储需要下载的文件的url链接,需要给一个列表
②:当文件下载完成后,会把文件下载的相关信息存储到item的files属性中。如下载路径、下载的url和文件校验码等
③:在配置文件settings.py中配置FILES_STORE,这个配置用来设置文件下载路径
④:启动pipeline:在ITEM_PIPELINES中设置scrapy.piplines.files.FilesPipeline:1

4.2下载图片的步骤Images Pipeline

①:定义好一个Item,然后在这个item中定义两个属性,分别为image_urls以及images下载路径。image_urls是用来存储需要下载的文件的url链接,需要给一个列表
②:当文件下载完成后,会把文件下载的相关信息存储到item的images属性中。如下载路径、下载的url和图片校验码等
③:在配置文件settings.py中配置IMAGES_STORE,这个配置用来设置文件下载路径
④:启动pipeline:在ITEM_PIPELINES中设置scrapy.pipelines.images.ImagesPipeline:1

5、用内置方法爬取汽车图片

优点:快速爬取,代码量少,命名等全不用自己管就可以实现快速爬取图片
spider代码

import scrapy
from neizhi.items import NeizhiItem


class AdSpider(scrapy.Spider):
    name = 'ad'
    allowed_domains = ['car.autohome.com.cn']
    start_urls = ['https://car.autohome.com.cn/photolist/series/43102/5304105.html#pvareaid=3454450']

    def parse(self, response):
        item = NeizhiItem()
        ul = response.xpath('//ul[@id="imgList"]/li')
        for li in ul:
            src = li.xpath('./a/img/@src').extract_first()
            # print(item)
            url = ['https:' + src]
            item['image_urls'] = url
            yield item

setting中的代码,打开内置管道,设置保存路径

import os
IMAGES_STORE = os.path.join(os.path.dirname(os.path.dirname(__file__)),'images')
ITEM_PIPELINES = {
   'neizhi.pipelines.NeizhiPipeline': 300,
    'scrapy.pipelines.images.ImagesPipeline':1
}

6、爬取苏宁图书

6.1找到爬取目标

在这里插入图片描述

6.2分析页面结构

发现网页源代码中有所需要的数据直接请求就ok
在这里插入图片描述

6.3创建scrapy框架普通爬虫

scrapy startproject book
cd book
scrapy genspider snbook book.suning.com

6.4写爬虫逻辑,在pipeline中保存

import scrapy
from copy import deepcopy
# import re


class SnbookSpider(scrapy.Spider):
    name = 'snbook'
    allowed_domains = ['suning.com']
    start_urls = ['https://book.suning.com/']

    def parse(self, response):
        dl_list = response.xpath('//div[@class="menu-list"]/div/dl')
        # print(dl_list)
        item = {}
        for dl in dl_list:
            item['b_cate'] = dl.xpath('./dt/h3/a/text()').extract_first()
            dd_list = dl.xpath('./dd/a')
            for dd in dd_list:
                item['s_href'] = dd.xpath('./@href').extract_first()
                item['s_cate'] = dd.xpath('./text()').extract_first()
                # print(item)
                yield scrapy.Request(
                    url=item['s_href'],
                    callback=self.parse_book_list,
                    meta={'item': deepcopy(item)}
                )

    def parse_book_list(self, response):
        item = response.meta.get('item')
        li_list = response.xpath('//ul[@class="clearfix"]/li')
        for li in li_list:
            item['book_name'] = li.xpath('//div[@class="res-img"]/div/a/img/@alt').extract_first()
            item['book_image'] = 'https:' + li.xpath('//div[@class="res-img"]/div/a/img/@src2').extract_first()
            item['book_href'] = 'https:' + li.xpath('//div[@class="res-img"]/div/a/@href').extract_first()
            yield scrapy.Request(
                url=item['book_href'],
                callback=self.parse_book_detail,
                meta={'item': deepcopy(item)}
            )

    def parse_book_detail(self, response):
        item = response.meta.get('item')
        # ul = response.xpath('//ul[@class="bk-publish clearfix"]/li')
        # for ul in ul
        item['book_author'] = response.xpath('//ul[@class="bk-publish clearfix"]/li[1]/text()').extract_first()
        item['book_press'] = response.xpath('//ul[@class="bk-publish clearfix"]/li[2]/text()').extract_first()
        item['book_author'] = item['book_author'].replace('\n','').replace('\t','').replace('\t','').strip()
        item['book_press'] = item['book_press'].replace('\n','').replace('\t','').replace('\t','').strip()
        yield item

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值