【问题标题】:Fast way to check if image on remote URL exists in python快速检查远程 URL 上的图像是否存在于 python 中的方法
【发布时间】:2015-08-15 18:39:53
【问题描述】:

我正在使用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)

但这比我想要的要长一点。

有没有更快的方法?

【问题讨论】:

    标签: python django python-requests


    【解决方案1】:

    您的请求是阻塞和同步的,这就是它需要一些时间的原因。简单来说,就是第二个请求不会开始,直到第一个请求完成。

    可以把它想象成一个带有一堆盒子的传送带,你有一个工人来处理每个盒子。

    worker 一次只能处理一个盒子;并且他必须等待处理完成,然后才能开始处理另一个盒子(换句话说,他不能从传送带上拿一个盒子,把它丢到要处理的地方,然后回来再挑选一个)。

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

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

    我们真的做不到#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)))]
    

    【讨论】:

    • 感谢您的全面回答。它确实变得更快了,但results 原来是Response 对象的列表,而不是项目,这令人惊讶。有什么办法可以解决这个问题?
    • 它是一堆响应对象的原因是因为这是grequests.map(rq)的返回。请参阅更新以将其映射回原始 item
    猜你喜欢
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2011-11-29
    • 1970-01-01
    • 2014-11-18
    • 2013-03-10
    • 1970-01-01
    相关资源
    最近更新 更多