scarpy中间件
# scrapy中间件
# 学习目标:
- 应用 scrapy中使用间件使用随机UA的方法
- 了解 scrapy中使用代理ip的的方法
# 1 scrapy中间件的分类和作用
# 1.1 scrapy中间件的分类
根据scrapy运行流程中所在位置不同分为:
- 下载中间件
- 爬虫中间件
# 1.2 scrapy中间的作用
- 主要功能是在爬虫运行过程中进行一些处理,如对非200响应的重试(重新构造Request对象yield给引擎)
- 也可以对header以及cookie进行更换和处理
- 其他根据业务需求实现响应的功能
但在scrapy默认的情况下 两种中间件都在middlewares.py一个文件中
爬虫中间件使用方法和下载中间件相同,常用下载中间件
# 2 下载中间件的使用方法:
接下来我们对腾讯招聘爬虫进行修改完善,通过下载中间件来学习如何使用中间件 编写一个Downloader Middlewares和我们编写一个pipeline一样,定义一个类,然后在setting中开启
Downloader Middlewares默认的方法:
process_request(self, request, spider):
- 当每个request通过下载中间件时,该方法被调用。
- 返回None值:继续请求
- 返回Response对象:不再请求,把response返回给引擎
- 返回Request对象:把request对象交给调度器进行后续的请求
process_response(self, request, response, spider):
- 当下载器完成http请求,传递响应给引擎的时候调用
- 返回Resposne:交给process_response来处理
- 返回Request对象:交给调取器继续请求
# 3. 定义实现随机User-Agent的下载中间件
# 3.1 在middlewares.py中完善代码
import random
from Tencent.settings import USER_AGENTS_LIST # 注意导入路径,请忽视pycharm的错误提示
class UserAgentMiddleware(object):
def process_request(self, request, spider):
user_agent = random.choice(USER_AGENTS_LIST)
request.headers['User-Agent'] = user_agent
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3.2 在爬虫文件tencent.py的每个解析函数中添加
class CheckUA:
def process_response(self,request,response,spider):
print(request.headers['User-Agent'])
1
2
3
2
3
# 3.3 在settings中设置开启自定义的下载中间件,设置方法同管道
DOWNLOADER_MIDDLEWARES = {
'Tencent.middlewares.UserAgentMiddleware': 543,
}
1
2
3
2
3
# 3.4 在settings中添加UA的列表
USER_AGENTS_LIST = [
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)", \
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)", \
"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)", \
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)", \
"Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6", \
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1", \
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0", \
"Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5" ]
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 3.5 运行爬虫观察现象
# 4 代理ip的使用
# 4.1 思路分析
- 代理添加的位置:request.meta中增加
proxy
字段 - 获取一个代理ip,赋值给
request.meta['proxy']
- 代理池中随机选择代理ip
- 代理ip的webapi发送请求获取一个代理ip
# 4.2 具体实现
免费代理ip:
class ProxyMiddleware(object):
def process_request(self,request,spider):
proxy = random.choice(proxies) # proxies可以在settings.py中,也可以来源于代理ip的webapi
# proxy = 'http://192.168.1.1:8118'
request.meta['proxy'] = proxy
return None # 可以不写return
1
2
3
4
5
6
2
3
4
5
6
收费代理ip:
# 人民币玩家
import base64
proxyServer = 'http://proxy.abuyun.com:9010' # 收费的代理ip服务器地址,这里是abuyun
# 代理隧道验证信息 这个是在那个网站上申请的
proxyUser = 用户名
proxyPass = 密码
proxyAuth = "Basic " + base64.b64encode(proxyUser + ":" + proxyPass)
class ProxyMiddleware(object):
def process_request(self, request, spider):
# 设置代理
request.meta["proxy"] = proxyServer
# 设置认证
request.headers["Proxy-Authorization"] = proxyAuth
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 4.3 检测代理ip是否可用
在使用了代理ip的情况下可以在下载中间件的process_response()方法中处理代理ip的使用情况,如果该代理ip不能使用可以替换其他代理ip
class ProxyMiddleware(object):
def process_response(self, request, response, spider):
if response.status != '200' and response.status != '302':
#此时对代理ip进行操作,比如删除
return request
1
2
3
4
5
2
3
4
5
# 总结
中间件的使用:
完善中间件代码:
process_request(self, request, spider):
* 当每个request通过下载中间件时,该方法被调用。 * 返回None值:继续请求 * 返回Response对象:不再请求,把response返回给引擎 * 返回Request对象:把request对象交给调度器进行后续的请求
process_response(self, request, response, spider):
* 当下载器完成http请求,传递响应给引擎的时候调用 * 返回Resposne:交给process\_response来处理 * 返回Request对象:交给调取器继续请求
需要在settings.py中开启中间件 DOWNLOADER_MIDDLEWARES = { 'myspider.middlewares.UserAgentMiddleware': 543, }
编辑 (opens new window)