Scrapy与分布式开发:scrapy下载中间件实现动态切换User-Agent

前言

请求头User-Agent是比较常规的反爬手段,不同站点对其检测机制各异,有的是检测是否是合规的浏览器User-Agent,有的是在这基础上检测使用次数与频率,更有甚者是跟ip和cookie绑定在一起检测,这就要求我们能够动态去切换User-Agent(随机or判定切换)。

关卡:实现动态切换User-Agent

scrapy设置User-Agent方式梳理

这里整理一下笔者已知的scrapy设置User-Agent的方式:

  1. setting配置文件中设置DEFAULT_REQUEST_HEADERS
    在这里插入图片描述
  2. 生成requests请求时设置请求头
    在这里插入图片描述
  3. setting配置文件中设置USER_AGENT
    我们在源码看一下USER_AGENT的默认值
    在这里插入图片描述
    scrapy是有自带的USER_AGENT中间件的,而USER_AGENT就是跟它一起配合生效的,这个中间件默认也是开启的。所以大家注意了,如果我们直接使用scrapy自带的USER_AGENT机制,是很容易被是被为爬虫的!!!
    在这里插入图片描述
  4. 自定义User-Agent下载中间件,这种方式其实跟方式3是一样的逻辑

User-Agent生效梳理

我们来调试一下方式1方式2方式3,看看三种方式同时设置时最终是哪个方式生效
如下图,按顺序分别为三种方式设置好User-Agent
在这里插入图片描述在这里插入图片描述
如下图,在发起请求生成request队列前,方式1设置成功
在这里插入图片描述
如下图,生成request队列后,经过下载中间件可以看到方式2覆盖了方式1
在这里插入图片描述
我们仔细看下中间件的代码,特别是process_request这个具体实现方法。
在此之前先了解一下setdefault这个方法:
setdefault是Python中字典的一个方法, 它用于在字典中查找指定键 如果键存在, 则返回对应的值; 如果键不存在,则在字典中添加该键,并将其值设置为指定的默认值
由于request.headersUser-Agent有值且是2,所以经过下载中间件后,它还是2
在这里插入图片描述
综上,我们可以得到结论:

  1. 方式1方式2方式3共存时,结果会取方式2
  2. 只存在方式1方式2时,结果会取方式2
  3. 只存在方式1方式3时,结果会取方式1
  4. 方式3要生效必须只有它这种方式

为何选择在下载中间件中实现

首先要说明一下,并非一定要在中间件中才能实现User-Agent动态切换,也可以在脚本开发中对每次生成的request请求时动态设置User-Agent(请求头),但这种方式在笔者看来是不符合python之美的,功能未解耦而不够灵活,每个脚本都要单独实现,既繁琐又提高学习成本。

自定义User-Agent下载中间件

既然选择自定义中间件,那我们就可以随便玩了
首先思考一下,根据需求整理出设计方案:

  1. 动态:随机生成User-Agent
  2. 切换:控制是否动态生成
  3. 全局:需要适配不同场景(固定、动态、切换)

通过上面的思考,在一个全局改动的位置要适配各式各样的脚本应用场景,就需要引入全局控制参数来实现点对点应用,下面是笔者的想法:
在request.meta中增加 auto_change_uachange_ua_ua三个参数来实现,
auto_change_ua是自动切换,每次request都会切换User-Agent
change_ua是一个切换,当前request会切换User-Agent
_ua是固定存储,不切换时一直使用它
同时准备User-Agent列表,用于随机生成,大致样式如下:

def get_random_ua(self):
    """Return a ua if possible"""
    return random.choice(self.ua_list)

def process_request(self, request, spider):
    meta = request.meta
    ua = None

    if meta.get('auto_change_ua') or meta.get('change_ua', None):
        ua = self.get_random_ua()
    elif meta.get('_ua', None):
        ua = meta['_ua']
    elif not request.headers.get('User-Agent', None):
        ua = self.get_random_ua()

    if ua:
        request.headers['User-Agent'] = ua

def process_response(self, request, response, spider):
    request.meta['_ua'] = request.headers['User-Agent']
    if 'change_ua' in request.meta:
        del request.meta['change_ua']
    if 'auto_change_ua' in request.meta:
        request.meta['change_ua'] = True
    return response

开发好后需要在settingDOWNLOADER_MIDDLEWARES配置才能生效,同时,记得把原生的UserAgentMiddleware设置为None,不然它还是会开启的。
在这里插入图片描述

结束

这个关卡的设计方案是笔者根据自己业务场景实现的,大家如果有同样的需求,需要结合自己的业务场景来思考、设计与实现。
好了,分享就到这了,有啥错误的地方请指正~

  • 28
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现随机切换User-Agent,你可以使用Python库中的fake_useragent模块和random模块。首先,你需要导入fake_useragent和random模块。然后,你可以使用fake_useragent来生成一个UserAgent对象,并使用random模块中的方法从该对象中选择一个随机的User-Agent。下面是一个示例代码: ```python import fake_useragent import random ua = fake_useragent.UserAgent() random_ua = getattr(ua, random.choice(list(fake_useragent.settings.SHORTCUTS.keys()))) print(random_ua) ``` 这段代码会打印出一个随机选择的User-Agent。 此外,你可以在爬虫中使用middleware来实现随机切换User-Agent。首先,在middleware.py文件中创建一个RandomUserAgentMiddleware类。该类的作用是在请求中随机设置User-Agent。下面是一个示例代码: ```python from fake_useragent import UserAgent class RandomUserAgentMiddleware(object): def __init__(self, crawler): super(RandomUserAgentMiddleware, self).__init__() self.ua = UserAgent() self.ua_type = crawler.settings.get("RANDOM_UA_TYPE", "random") @classmethod def from_crawler(cls, crawler): return cls(crawler) def process_request(self, request, spider): def get_ua(): return getattr(self.ua, self.ua_type) request.headers.setdefault('User-Agent', get_ua()) ``` 在这个示例代码中,RandomUserAgentMiddleware类继承自Scrapy的Middleware类,并重写了process_request方法来设置请求的User-Agent。在设置User-Agent时,它使用了之前生成的UserAgent对象,并根据设置的ua_type随机选择一个User-Agent进行设置。 为了让Scrapy使用这个middleware,你还需要在settings.py文件中配置相应的参数。你可以在settings.py文件中添加以下代码: ```python DOWNLOADER_MIDDLEWARES = { 'your_project_name.middlewares.RandomUserAgentMiddleware': 543, } RANDOM_UA_TYPE = "random" ``` 这段代码会告诉Scrapy使用RandomUserAgentMiddleware来处理请求,并设置RANDOM_UA_TYPE参数为"random",以随机选择User-Agent。 通过以上步骤,你就可以实现随机切换User-Agent了。每次请求时,middleware都会随机选择一个User-Agent并设置到请求中。这样能够增加爬虫的隐匿性,防止被网站封禁。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [随机切换user-agent](https://blog.csdn.net/weixin_30908941/article/details/97354994)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [scrapy随机更换User-Agent](https://blog.csdn.net/weixin_42260204/article/details/81087402)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九月镇灵将

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值