首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python中扩展url的最快方法是什么?

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

Stack Overflow用户
提问于 2016-04-28 14:35:39
回答 2查看 1.7K关注 0票数 2

我有一个签入列表,其中包含大约600000个签入,每个签入中都有一个url,我需要将它们扩展回原来的长签。我是这样做的

代码语言:javascript
复制
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的最有效方法是什么?

修改:一些Urls来自Bitly,而另一些则不是,我不知道它们来自何处。在这种情况下,我只想简单地使用urllib2模块。

关于您的信息,下面是checkin[5]的一个示例

代码语言:javascript
复制
I'm at The Diner (2453 18th Street NW, Columbia Rd., Washington) w/ 4 others. http...... (this is the short url)
EN

回答 2

Stack Overflow用户

发布于 2016-04-28 15:29:39

我想我将对我关于使用multiprocessing来加速这项任务的评论作进一步的阐述。

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

代码语言:javascript
复制
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)元组,或者在发生故障时返回(shorturl, None)

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

代码语言:javascript
复制
import multiprocessing

pool = multiprocessing.Pool(10)

然后请我们的池解析一个urls列表:

代码语言:javascript
复制
resolved_urls = []
for shorturl, longurl in pool.map(resolve_url, urls):
    resolved_urls.append((shorturl, longurl))

使用上面的代码..。

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

希望这足以让你开始工作。

(注意:您可以使用threading模块而不是multiprocessing编写类似的解决方案。通常我只是先抓取multiprocessing,但在这种情况下,这两种方法都可以工作,而线程处理甚至可能稍微高效一些。)

票数 1
EN

Stack Overflow用户

发布于 2016-04-28 15:21:07

在网络I/O情况下,线程是最合适的,但您可以先尝试以下操作。

代码语言:javascript
复制
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是毫无意义的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36917848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档