我正在使用 python-requests图书馆来完成我的要求。
在网站的主页上,我得到了一堆图片并将它们展示给用户。有时这些图片会被删除,我会得到一个损坏的图片网址。
所以我想检查图像是否存在。
这是我做的:
items = Item.objects.filter(shop__is_hidden=False, is_hidden=False).order_by("?")[:16]
existing_items = []
for item in items:
response = requests.head(item.item_low_url)
if response.status_code == 200:
existing_items.append(item)
但它花费的时间比我想要的要长一些。
有没有更快的方法?
最佳答案
您的请求是阻塞的和同步的,这就是它需要一些时间的原因。简单来说,这意味着第二个请求不会开始,直到第一个请求完成。
可以把它想象成带有一堆箱子的传送带,你有一个 worker 来处理每个箱子。
worker 一次只能处理一个箱子;并且他必须等待处理完成才能开始处理另一个箱子(换句话说,他不能从传送带上拿一个箱子,把它放到某个地方进行处理,然后再回来取另一个箱子)。
要减少处理框所需的时间,您可以:
- 减少处理每个箱子所需的时间。
- 让多个箱子可以同时处理(换句话说, worker 不必等待)。
- 增加传送带和 worker 的数量,然后在传送带之间划分箱子。
我们真的不能做#1,因为这个延迟来自网络(你可以减少超时时间,但不推荐这样做)。
相反,我们想要做的是 #2 - 由于一个盒子的处理是独立的,我们不需要等待一个盒子完成才能开始处理下一个盒子。
所以我们想做以下事情:
- 同时向服务器快速发送多个 URL 请求。
- 等待他们每个人完成(彼此独立)。
- 收集结果。
documentation for requests 中列出了多种方法可以做到这一点;这是一个使用 grequests
的例子:
import grequests
# Create a map between url and the item
url_to_item = {item.item_low_url: item for item in items}
# Create a request queue, but don't send them
rq = (grequests.head(url) for url in url_to_item.keys())
# Send requests simultaneously, and collect the results,
# and filter those that are valid
# Each item returned in the Response object, which has a request
# property that is the original request to which this is a response;
# we use that to filter out the item objects
results = [url_to_item[i.request.url]
for i in filter(lambda x: x.status_code == 200,
grequests.map(rq)))]
关于python - 快速检查远程 URL 上的图像是否存在于 python 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30588154/