【问题标题】:Scrapy don't change a proxyScrapy 不会更改代理
【发布时间】:2016-02-23 13:16:57
【问题描述】:

在尝试使用 Scrapy 测试代理时,我遇到了一个问题。我想用 httpbin.org 检查代理,并制作爬虫:

class CheckerSpider(scrapy.Spider):
    name = "checker"
    start_urls = (
        'https://www.httpbin.org/ip'
    )
    connection = get_connection()

    def start_requests(self):

        with self.connection.cursor() as cursor:
            limit = int((datetime.now() - datetime(1970, 1, 1)).total_seconds()) - 3600
            q = """ SELECT *
                    FROM {}
                    WHERE active = 1 AND last_checked <= {} OR last_checked IS NULL;""".format(DB_TABLE, limit)
            cursor.execute(q)
            proxy_list = cursor.fetchall()

        for proxy in proxy_list[:15]:
            word = get_random_word()
            req = scrapy.Request(self.start_urls, self.check_proxy, dont_filter=True)
            req.meta['proxy'] = 'https://{}:8080'.format(proxy['ip'])
            req.meta['item'] = proxy
            user_pass = base64.encodestring('{}:{}'.format(PROXY_USER, PROXY_PASSWORD))
            req.headers['Proxy-Authorization'] = 'Basic {}'.format(user_pass)
            req.headers['User-Agent'] = get_user_agent()
            yield req

    def check_proxy(self, response):
        print response.request.meta['proxy']
        print response.meta['item']['ip']
        print response.body

但是当我测试它时,我发现 Scrapy 仅使用 5 个代理连接到 url,然后没有更改它。示例输出(只是弄乱了 IP):

2016-02-23 14:54:36 [scrapy] DEBUG: Crawled (200) <GET https://www.httpbin.org/ip> (referer: None)
https://192.168.100.130:8080
192.168.100.130
{
  "origin": "192.168.100.130"
}

2016-02-23 14:54:36 [scrapy] DEBUG: Crawled (200) <GET https://www.httpbin.org/ip> (referer: None)
https://192.168.100.131:8080
192.168.100.131
{
  "origin": "192.168.100.131"
}
2016-02-23 14:54:37 [scrapy] DEBUG: Crawled (200) <GET https://www.httpbin.org/ip> (referer: None)
https://192.168.100.132:8080
192.168.100.132
{
  "origin": "192.168.100.132"
}

# Here Scrapy used wrong proxy to connect to site.
2016-02-23 14:54:37 [scrapy] DEBUG: Crawled (200) <GET https://www.httpbin.org/ip> (referer: None)
https://192.168.100.134:8080
192.168.100.134
{
  "origin": "192.168.100.130"
}

可能是我做错了什么?任何的想法?谢谢。

更新: 实际上,现在我正在使用中间件来为请求添加代理。我把它按顺序放在中间件中:

DOWNLOADER_MIDDLEWARES = {
    'checker.middlewares.ProxyCheckMiddleware': 100,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
}

但我有同样的结果。这是我添加代理的自定义中间件:

class ProxyCheckMiddleware(object):

    def process_request(self, request, spider):
        if 'proxy' not in request.meta:
            request.meta['proxy'] = 'https://{}:8080'.format(request.meta['item']['ip'])
            request.meta['handle_httpstatus_list'] = [302, 503]
            user_pass = base64.encodestring('{}:{}'.format(PROXY_USER, PROXY_PASSWORD))
            request.headers['Proxy-Authorization'] = 'Basic {}'.format(user_pass)

UPD。 到目前为止,这似乎是 Scrapy 中的一个错误。看这里的对话:https://github.com/scrapy/scrapy/issues/1807

【问题讨论】:

    标签: python proxy scrapy


    【解决方案1】:

    在故事的最后,这是 Scrapy 中的一个错误,该错误已在 1.1.0 版中修复(请参阅conversation)。非常感谢 redapplerverbitsky 的帮助!

    【讨论】:

      【解决方案2】:

      你试过this吗?

      按照设置说明,拥有一个包含指定格式的代理列表的文本文件,并通过它运行请求。它将使用的代理随机化,并丢弃在设定的尝试次数后失败的代理。可以强烈推荐它,目前将它与 hidemyass.com 的代理列表一起使用

      【讨论】:

      • 这不适合我的情况。我知道如何编写中间件,但这是 Scrapy 中的一个错误(请参阅问题末尾的 github 链接)。已在 Scrapy 1.1.0 中修复
      【解决方案3】:

      在您的 middlewares.py 文件中试用此 ProxyMiddleware。

      class ProxyMiddleware(object):
      
          def process_request(self, request, spider):
              request.meta['proxy'] == 'https://{}:8080'.format(request.meta.get('item').get('ip'))
      
              # If the proxy needs auth (you will also need to import base64 
              # proxy_auth = "username:password"
              # encoded_auth = base64.encodestring(proxy_auth)
      
              # request.headers['Proxy-Authorization'] = 'Basic ' + encoded_auth
              return request
      

      在您的settings.py 文件中:

      DOWNLOADER_MIDDLEWARES = {
          'checker.middlewares.ProxyMiddleware': 100,
          'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 110
      }
      

      【讨论】:

      • 您的示例将产生不定式循环,导致如果中间件返回请求,Scrapy 重新排队并再次调用所有中间件。其实这个问题已经解决了,看问题最后的github链接。在 1.1.0 中,此错误已修复。
      • @drjackild 它不会创建无限循环。你必须适当地订购你的中间件,它不会像你说的那样做。这是一个简单的解决方法。我只是提供一些建议。
      猜你喜欢
      • 2018-02-12
      • 1970-01-01
      • 2012-06-28
      • 1970-01-01
      • 2020-09-26
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      相关资源
      最近更新 更多