0


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

目录


中间件

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

scrapy startproject mid
scrapy genspider baidu baidu.com

setting.py内

  1. ROBOTSTXT_OBEY =False
  2. LOG_LEVEL ="WARNING"

运行

scrapy crawl baidu

middlewares.py 中间件
在这里插入图片描述

先看下载器中间件

  1. # Not all methods need to be defined. If a method is not defined,
  2. # scrapy acts as if the downloader middleware does not modify the
  3. # 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 内有

  1. USER_AGENT =

动态UA

可以使用useragentsring.com设置一个USER_AGENT_LIST
middlewares只留process_request即可

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

开启setting内的

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

代理处理

setting内

  1. DOWNLOADER_MIDDLEWARES ={"douban.middlewares.DoubanDownloaderMiddleware":543,"douban.middlewares.ProxyDownloaderMiddleware":545,#加}
  2. PROXY_IP_LIST ={"IP:端口","IP:端口"}

middlewares.py内

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

selenium+scrapy

selenium作为下载器

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

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

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

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

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

新建request.py

  1. from scrapy import Request
  2. classSeleniumRequest(Request):#继承Request ,导致功能与scrapy一致pass

爬虫内

  1. from typing import Iterable
  2. import scrapy
  3. from zhipin.request import SeleniumRequest
  4. classZpSpider(scrapy.Spider):
  5. name ="zp"
  6. allowed_domains =["zhipin.com"]
  7. start_urls =["https://zhipin.com"]defstart_requests(self):yield SeleniumRequest(
  8. url=self.start_urls[0],
  9. callback=self.parse
  10. )defparse(self, response):pass

middleware

  1. from zhipin.request import SeleniumRequest
  2. ......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 导入一个类

  1. from scrapy.http.response.html import HtmlResponse
  2. ......defprocess_request(self, request, spider):ifisinstance(request,SeleniumRequest):
  3. self.web.get(request.url)
  4. page_source = self.web.page_source
  5. return HtmlResponse(
  6. url = request.url,
  7. status=200,
  8. headers=None,
  9. body=page_source,
  10. flags=None,
  11. request=request,
  12. Encoding ="utf-8")#来源于父类returnNone
标签: 爬虫 学习 scrapy

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

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

还没有评论