中間件
控制臺(tái)操作 (百度只起個(gè)名
scrapy startproject mid
scrapy genspider baidu baidu.com
setting.py內(nèi)
ROBOTSTXT_OBEY = False
LOG_LEVEL = "WARNING"
運(yùn)行
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.
重點(diǎn)在 process_request
在引擎將請(qǐng)求的信息交給下載器之前,自動(dòng)的調(diào)用該方法
process_response…
process_exception 異常 (看名就知道了…)
spider_open 爬蟲開始
setting.py內(nèi) DOWNLOADER_MIDDLEWARES
運(yùn)行順序
UA、代理處理—process_request
process_request 返回值有規(guī)定
- 如果返回的 None,不做攔截,繼續(xù)向后面的中間件執(zhí)行.(多個(gè)中間件,權(quán)重大越往后)
- 如果返回的是Request.后續(xù)的中間件將不再執(zhí)行.將請(qǐng)求重新交給引擎.引擎重新扔給調(diào)度器
- 如果返回的是Response,后續(xù)的中間件將不再執(zhí)行.將響應(yīng)信息交給引擎,引擎將響應(yīng)丟給spider.進(jìn)行數(shù)據(jù)處理
一個(gè)請(qǐng)求return ;yield一群
弄2個(gè)中間件???e.g.權(quán)重544 545
UA隨機(jī)
老樣子:
scrapy startproject douban
cd…
scrapy genspider movie douban.com
改settingROBOTSTXT_OBEY = False
LOG_LEVEL = “WARNING”scrapy crawl movie
豆瓣UA 失敗
setting 內(nèi)有USER_AGENT =
動(dòng)態(tài)UA
可以使用useragentsring.com設(shè)置一個(gè)USER_AGENT_LIST
middlewares只留process_request即可
def process_request(self, request, spider):
UA = choice(USER_AGENT_LIST)
request.headers['User-Agent'] = UA
return None
開啟setting內(nèi)的
DOWNLOADER_MIDDLEWARES = {
"douban.middlewares.DoubanDownloaderMiddleware": 543,
}
代理處理
setting內(nèi)
DOWNLOADER_MIDDLEWARES = {
"douban.middlewares.DoubanDownloaderMiddleware": 543,
"douban.middlewares.ProxyDownloaderMiddleware": 545, #加
}
PROXY_IP_LIST = {
"IP:端口","IP:端口"
}
middlewares.py內(nèi)
from douban.settings import PROXY_IP_LIST
from random import choice #隨機(jī)
......
class ProxyDOwnloaderMiddleware:
def process_request(self,request,spider)
ip = choice(ProxyDOwnloaderMiddleware)
request.meta['proxy'] = "https://"+ip
return None #放行
selenium+scrapy
selenium作為下載器
由于想要替換掉原來(lái)的downloader,原中間件無(wú)意義
原最大中間價(jià)最大優(yōu)先級(jí)100
DOWNLOADER_MIDDLEWARES = {
"zhipin.middlewares.ZhipinDownloaderMiddleware": 99,
}
如果有多個(gè)spider,替換掉的下載器可能占全局
想辦法適配判斷是否使用selenium 處理請(qǐng)求
新建request.py
from scrapy import Request
class SeleniumRequest(Request): #繼承Request ,導(dǎo)致功能與scrapy一致
pass
爬蟲內(nèi)
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
from zhipin.request import SeleniumRequest
......
def process_request(self, request, spider):
#所有請(qǐng)求都回到這里
#需要進(jìn)行判斷。判斷出是否需要用selenium來(lái)處理請(qǐng)求
#開始selenium的操作,返回頁(yè)面源代碼組裝的response
#isinstance 判斷xxx , 是不是 xxx類型
if isinstance(request,SeleniumRequest):
pass
else:
return None
return None
isinstance() 函數(shù)來(lái)判斷一個(gè)對(duì)象是否是一個(gè)已知的類型,類似 type()。
isinstance() 與 type() 區(qū)別:
- type() 不會(huì)認(rèn)為子類是一種父類類型,不考慮繼承關(guān)系。
- isinstance() 會(huì)認(rèn)為子類是一種父類類型,考慮繼承關(guān)系。
如果要判斷兩個(gè)類型是否相同推薦使用 isinstance()。
不能以原來(lái)的思路寫selenium ,因?yàn)橹挥?個(gè)返回值–None、 Request、 Response、
封裝一個(gè)響應(yīng)對(duì)象文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-842624.html
在middlewares.py 導(dǎo)入一個(gè)類文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-842624.html
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"
) #來(lái)源于父類
return None
到了這里,關(guān)于爬蟲學(xué)習(xí) Scrapy中間件&代理&UA隨機(jī)&selenium使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!