我想废弃一个网站。有大约8000件商品要废弃。我有问题,如果要求1件物品需要1秒钟,那么这些物品需要大约8000秒,这意味着它需要大约134分钟和2.5小时。任何人都可以帮助解决如何完成它并同时执行多个请求。我正在使用python urllib2来请求内容。
答案 0 :(得分:4)
使用更好的HTTP客户端。 Urllib2使用Connection: close
发出请求,因此必须协商新的TCP连接。使用requests
,您可以重用该TCP连接。
s = requests.Session()
r = s.get("http://example.org")
并行提出请求。由于这是I / O绑定,因此可以使用GIL并且可以使用线程。您可以运行一些简单的线程来下载一批URL,然后等待所有这些URL完成。但也许像"平行地图"会更好地适应这种情况 - 我用简单的例子找到了这个答案:
https://stackoverflow.com/a/3332884/196206
如果您在线程之间共享任何内容,请确保它是线程安全的 - 请求会话对象似乎是线程安全的:https://stackoverflow.com/a/20457621/196206
更新 - 一个小例子:
#!/usr/bin/env python
import lxml.html
import requests
import multiprocessing.dummy
import threading
first_url = "http://api.stackexchange.com/2.2/questions?pagesize=10&order=desc&sort=activity&site=stackoverflow"
rs = requests.session()
r = rs.get(first_url)
links = [item["link"] for item in r.json()["items"]]
lock = threading.Lock()
def f(data):
n, link = data
r = rs.get(link)
doc = lxml.html.document_fromstring(r.content)
names = [el.text for el in doc.xpath("//div[@class='user-details']/a")]
with lock:
print("%s. %s" % (n+1, link))
print(", ".join(names))
print("---")
# you can also return value, they will be returned
# from pool.map() in order corresponding to the links
return (link, names)
pool = multiprocessing.dummy.Pool(5)
names_list = pool.map(f, enumerate(links))
print(names_list)
答案 1 :(得分:0)
您应该考虑使用Scrapy而不是直接使用lxml和urllib。 Scrapy是“一种快速的高级屏幕抓取和网络爬行框架,用于抓取网站并从网页中提取结构化数据。”它建立在Twisted之上,因此它本身可以异步,因此它非常非常快。
我无法向您提供有关您的抓取速度有多快的任何具体数字,但想象您的请求是并行而非串行发生的。您仍然需要使用xpath或Beautiful Soup编写代码来提取所需的信息,但是您不必计算页面的提取。