我有一个签到列表,其中包含大约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)
答案 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))
使用上面的代码......
希望能让你开始。
(注意:您可以使用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的过程是没有意义的