爬虫学习 Scrapy中间件&代理&UA随机&selenium使用

目录


中间件

控制台操作 (百度只起个名

scrapy startproject mid

scrapy genspider baidu baidu.com

setting.py内

python 复制代码
ROBOTSTXT_OBEY = False

LOG_LEVEL = "WARNING"

运行

scrapy crawl baidu

middlewares.py 中间件

先看下载器中间件

复制代码
# Not all methods need to be defined. If a method is not defined,
    # scrapy acts as if the downloader middleware does not modify the
    # passed objects.

重点在 process_request

在引擎将请求的信息交给下载器之前,自动的调用该方法

process_response...
process_exception 异常 (看名就知道了...)
spider_open 爬虫开始

setting.py内 DOWNLOADER_MIDDLEWARES

运行顺序


UA、代理处理---process_request

process_request 返回值有规定

  1. 如果返回的 None,不做拦截,继续向后面的中间件执行.(多个中间件,权重大越往后)
  2. 如果返回的是Request.后续的中间件将不再执行.将请求重新交给引擎.引擎重新扔给调度器
  3. 如果返回的是Response,后续的中间件将不再执行.将响应信息交给引擎,引擎将响应丢给spider.进行数据处理

一个请求return ;yield一群

弄2个中间件???e.g.权重544 545

UA随机

老样子:

scrapy startproject douban

cd...

scrapy genspider movie douban.com

改setting

ROBOTSTXT_OBEY = False
LOG_LEVEL = "WARNING"

scrapy crawl movie

豆瓣UA 失败

setting 内有
USER_AGENT =

动态UA

可以使用useragentsring.com设置一个USER_AGENT_LIST

middlewares只留process_request即可

python 复制代码
def process_request(self, request, spider):
        UA = choice(USER_AGENT_LIST)
        request.headers['User-Agent'] = UA
        return None

开启setting内的

python 复制代码
DOWNLOADER_MIDDLEWARES = {
   "douban.middlewares.DoubanDownloaderMiddleware": 543,
}

代理处理

setting内

python 复制代码
DOWNLOADER_MIDDLEWARES = {
   "douban.middlewares.DoubanDownloaderMiddleware": 543,
   "douban.middlewares.ProxyDownloaderMiddleware": 545, #加
}

PROXY_IP_LIST = {
    "IP:端口","IP:端口"
}

middlewares.py内

python 复制代码
from douban.settings import PROXY_IP_LIST
from random import choice #随机

......

class ProxyDOwnloaderMiddleware:
    def process_request(self,request,spider)
        ip = choice(ProxyDOwnloaderMiddleware)
        request.meta['proxy'] = "https://"+ip
        return None  #放行

selenium+scrapy

selenium作为下载器

由于想要替换掉原来的downloader,原中间件无意义

原最大中间价最大优先级100

python 复制代码
DOWNLOADER_MIDDLEWARES = {
   "zhipin.middlewares.ZhipinDownloaderMiddleware": 99,
}

如果有多个spider,替换掉的下载器可能占全局

想办法适配判断是否使用selenium 处理请求

新建request.py

python 复制代码
from scrapy import Request


class SeleniumRequest(Request): #继承Request ,导致功能与scrapy一致
    pass

爬虫内

python 复制代码
from typing import Iterable
import scrapy

from zhipin.request import SeleniumRequest


class ZpSpider(scrapy.Spider):
    name = "zp"
    allowed_domains = ["zhipin.com"]
    start_urls = ["https://zhipin.com"]


    def start_requests(self):
        yield SeleniumRequest(
            url=self.start_urls[0],
            callback=self.parse
        )
    def parse(self, response):
        pass

middleware

python 复制代码
from zhipin.request import SeleniumRequest

......

def process_request(self, request, spider):
        #所有请求都回到这里
        #需要进行判断。判断出是否需要用selenium来处理请求
        #开始selenium的操作,返回页面源代码组装的response
        #isinstance 判断xxx , 是不是 xxx类型
        if isinstance(request,SeleniumRequest):
            pass
        else:
            return None
        return None

isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。

isinstance() 与 type() 区别:

  • type() 不会认为子类是一种父类类型,不考虑继承关系。
  • isinstance() 会认为子类是一种父类类型,考虑继承关系。

如果要判断两个类型是否相同推荐使用 isinstance()。

不能以原来的思路写selenium because只有3个返回值--None Request Response

封装一个响应对象

在middlewares.py 导入一个类

python 复制代码
from scrapy.http.response.html import HtmlResponse

......

def process_request(self, request, spider):
        if isinstance(request,SeleniumRequest):
       		self.web.get(request.url)
        	page_source = self.web.page_source
        	return HtmlResponse(
                url = request.url,
                status=200,
                headers=None,
                body=page_source,
                flags=None,
                request=request,
                Encoding = "utf-8"
                ) #来源于父类
            return None
相关推荐
旖旎夜光8 小时前
C++(17)
c++·学习
专注于大数据技术栈9 小时前
java学习--StringBuilder
java·学习
qcwl6610 小时前
操作系统 真象还原 学习笔记#13
笔记·学习
车载测试工程师10 小时前
CAPL学习-CAN相关函数-概述
网络协议·学习·capl·canoe
roman_日积跬步-终至千里10 小时前
【人工智能导论】08-学习-如何让计算机理解序列数据——用RNN/LSTM建模时序依赖,用文本嵌入表示序列元素
人工智能·rnn·学习
m0_6896182810 小时前
30 分钟打印!多材料3D打印软机器人内置驱动 + 自主避障
笔记·学习·机器人
charlie11451419111 小时前
现代嵌入式C++教程:C++98——从C向C++的演化(2)
c语言·开发语言·c++·学习·嵌入式·教程·现代c++
Rousson11 小时前
硬件学习笔记--93 静电防护方案(电阻、磁珠、电感、TVS等)
笔记·单片机·学习
思成不止于此11 小时前
【MySQL 零基础入门】事务精讲(二):ACID 特性与并发问题
数据库·笔记·学习·mysql
happyhappy没有句号12 小时前
嵌入式单片机一套通关学习笔记
笔记·单片机·嵌入式硬件·学习