【问题标题】:how to validate url using gevent如何使用 gevent 验证 url
【发布时间】:2013-03-18 12:10:46
【问题描述】:

我有一百万个 URL 需要验证。 其中一些无法从我的国家/地区访问,有些无效,我想验证所有网址。 我使用python来做到这一点,并使用gevent来加速速度,但我是gevent的新手,有些似乎不起作用。 我的代码如下:

import gevent
import gevent.monkey
import urllib2
from gevent.pool import Pool
from gevent import Timeout
gevent.monkey.patch_all()
p = Pool(10)

seconds = 10

#timeout = Timeout(seconds)
#timeout.start()
#timer = Timeout(3).start()

def down(url):
    urllib2.urlopen(url)


def wait():
    while True:
        gevent.sleep(0)
        print 'hi'
        with Timeout(5,False):
            p.spawn(down,'http://www.twitter.com')
        print '---------------------------------'
wait()

我的国家无法访问 Twitter,输出为:

hi
---------------------------------
hi
---------------------------------
hi

5 秒后它没有告诉超时,我的代码有什么问题?

我想知道如何在运行时向 gevent 添加新任务。

我想验证分发中的所有 url,所以我从数据库中读取 url 并将 url 发送到消息队列,许多接收者从消息中接收消息,然后验证 url。

我的消息是rabbitmq。

我只知道如果我有 10 个 url,我可以使用 gevent,例如:

for x in xrange(10)
    tasks.append(gevent.spawn(validate,url))
gevent.joinall(tasks)

但在我的情况下,我只是阅读了一条消息,然后生成了一个 greenlet,如果一个 url 无法访问,它将阻止该消息,直到 greenlet 完成。

那么我该如何做一些异步的方式来验证我的网址呢? 比如我总是读回 url 并在没有阻塞的情况下生成 greenlet。

谢谢

【问题讨论】:

    标签: python rabbitmq gevent


    【解决方案1】:

    您需要使用with Timeout() 包装您的 IO/“等待”代码。现在,您正在包装gevent.spawn()/pool.spawn() 调用,这是不对的。在这种情况下,您要超时的 IO 代码是 urllib2.urlopen(url)

    这种性质的代码通常看起来像这样:

    validated = []
    urls = ["http://a.com", "http://b.com"]
    
    def down(url):
        with Timeout(5, False):
            urllib2.urlopen(url)
            validated.append(url)
    
    pool = gevent.Pool(10)
    for url in urls:
        pool.spawn(down, url)
    pool.join() #you didn't call pool.join() in the original code because you have a wait loop already, which is okay
    print "Valid URLs are: %s" % ", ".join(validated)
    

    您可以保持无限的while True 循环,并在其中从您的数据库/队列中获取传入的 URL。这可能就是你想要的。我只是举例说明如何检查我想要验证的预设 URL 列表。

    在这种情况下,您的错误是您使用with Timeout() 包装了pool.spawn()。只产生一个greenlet 的行为几乎会立即发生,因此在其周围添加一个超时将无济于事。这就是为什么您没有看到超时。您需要使用 Timeout() 上下文包装 urllib2.urlopen() 调用。

    另外,如果您只是检查超时,这可以正常工作。您可能想检查请求是否返回了 HTTP 200 代码,在这种情况下,您应该检查 urllib2.urlopen(url).getcode()

    【讨论】:

      猜你喜欢
      • 2021-06-22
      • 1970-01-01
      • 2016-05-05
      • 1970-01-01
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      相关资源
      最近更新 更多