V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
pc10201
V2EX  ›  Python

scrapy 为不同网站设置不同的代理

  •  
  •   pc10201 · 2014-09-01 14:36:12 +08:00 · 4916 次点击
    这是一个创建于 3547 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在公司项目中,有一些爬虫中需要用的国内代理,有一些需要用到国外代理,有一些不用代理

    我测试了三个方案

    方案一:
    在settings.py中开启代理,然后在spider中重写DOWNLOADER_MIDDLEWARES,但重写无法生效

    方案二:
    让scrapy切换到不同的settings.py文件,这个手动切换是有效果的,但是我研究了半天不知道如果让程序自动切换,最后放弃

    方案三:
    在middlewares.py中直接写,通过request.url来判断并启用相应的代理

    class ProxyMiddleware(object):
    def process_request(self, request, spider):
    url=request.url
    if 'baidu.com' in url:
    request.meta['proxy'] = '这里设置国内http代理'
    elif 'facebook.com' in url:
    request.meta['proxy']='这里设置国外http代理'
    else:
    pass
    这个方案是可行的

    大家有没有更好的解决办法?
    2 条回复    2014-09-17 17:27:15 +08:00
    qsl0913
        1
    qsl0913  
       2014-09-01 14:55:26 +08:00
    推荐方案一的做法,debug一下,看看middleware执行了没有,为什么不生效。
    这里提供一段做多proxy随机的middleware,修改为判断request.url 即可做到不同domain采用不同的proxy。

    settings.py


    `
    DOWNLOADER_MIDDLEWARES = {

    'dp.spiders.downloadermiddleware.ProxyMiddleware' : 400 ,

    }


    downloadermiddleware.py


    `
    class ProxyMiddleware(object):

    def process_request(self, request, spider):
    proxy = random.choice(self.proxy_list)
    if proxy:
    request.meta['proxy'] = proxy
    log.msg('Current proxy: '+proxy, level='INFO')

    proxy_list = settings.get('PROXY_LIST')
    `
    forever139
        2
    forever139  
       2014-09-17 17:27:15 +08:00
    其实作者有提供的,
    class SelectiveProxyMiddleware(object):
    """A middleware to enable http proxy to selected spiders only.

    Settings:
    HTTP_PROXY -- proxy uri. e.g.: http://user:[email protected]:port
    PROXY_SPIDERS -- all requests from these spiders will be routed
    through the proxy
    """

    def __init__(self, settings):
    self.proxy = self.parse_proxy(settings.get('HTTP_PROXY'), 'http')
    self.proxy_spiders = set(settings.getlist('PROXY_SPIDERS', []))

    @classmethod
    def from_crawler(cls, crawler):
    return cls(crawler.settings)

    def parse_proxy(self, url, orig_type):
    proxy_type, user, password, hostport = _parse_proxy(url)
    proxy_url = urlunparse((proxy_type or orig_type, hostport, '', '', '', ''))

    if user and password:
    user_pass = '%s:%s' % (unquote(user), unquote(password))
    creds = base64.b64encode(user_pass).strip()
    else:
    creds = None

    return creds, proxy_url

    def process_request(self, request, spider):
    if spider.name in self.proxy_spiders:
    creds, proxy = self.proxy
    request.meta['proxy'] = proxy
    if creds:
    request.headers['Proxy-Authorization'] = 'Basic ' + creds




    然后再在你的settings.py里配置:
    HTTP_PROXY='your_proxy'
    PROXY_SPIDERS=[your_spider_names]



    不过整体和你的思路一样
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   872 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 21:17 · PVG 05:17 · LAX 14:17 · JFK 17:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.