将 Scrapy 代理中间件设置为在每个请求上轮换

Posted

技术标签:

【中文标题】将 Scrapy 代理中间件设置为在每个请求上轮换【英文标题】:Setting Scrapy proxy middleware to rotate on each request 【发布时间】:2014-01-14 12:59:43 【问题描述】:

这个问题必然有两种形式,因为我不知道更好的解决方案。

我正在抓取的网站经常将我踢到重定向的“用户被阻止”页面,但频率(按请求/时间)似乎是随机的,而且他们似乎有一个黑名单阻止了我的许多“开放”代理列表'正在通过 Proxymesh 使用。所以……

    当 Scrapy 收到对其请求的“重定向”(例如 DEBUG: Redirecting (302) to (GET http://.../you_got_blocked.aspx) from (GET http://.../page-544.htm))时,它会继续尝试访问 page-544.htm,还是会继续访问 page-545.htm 并永远在 page-544.htm 上丢失?如果它“忘记”(或将其视为已访问),有没有办法告诉它继续重试该页面? (如果它自然而然地做到了,那就好,很高兴知道......)

    什么是最有效的解决方案?

(a) 我目前在做什么:通过 http_proxy 环境变量使用 proxymesh 旋转代理,这似乎经常旋转代理,至少可以相当定期地通过目标站点的重定向。 (缺点:开放代理的 ping 速度很慢,只有这么多,proxymesh 最终会开始向我收取超过 10 场演出的每场演出费用,我只需要它们在重定向时旋转,我不需要'不知道它们旋转的频率或触发器,以及以上内容:我不知道我被重定向的页面是否正在被 Scrapy 重新排队......)(如果 Proxymesh 在每个请求上旋转,那么我愿意支付合理的费用。)

(b) 使用中间件在每次重定向时重新选择一个新代理是否有意义(并且简单)?对于每一个请求呢?通过 TOR 或 Proxifier 之类的其他东西会更有意义吗?如果这相对简单,我将如何设置它?我在几个地方读过类似的东西,但大多数都过时了,链接断开或废弃的 Scrapy 命令。

作为参考,我目前确实为 Proxy Mesh 设置了中间件(是的,我使用的是 http_proxy 环境变量,但在不遇到麻烦时我喜欢冗余)。所以这就是我目前所拥有的,以防万一:

 class ProxyMiddleware(object):
  def process_request(self, request, spider):
    request.meta['proxy'] = "http://open.proxymesh.com:[port number]"

    proxy_user_pass = "username:password"
    encoded_user_pass = base64.encodestring(proxy_user_pass)
    request.headers['Proxy-Authorization'] = 'Basic ' + encoded_user_pass

【问题讨论】:

【参考方案1】:

昨天我在代理和防御 DDoS 方面有类似的任务。 (我已经解析了一个网站) 这个想法在random.choice。每个请求都有机会更改 IP。 Scrapy 使用 Tor 和 telnetlib3。您需要配置 ControlPort 密码。

from scrapy import log
from settings import USER_AGENT_LIST

import random
import telnetlib
import time


# 15% ip change
class RetryChangeProxyMiddleware(object):
    def process_request(self, request, spider):
        if random.choice(xrange(1,100)) <= 15:
            log.msg('Changing proxy')
            tn = telnetlib.Telnet('127.0.0.1', 9051)
            tn.read_until("Escape character is '^]'.", 2)
            tn.write('AUTHENTICATE "<PASSWORD HERE>"\r\n')
            tn.read_until("250 OK", 2)
            tn.write("signal NEWNYM\r\n")
            tn.read_until("250 OK", 2)
            tn.write("quit\r\n")
            tn.close()
            log.msg('>>>> Proxy changed. Sleep Time')
            time.sleep(10)



# 30% useragent change
class RandomUserAgentMiddleware(object):
    def process_request(self, request, spider):
        if random.choice(xrange(1,100)) <= 30:
            log.msg('Changing UserAgent')
            ua  = random.choice(USER_AGENT_LIST)
            if ua:
                request.headers.setdefault('User-Agent', ua)
            log.msg('>>>> UserAgent changed')

【讨论】:

以上是关于将 Scrapy 代理中间件设置为在每个请求上轮换的主要内容,如果未能解决你的问题,请参考以下文章

Scrapy框架设置UA池与代理池 -- 2019-08-08 17:20:36

Scrapy框架设置UA池与代理池 -- 2019-08-08 18:00:10

scrapy框架设置代理

UA池和代理池

UA池和代理池

14.UA池和代理池