如何使用geven验证url

2024-04-18 11:41:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一百万个网址要验证。 有些是无法从我的国家访问,有些是无效的,我想验证所有的网址。 我使用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,输出为:

^{pr2}$

5秒后没有通知超时,我的代码怎么了?在

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

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

我的留言是rabbitmq。在

我只知道如果我有10个网址,我可以使用gevent,比如:

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

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

那么我该如何做一些异步的方式来验证我的url呢? 比如我总是把网址读回去,不加阻拦地生成greenlet。在

泰铢


Tags: 代码fromimport消息urltimeoutgeventurllib2
1条回答
网友
1楼 · 发布于 2024-04-18 11:41:23

您需要用with Timeout()包装IO/“waiting”代码。现在,您正在包装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()。只产卵一个绿色小鱼的行为几乎会立即发生,所以在这附近增加一个超时不会起任何作用。这就是为什么你没有看到暂停。您需要用Timeout()上下文包装urllib2.urlopen()调用。在

另外,如果你只是检查超时,这个工作很好。但是,您可能需要检查请求是否返回了HTTP200代码,在这种情况下,您应该检查urllib2.urlopen(url).getcode()。在

相关问题 更多 >