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

时间:2013-12-26 22:35:16

标签: python redirect proxy scrapy http-proxy

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

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

  1. 当Scrapy收到“重定向”到其请求时(例如DEBUG: Redirecting (302) to (GET http://.../you_got_blocked.aspx) from (GET http://.../page-544.htm)),它是否继续尝试访问page-544.htm,还是继续到page-545.htm并永远失去了第544页.htm?如果它“忘记”(或将其视为已访问),是否有办法告诉它继续重试该页面? (如果它自然地这样做,那么耶和华,很高兴知道......)

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

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

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

    作为参考,我确实为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 个答案:

答案 0 :(得分:8)

昨天我有代理和防范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')