本文主要是介绍Scrapy中间件(代理、Cookie、请求头、UA),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Scrapy中间件(代理、Cookie、请求头、UA)
目录
- Scrapy中间件(代理、Cookie、请求头、UA)
- 爬虫中间件
- from_crawler
- process_spider_input
- process_spider_output
- process_spider_exception
- process_start_requests
- spider_opened
- 下载中间件
- 使用代理
- 携带Cookie
- 携带请求头
- 携带UserAgent
爬虫中间件
爬虫和引擎之间的中间件
位于middlewares.py
class CppSpiderMiddleware:# Not all methods need to be defined. If a method is not defined,# scrapy acts as if the spider middleware does not modify the# passed objects.@classmethoddef from_crawler(cls, crawler):# This method is used by Scrapy to create your spiders.s = cls()crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)return sdef process_spider_input(self, response, spider):# Called for each response that goes through the spider# middleware and into the spider.# Should return None or raise an exception.return Nonedef process_spider_output(self, response, result, spider):# Called with the results returned from the Spider, after# it has processed the response.# Must return an iterable of Request, or item objects.for i in result:yield idef process_spider_exception(self, response, exception, spider):# Called when a spider or process_spider_input() method# (from other spider middleware) raises an exception.# Should return either None or an iterable of Request or item objects.passdef process_start_requests(self, start_requests, spider):# Called with the start requests of the spider, and works# similarly to the process_spider_output() method, except# that it doesn’t have a response associated.# Must return only requests (not items).for r in start_requests:yield rdef spider_opened(self, spider):spider.logger.info("Spider opened: %s" % spider.name)
from_crawler
from_crawler
会在创建爬虫实例时被调用,用于初始化中间件实例
class CppSpiderMiddleware:@classmethod
def from_crawler(cls, crawler):# 该方法是Scrapy用于创建爬虫实例的方法。# 首先创建了一个中间件实例 `s`s = cls()# 然后通过 `crawler.signals.connect` 方法连接了 `spider_opened` 信号和对应的处理方法。crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)return s
process_spider_input
response响应返回spider时经过的中间件,可以对响应进行预处理或检查
def process_spider_input(self, response, spider):# 当响应从爬虫中间件进入爬虫时,调用该方法进行处理。# response: 是响应对象# spider: 是当前爬虫实例# 应该返回 `None` 或引发异常return None
process_spider_output
当spider处理完响应后被调用,主要用于对结果的二次处理(request、item)
必须返回一个可迭代的Request对象或item对象
def process_spider_output(self, response, result, spider):# 当爬虫处理完响应后,调用该方法对处理结果进行处理。# response 是爬虫处理后的响应对象# result 是爬虫的处理结果# spider 是当前爬虫实例# 必须返回一个可迭代的Request对象或item对象。for i in result:yield i
process_spider_exception
该方法一般在爬虫或者process_spider_input
抛出异常时执行,一般用于对异常结果进行处理
def process_spider_exception(self, response, exception, spider):# 当爬虫中抛出异常时,调用该方法进行处理。# response 是发生异常的响应对象# exception 是抛出的异常对象# spider 是当前爬虫实例。# 应返回None或者一个可迭代的Request对象或item对象。pass
process_start_requests
在爬虫启动时被调用,用于对初始化请求进行处理
该方法必须返回可迭代的Request对象,不能是item对象
def process_start_requests(self, start_requests, spider):# 在爬虫启动时,对初始请求进行处理。# start_requests 是初始请求的列表# spider 是当前爬虫实例# Must return only requests (not items).for r in start_requests:yield r
spider_opened
该方法在爬虫被打开时调用,一般用于记录日志
def spider_opened(self, spider):spider.logger.info("Spider opened: %s" % spider.name)
在这行代码中,使用了Python的字符串格式化来构造日志信息,其中%s
会被替换为spider.name
的值,从而输出Spider opened: [spider_name]
的日志信息
下载中间件
引擎和下载器之间的中间件
与爬虫中间件类似
class CppDownloaderMiddleware:# 不是所有的方法都需要定义。如果某个方法没有被定义,# Scrapy会认为这个下载中间件不会修改传递的对象.@classmethoddef from_crawler(cls, crawler):# Scrapy使用该方法创建您的爬虫s = cls()# 通过signals连接spider_opened信号和spider_opened方法crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)return s# 拦截处理所有的请求对象# 参数:request就是拦截到的请求对象,spider爬虫文件中爬虫类实例化的对象# spider参数的作用可以实现爬虫类和中间类的数据交互def process_request(self, request, spider):# 返回None:继续处理本次请求,执行下一个中间件的process_request方法# 返回一个Response对象:执行当前中间件的process_response方法,重新回到引擎,被调度# 返回一个Request对象:直接返回给引擎,被调度。进入调度器等待下次被调用# 抛出IgnoreRequest异常:调用已安装的下载中间件的process_exception方法return None# 拦截处理所有的响应对象# 参数:response就是拦截到的响应对象,request就是被拦截到响应对象对应的唯一的一个请求对象def process_response(self, request, response, spider):# - 返回一个Response对象:继续执行,进入引擎,被调度到爬虫进行解析# - 返回一个Request对象:进入引擎,返回到调度器被重新调用# - 或者抛出IgnoreRequest异常:抛出异常return response# 拦截和处理发生异常的请求对象# 参数:reqeust就是拦截到的发生异常的请求对象# 方法存在的意义:将发生异常的请求拦截到,然后对其进行修正def process_exception(self, request, exception, spider):# 当下载处理程序或process_request()方法(来自其他下载中间件)引发异常时调用。# 必须返回以下之一:# - 返回None:继续处理该异常# - 返回一个Response对象:停止process_exception()链# - 返回一个Request对象:停止process_exception()链pass# 记录下载日志def spider_opened(self, spider):spider.logger.info("Spider opened: %s" % spider.name)
使用代理
在下载中间件中的process_request使用
def get_proxy(self):import requestsres = requests.get('http://127.0.0.1:5010/get/').json()if res.get('https'):return 'https://' + res.get('proxy')else:return 'http://' + res.get('proxy')def process_request(self, request, spider):request.meta['proxy'] = self.get_proxy()return None
如有第三方代理池需要自己定义
如果代理不能用,会触发process_exception,因此需要再里面补充
def process_exception(self, request, exception, spider):# 第二步:代理可能不能用,会触发process_exception,在里面写def process_exception(self, request, exception, spider):print('-----', request.url) # 这个地址没有爬return request
携带Cookie
def process_request(self, request, spider):# 添加cookierequest.cookies['cookies'] = 'cookies'print(request.url+':请求对象拦截成功!')return None
携带请求头
def process_request(self, request, spider):request.headers['referer'] = 'http://www.lagou.com'return None
携带UserAgent
用fake_useragent模块生成随机的UA
# fake_useragent模块
from fake_useragent import UserAgent# 动态生成User-agent使用
def process_request(self, request, spider):request.headers['User-Agent']=str(UserAgent().random)print(request.url+':请求对象拦截成功!')return None
这篇关于Scrapy中间件(代理、Cookie、请求头、UA)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!