for循环调用urllib.urlopen()。getcode()很慢

时间:2014-11-20 15:46:15

标签: python performance python-2.7 for-loop urllib

我有一个Python程序,它运行字符串的所有组合(保存在列表comb中)并检查属于它的网站是否存在。该程序有效,但运行速度非常慢。在尝试了一些事情之后,我认为问题是getcode方法,因为除了该行之外所有其他部分都能快速工作。如何让这个程序更快?

它占用的CPU少于1%,而我的互联网带宽却很少。我尝试一次运行3个程序实例,每个实例都运行得很快,就像我只运行其中一个实例一样。是否有可能在程序中复制它?

for p in comb: 
    if urllib.urlopen(url + p).getcode()!=404:
        print "Sucessful: " + str(p)
        break
    else:
        print "Failure:" + str(p)

2 个答案:

答案 0 :(得分:3)

多线程的替代方法是使用异步请求。您可以使用grequestsrequests库的变体与Gevent相结合)来执行此操作。使用Github page itself中的代码。

import grequests

urls = [
    'http://www.heroku.com',
    'http://python-tablib.org',
    'http://httpbin.org',
    'http://python-requests.org',
    'http://kennethreitz.com'
]

rs = (grequests.get(u) for u in urls)

for i in grequests.imap(rs):
    print i, i.url

我的结果是一个漂亮的7秒。

<Response [200]> http://docs.python-tablib.org/en/latest/
<Response [200]> https://www.heroku.com/
<Response [200]> http://httpbin.org/
<Response [200]> http://docs.python-requests.org/en/latest/
<Response [200]> http://www.kennethreitz.org/
[Finished in 7.0s]

我对多线程的看法。

import requests as rq
import threading

urls = ["...={}".format(x) for x in range(100)]

def get_status(url):
    if rq.get(url, verify=False).status_code != 404:
        print "Successful: {}\n".format(url)
    else:
        print "Failed: {}".format(url)

for url in urls:
    t = threading.Thread(None, get_status, url, (url,))
    t.start()

这可以在大约10秒钟内获得100个网站的状态。

答案 1 :(得分:0)

使用Thread可能是一种解决方案

from Threading import Thread

def checkresponse(p):
    if urllib.urlopen(p).getcode()!=404:
        print "Sucessful: " + str(p)
    else:
        print "Failure:" + str(p)

for p in comb: 
    t = Thread(target ="checkresponse", args=(p,))
    t.start()