爬虫学习 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
相关推荐
行然梦实12 分钟前
学习日记_20241110_聚类方法(K-Means)
学习·kmeans·聚类
马船长17 分钟前
制作图片木马
学习
秀儿还能再秀29 分钟前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
WCF向光而行34 分钟前
Getting accurate time estimates from your tea(从您的团队获得准确的时间估计)
笔记·学习
wang09071 小时前
工作和学习遇到的技术问题
学习
Li_0304062 小时前
Java第十四天(实训学习整理资料(十三)Java网络编程)
java·网络·笔记·学习·计算机网络
心怀梦想的咸鱼2 小时前
ue5 蓝图学习(一)结构体的使用
学习·ue5
kali-Myon3 小时前
ctfshow-web入门-SSTI(web361-web368)上
前端·python·学习·安全·web安全·web
B站计算机毕业设计超人3 小时前
计算机毕业设计Python+大模型农产品价格预测 ARIMA自回归模型 农产品可视化 农产品爬虫 机器学习 深度学习 大数据毕业设计 Django Flask
大数据·爬虫·python·深度学习·机器学习·课程设计·数据可视化
龙中舞王3 小时前
Unity学习笔记(4):人物和基本组件
笔记·学习·unity