什么是在python中扩展url的最快方法

时间:2016-04-28 14:35:39

标签: python url expand

我有一个签到列表,其中包含大约600000个签到,并且每个签到都有一个URL,我需要将它们扩展回原来的长签。

我是这样做的
now = time.time()
files_without_url = 0
for i, checkin in enumerate(NYC_checkins):
    try:
        foursquare_url = urllib2.urlopen(re.search("(?P<url>https?://[^\s]+)", checkin[5]).group("url")).url
    except:
        files_without_url += 1

    if i%1000 == 0:
        print("from %d to %d: %2.5f seconds" %(i-1000, i, time.time()-now))
        now = time.time()

但这需要很长时间:从0到1000次登记,需要 3241秒!这是正常的吗?什么是Python扩展URL的最有效方法?

修改:有些网址来自Bitly,有些则不是,而且我不确定它们来自哪里。在这种情况下,我想简单地使用urllib2模块。

有关您的信息,以下是checkin[5]的示例:

I'm at The Diner (2453 18th Street NW, Columbia Rd., Washington) w/ 4 others. http...... (this is the short url)

2 个答案:

答案 0 :(得分:1)

我想我会扩展我对使用multiprocessing来加快这项任务的评论。

让我们从一个简单的函数开始,该函数将采用url并尽可能地解析它(重定向后直到获得200响应代码):

import requests

def resolve_url(url):
    try:
        r = requests.get(url)
    except requests.exceptions.RequestException:
        return (url, None)

    if r.status_code != 200:
        longurl = None
    else:
        longurl = r.url

    return (url, longurl)

这将返回(shorturl, longurl)元组,或者它将返回。{p> 如果发生故障,请返回(shorturl, None)

现在,我们创建了一个工人池:

import multiprocessing

pool = multiprocessing.Pool(10)

然后让我们的池解析网址列表:

resolved_urls = []
for shorturl, longurl in pool.map(resolve_url, urls):
    resolved_urls.append((shorturl, longurl))

使用上面的代码......

  • 拥有10名工作人员,我可以在900秒内解析500个网址。
  • 如果我将工作人员数量增加到100,我可以在30秒内解析500个网址。
  • 如果我将工作人员数量增加到200,我可以在25秒内解析500个网址。

希望能让你开始。

(注意:您可以使用threading模块而不是multiprocessing编写类似的解决方案。我通常首先抓住multiprocessing,但在这种情况下,要么可以使用,要么使用线程甚至可能会稍微提高效率。)

答案 1 :(得分:-1)

线程最适合网络I / O.但您可以先尝试以下方法。

pat = re.compile("(?P<url>https?://[^\s]+)") # always compile it
missing_urls = 0
bad_urls = 0
def check(checkin):
    match = pat.search(checkin[5])
    if not match:
        global missing_urls
        missing_urls += 1
    else:
        url = match.group("url")
        try:
            urllib2.urlopen(url) # don't lookup .url if you don't need it later
        except URLError: # or just Exception
            global bad_urls
            bad_urls += 1
for i, checkin in enumerate(NYC_checkins):
    check(checkin)
print(bad_urls, missing_urls)

如果你没有任何改进,现在我们有一个很好的check功能,创建一个线程池并提供它。加速是有保证的。使用网络I / O的过程是没有意义的