Scrapy 设置 User-Agent 无效

问题

使用 Scrapy 的过程当中 ,我想要实现一个功能 :
每个请求使用随机的 User-Agent 。


错误方案

习惯性的随手 Google , 找了篇博客 , copy 了方案 , 发现设置的 User-Agent 无效。代码如下 :

class CustomerUserAgent(UserAgentMiddleware):
    def process_request(self, request, spider):
        ua = random.choice(self.user_agent_list)
        request.headers.setdefault('User-Agent', ua)

    user_agent_list = [
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
        "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
    ]

同时在 settings.py 中设置了 User-Agent 的优先级

DOWNLOADER_MIDDLEWARES = {
   'spider.middlewares.CustomerUserAgent': 543,
}

上述代码无法设置 User-Agent 。


问题分析

Scrapy 的中间件是有优先级的 , 数字越小 , 优先级越高 。
首先来看下默认的 UserAgentMiddleware 优先级 , 在 default_settings.py 当中 。


DOWNLOADER_MIDDLEWARES_BASE = {
    # Engine side
	---
    'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware': 400,
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': 500,
    ---
}

默认的优先级是 500 , 而我设置的是 543, 也就是说在执行过程当中, 默认的执行的顺序为 :
UserAgentMiddleware -> CustomerUserAgent

那就首先看 UserAgentMiddleware , 通过断点调试 , 我们发现 :

class UserAgentMiddleware(object):
    """This middleware allows spiders to override the user_agent"""

    def __init__(self, user_agent='Scrapy'):
        self.user_agent = user_agent

    @classmethod
    def from_crawler(cls, crawler):
        o = cls(crawler.settings['USER_AGENT'])
        crawler.signals.connect(o.spider_opened, signal=signals.spider_opened)
        return o

    def spider_opened(self, spider):
        self.user_agent = getattr(spider, 'user_agent', self.user_agent)

    def process_request(self, request, spider):
        if self.user_agent:
            request.headers.setdefault(b'User-Agent', self.user_agent)

在调用 process_request 过程中 ,调用了

 request.headers.setdefault(b'User-Agent', self.user_agent)

其中 self.self.user_agent 值为 ‘Scrapy/1.5.1 (+https://scrapy.org)’ (我当前Scrapy 版本为 1.5.1),之后调用了自定义的 CustomerUserAgent , 也就是 :

request.headers.setdefault('User-Agent', ua)

问题就在 request.headers.setdefault() 方法中 . setdefault 方法意味着 :
如果键不存在于字典中,将会添加键并将值设为默认值。如果存在,则不添加 。可参考 文档
因为系统的 UserAgentMiddleware 已经添加了 User-Agent ,所以我们这里添加失败 。


解决方案

第一种解决方案 : 在 CustomerUserAgent 使用以下方式设置请求头:

# 如果 key 存在, 直接覆盖
request.headers['User-Agent'] = ua   

第二种解决方案 : settings.py 设置 CustomerUserAgent 小于 500 , CustomerUserAgent 早于 UserAgentMiddleware 执行即可。

DOWNLOADER_MIDDLEWARES = {
   'spider.middlewares.CustomerUserAgent': 499,
}

debug

查看请求头是否设置成功

  1. 直接抓包查看当前的请求头 , 可以使用 Charles/Fiddler
  2. scrapy 中访问 , https://httpbin.org/get?show_env=1 , 然后打印 response.txt
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值