0


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

目录


中间件

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

scrapy startproject mid
scrapy genspider baidu baidu.com

setting.py内

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即可

defprocess_request(self, request, spider):
        UA = choice(USER_AGENT_LIST)
        request.headers['User-Agent']= UA
        returnNone

开启setting内的

DOWNLOADER_MIDDLEWARES ={"douban.middlewares.DoubanDownloaderMiddleware":543,}

代理处理

setting内

DOWNLOADER_MIDDLEWARES ={"douban.middlewares.DoubanDownloaderMiddleware":543,"douban.middlewares.ProxyDownloaderMiddleware":545,#加}

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

middlewares.py内

from douban.settings import PROXY_IP_LIST
from random import choice #随机......classProxyDOwnloaderMiddleware:defprocess_request(self,request,spider)
        ip = choice(ProxyDOwnloaderMiddleware)
        request.meta['proxy']="https://"+ip
        returnNone#放行

selenium+scrapy

selenium作为下载器

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

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

DOWNLOADER_MIDDLEWARES ={"zhipin.middlewares.ZhipinDownloaderMiddleware":99,}

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

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

新建request.py

from scrapy import Request

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

爬虫内

from typing import Iterable
import scrapy

from zhipin.request import SeleniumRequest

classZpSpider(scrapy.Spider):
    name ="zp"
    allowed_domains =["zhipin.com"]
    start_urls =["https://zhipin.com"]defstart_requests(self):yield SeleniumRequest(
            url=self.start_urls[0],
            callback=self.parse
        )defparse(self, response):pass

middleware

from zhipin.request import SeleniumRequest

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

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

isinstance() 与 type() 区别:

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

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

不能以原来的思路写selenium ,因为只有3个返回值–None、 Request、 Response、

封装一个响应对象

在middlewares.py 导入一个类

from scrapy.http.response.html import HtmlResponse

......defprocess_request(self, request, spider):ifisinstance(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")#来源于父类returnNone
标签: 爬虫 学习 scrapy

本文转载自: https://blog.csdn.net/SHI_56/article/details/136688447
版权归原作者 name_S56 所有, 如有侵权,请联系我们删除。

“爬虫学习 Scrapy中间件&代理&UA随机&selenium使用”的评论:

还没有评论