python - 快速检查远程 URL 上的图像是否存在于 python 中

标签 python django python-requests

我正在使用 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 一次只能处理一个箱子;并且他必须等待处理完成才能开始处理另一个箱子(换句话说,他不能从传送带上拿一个箱子,把它放到某个地方进行处理,然后再回来取另一个箱子)。

要减少处理框所需的时间,您可以:

  1. 减少处理每个箱子所需的时间。
  2. 让多个箱子可以同时处理(换句话说, worker 不必等待)。
  3. 增加传送带和 worker 的数量,然后在传送带之间划分箱子。

我们真的不能做#1,因为这个延迟来自网络(你可以减少超时时间,但不推荐这样做)。

相反,我们想要做的是 #2 - 由于一个盒子的处理是独立的,我们不需要等待一个盒子完成才能开始处理下一个盒子。

所以我们想做以下事情:

  1. 同时向服务器快速发送多个 URL 请求。
  2. 等待他们每个人完成(彼此独立)。
  3. 收集结果。

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/

相关文章:

python - 分发具有 Julia 依赖项的独立 Python 软件

python - 将 PyTorch CUDA 张量转换为 NumPy 数组

python - 是否有更优雅的方法来处理此抓取工具中的空值?

python - NumPy 矩阵类的弃用状态

python - 重定向 URL 在 azure 上不匹配

python-3.x - 使用 Djangobulk_update() 时,“dict”对象没有属性 'pk'

python - 如果数据库发生变化,如何停止执行长进程?

python - 需要接受隐私政策才能访问页面

python - 通过请求发布到 FB 组,允许加载 youtube 视频

Python:如何使用请求库通过多个不同的代理服务器访问 url?