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
DuckJK
V2EX  ›  Python

关于爬虫切换代理

  •  1
     
  •   DuckJK · 2016-01-17 22:30:09 +08:00 · 2359 次点击
    这是一个创建于 3030 天前的主题,其中的信息可能已经有所发展或是发生改变。

    脑袋有点晕了,问题是这样的:
    ```
    def run(self):
    global out_queue
    while True:
    page = self.out_queue.get(True, 2)
    try:
    html = requests.get('http://xxx.com', proxies={q_proxy.get().split('=')[0]: q_proxy.get().split('=')[1]}, timeout=3)
    except requests.exceptions.ReadTimeout:
    html = requests.get('http://xxx.com', proxies={q_proxy.get().split('=')[0]: q_proxy.get().split('=')[1]}, timeout=3)
    self.fun()
    self.out_queue.task_done()

    在获取目标 url 的时候使用的是代理,但是会 raise ReadTimeout ,我现在的打算是在抛出这个异常之后继续切换代理,使用下一个代理,代理在队列里面。
    现在如何在抛出异常之后切换代理,在切换代理之后如果还抛出异常就继续切换代理?
    
    15 条回复    2016-01-20 08:17:45 +08:00
    Kisesy
        1
    Kisesy  
       2016-01-17 22:35:58 +08:00
    死循环啊,没异常之后就跳出
    just1
        2
    just1  
       2016-01-17 22:38:37 +08:00 via Android
    看代码你的代理在数组。用整数变量啊,,错误就 n+=1,
    just1
        3
    just1  
       2016-01-17 22:39:04 +08:00 via Android
    @just1 最好先检测代理可用
    DuckJK
        4
    DuckJK  
    OP
       2016-01-17 22:46:04 +08:00
    @Kisesy
    while True:
    try:
    html = requests.get('http://xxx.com', proxies={q_proxy.get().split('=')[0]: q_proxy.get().split('=')[1]}, timeout=3)
    break
    except except requests.exceptions.ReadTimeout:
    html = requests.get('http://xxx.com', proxies={q_proxy.get().split('=')[0]: q_proxy.get().split('=')[1]}, timeout=3)

    是这样子吧?整个代码套了好多层 while 和 try 。。。。谢谢。
    DuckJK
        5
    DuckJK  
    OP
       2016-01-17 22:48:41 +08:00
    @just1 中间用了多线程,这个代理还有另外的生产者在使用,所以偷懒就直接放到 Queue 里面了。
    Kisesy
        6
    Kisesy  
       2016-01-17 22:55:49 +08:00
    你这代码,出现异常之后写 continue 就行,就不要再写 requests.get 了
    Kisesy
        7
    Kisesy  
       2016-01-17 22:56:34 +08:00   ❤️ 1
    写 pass 也行
    DuckJK
        8
    DuckJK  
    OP
       2016-01-17 22:57:08 +08:00
    @Kisesy 啊,明白了,谢谢你。
    master13
        9
    master13  
       2016-01-18 09:22:00 +08:00
    啊!我有个问题!
    LZ 的 q_proxy 看起来像是个 iterator ,你这样调用不会有逻辑错误?

    `proxies={q_proxy.get().split('=')[0]: q_proxy.get().split('=')[1]}`

    看起来像是取了第 N 个元素等号前的东西和第 N+1 个元素等号后的东西……天啦噜!
    他们拼起来竟然可以用的呢!
    DuckJK
        10
    DuckJK  
    OP
       2016-01-18 10:38:22 +08:00
    @master13 谢谢你啊,刚刚开会的时候突然想起来这个, q_proxy 是一个队列,所以每次调用 get 之后的话,都会取出来一个值。刚刚想出来试试的。。,实在是偷懒偷大发了。。
    DuckJK
        11
    DuckJK  
    OP
       2016-01-18 10:40:19 +08:00
    @master13 Python 封装了好多东西啊,我艹啊。。我决定下个语言是 C 了。
    DuckJK
        12
    DuckJK  
    OP
       2016-01-18 10:45:02 +08:00
    @master13 而且我觉得上面的 exception 还少了,首先爬虫采集的目标网站会有反爬虫策略,这个我简单的切换了代理,在切换代理的情况下,没有考虑通过代理不可用的情况,感觉会抛出 timeout ,这个异常没有捕捉到。因为采集目标是肯定可以连接上的,所以窝决定不管抛出神码异常,都切换代理,然后设定一个次数,超过这个次数之后就退出程序。下一步就是继续看对方神码反爬虫策略了。
    1KEco
        13
    1KEco  
       2016-01-20 06:05:13 +08:00
    把设置代理单独拿出来作为一个函数, except 之后再调用一遍设置代理的函数就好了
    DuckJK
        14
    DuckJK  
    OP
       2016-01-20 08:13:40 +08:00
    @1KEco 改好了,没有写一个单独的函数,加了两行,现在可以顺利运行啦。
    DuckJK
        15
    DuckJK  
    OP
       2016-01-20 08:17:45 +08:00
    @1KEco 我觉得可以把代理写成模块,每次 import 下就好了,自带服务器。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1146 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 17:55 · PVG 01:55 · LAX 10:55 · JFK 13:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.