【问题标题】:Scrapy and proxiesScrapy 和代理
【发布时间】:2011-06-10 06:37:51
【问题描述】:

您如何在 python 网络抓取框架 Scrapy 中利用代理支持?

【问题讨论】:

  • 您的问题需要更具体...

标签: python scrapy


【解决方案1】:

这就是我的工作

方法一:

像这样创建一个下载中间件

class ProxiesDownloaderMiddleware(object):

    def process_request(self, request, spider):
        
        request.meta['proxy'] = 'user:pass@host:port'

并在 settings.py 中启用它

DOWNLOADER_MIDDLEWARES: {
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
    'my_scrapy_project_directory.middlewares.ProxiesDownloaderMiddleware': 600,
},

就是这样,现在代理将应用于每个请求

方法二:

只需在settings.py 中启用HttpProxyMiddleware,然后为每个请求执行此操作

yield Request(url=..., meta={'proxy': 'user:pass@host:port'})

【讨论】:

  • 在哪里可以找到myproject 的值?
  • @rom 你的 Scrapy 项目的根目录名
  • 对不起,你能举个例子吗?
  • @rom 你的scrapy项目所在文件夹的名字,就这么简单
【解决方案2】:

我建议您使用诸如scrapy-proxies 之类的中间件。您可以为所有请求轮换代理、过滤不良代理或使用单个代理。此外,使用中间件可以省去每次运行时设置代理的麻烦。

这直接来自 GitHub README。

  • 安装 scrapy-rotating-proxy 库

    pip install scrapy_proxies

  • 在您的 settings.py 中添加以下设置

# Retry many times since proxies often fail
RETRY_TIMES = 10
# Retry on most error codes since proxies fail for different reasons
RETRY_HTTP_CODES = [500, 503, 504, 400, 403, 404, 408]

DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.retry.RetryMiddleware': 90,
    'scrapy_proxies.RandomProxy': 100,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
}

# Proxy list containing entries like
# http://host1:port
# http://username:password@host2:port
# http://host3:port
# ...
PROXY_LIST = '/path/to/proxy/list.txt'

# Proxy mode
# 0 = Every requests have different proxy
# 1 = Take only one proxy from the list and assign it to every requests
# 2 = Put a custom proxy to use in the settings
PROXY_MODE = 0

# If proxy mode is 2 uncomment this sentence :
#CUSTOM_PROXY = "http://host1:port"

您可以在此处更改重试次数,设置单个或轮换代理

  • 然后将您的代理添加到这样的 list.txt 文件中
http://host1:port
http://username:password@host2:port
http://host3:port

在此之后,您对该项目的所有请求都将通过代理发送。代理随机轮换每个请求。不会影响并发。

注意:如果您不想使用代理。您可以简单地评论 scrapy_proxy 中间件行。

DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.retry.RetryMiddleware': 90,
#    'scrapy_proxies.RandomProxy': 100,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
}

爬行愉快!!!

