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

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

  • 当Scrapy收到对其请求的“重定向”(例如DEBUG: Redirecting (302) to (GET http://.../you_got_blocked.aspx) from (GET http://.../page-544.htm))时,它会继续尝试访问第544.htm页,还是继续到第545.htm页并永久丢失第544页。 htm?如果它“忘记”(或将其视为已访问),是否有办法告诉它继续重试该页面? (如果它自然地这样做,那么很好,并且很了解...)
  • 什么是最有效的解决方案?

  • (a)我目前正在做什么:通过http_proxy环境变量使用proxymesh旋转Proxy,该变量似乎经常旋转代理以至少相当定期地通过目标站点的重定向。 (缺点:开放代理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
    

    最佳答案

    昨天,我在代理和防御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')
    

    10-07 19:27
    查看更多