【讨论】:

    【解决方案3】:

    单一代理

    1. 在您的settings.py 中启用HttpProxyMiddleware,如下所示:

      DOWNLOADER_MIDDLEWARES = {
          'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 1
      }
      
    2. 通过request.meta传递代理请求:

      request = Request(url="http://example.com")
      request.meta['proxy'] = "host:port"
      yield request
      

    如果您有地址池,您也可以随机选择代理地址。像这样:

    多个代理

    class MySpider(BaseSpider):
        name = "my_spider"
        def __init__(self, *args, **kwargs):
            super(MySpider, self).__init__(*args, **kwargs)
            self.proxy_pool = ['proxy_address1', 'proxy_address2', ..., 'proxy_addressN']
    
        def parse(self, response):
            ...parse code...
            if something:
                yield self.get_request(url)
    
        def get_request(self, url):
            req = Request(url=url)
            if self.proxy_pool:
                req.meta['proxy'] = random.choice(self.proxy_pool)
            return req
    

    【讨论】:

    • 文档说 HttpProxyMiddleware 在每个请求元属性中设置代理,因此启用 ProxyMiddleware 并手动设置它没有意义
    • 我应该复制这段代码。我看了一眼,然后自己编码,但代理功能不起作用。现在我看到代理值设置为request.headers 而不是request.meta。愚蠢的我(掌心)!我去看了HttpProxyMiddleware的代码,如果有人已经设置了request.meta['proxy']就跳过了,所以不需要在设置里列出github.com/scrapy/scrapy/blob/master/scrapy/…
    • 我不确定我是否理解两者之间的区别,BaseSpider 是您的原始蜘蛛,MySpider 还是 MySpider 是实际修改后的蜘蛛,BaseSpider 指的是scrapy.Spider ?
    【解决方案4】:

    1-创建一个名为“middlewares.py”的新文件并将其保存在您的scrapy项目中,并在其中添加以下代码。

    import base64
    class ProxyMiddleware(object):
        # overwrite process request
        def process_request(self, request, spider):
            # Set the location of the proxy
            request.meta['proxy'] = "http://YOUR_PROXY_IP:PORT"
    
            # Use the following lines if your proxy requires authentication
            proxy_user_pass = "USERNAME:PASSWORD"
            # setup basic authentication for the proxy
            encoded_user_pass = base64.encodestring(proxy_user_pass)
            request.headers['Proxy-Authorization'] = 'Basic ' + encoded_user_pass
    

    2 – 打开项目的配置文件 (./project_name/settings.py) 并添加以下代码

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

    现在,您的请求应该由该代理传递。很简单,不是吗?

    【讨论】:

    • 我实施了您的解决方案,看起来正确,但我不断收到 Twisted 错误:twisted.web._newclient.ResponseNeverReceived: [>] 任何建议???
    • 注意使用base64.b64encode 而不是base64.encodestring,因为后者会在编码的base64结果中添加换行符...!见stackoverflow.com/a/32243566/426790
    • 如何在 20 次请求后将代理更改为不被禁止?
    • scrapy.contrib 已弃用,应该只是scrapy
    • 你是怎么得到project_name的?
    【解决方案5】:

    来自Scrapy FAQ

    Scrapy 可以与 HTTP 代理一起使用吗?

    是的。通过 HTTP 代理下载器中间件提供对 HTTP 代理的支持(从 Scrapy 0.8 开始)。见HttpProxyMiddleware

    使用代理最简单的方法是设置环境变量http_proxy。如何做到这一点取决于你的 shell。

    C:\> 设置 http_proxy=http://proxy:port csh% setenv http_proxy http://proxy:port sh$ 导出 http_proxy=http://proxy:port

    如果你想使用 https 代理并访问 https 网络,设置环境变量http_proxy 你应该遵循以下,

    C:\>设置 https_proxy=https://proxy:port csh% setenv https_proxy https://proxy:port sh$ 导出 https_proxy=https://proxy:port

    【讨论】:

    • 谢谢...所以我需要在运行scrapy crawler之前设置这个var,不可能从爬虫代码中设置或更改它
    • 您甚至可以在每个请求的基础上设置代理:request.meta['proxy'] = 'your.proxy.address'
    • 如何验证代理?
    • @ephemient 我们如何判断scrapy 是否正在使用代理?
    • @ocean800 我使用scrapy 来抓取一个显示你当前IP 的网站,看看它是否正在使用代理。这样我就可以通过 chrome 加载页面并查看我的实际 IP 并将其与 scrapy 在同一页面上看到的内容进行比较。
    【解决方案6】:

    有人[1]写了一个不错的中间件:https://github.com/aivarsk/scrapy-proxies"Scrapy proxy middleware"

    【讨论】:

      【解决方案7】:

      由于我在 /etc/environment 中设置环境时遇到了麻烦,所以我在我的蜘蛛 (Python) 中添加了以下内容:

      os.environ["http_proxy"] = "http://localhost:12345"
      

      【讨论】:

      • 不妨加上os.environ["https_proxy"]。为我工作。
      【解决方案8】:

      在 Windows 中,我将之前的几个答案放在一起,并且效果很好。我只是做了:

      C:>  set http_proxy = http://username:password@proxy:port
      

      然后我启动了我的程序:

      C:/.../RightFolder> scrapy crawl dmoz
      

      其中“dmzo”是程序名称(我写它是因为它是您在互联网上的教程中找到的,如果您在这里,您可能已经从教程开始)。

      【讨论】:

        【解决方案9】:

        那就是:

        导出 http_proxy=http://user:password@proxy:port

        【讨论】:

        • 我用这个但我刚刚收到[<twisted.python.failure.Failure <class 'twisted.web._newclient.ParseError'>>]
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-28
        • 2013-10-27
        • 2021-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多