【问题标题】:Could not download image from url link using Python无法使用 Python 从 url 链接下载图像
【发布时间】:2018-10-17 08:40:51
【问题描述】:

我想从网上下载一张图片,但无论使用哪种方法,我总是会收到错误消息。但是,我使用这种方法下载其他图像没有问题。

作品 - https://mobec.sk/proxy/geo?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng8&TRANSPARENT=true&layers=global%3Abase&tiled=true&STYLES=&WIDTH=512&HEIGHT=512&CRS=EPSG%3A3857&FORMAT_OPTIONS=dpi%3A180&BBOX=1934774.0599543825%2C6239707.492975509%2C1937220.044859508%2C6242153.477880634

不起作用 - https://mobec.sk/proxy/geo?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&layers=custom%3Avrbovce_elektrina&tiled=true&STYLES=&WIDTH=512&HEIGHT=512&CRS=EPSG%3A3857&FORMAT_OPTIONS=dpi%3A180&BBOX=1947003.9844800085%2C6242153.477880634%2C1949449.969385134%2C6244599.46278576

方法一

使用 Python 的 requests 和 Pillow 库。这里应该直接从url下载图片。

import requests
from PIL import Image
from io import BytesIO

url = 'https://mobec.sk/proxy/geo?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&layers=custom%3Avrbovce_elektrina&tiled=true&STYLES=&WIDTH=512&HEIGHT=512&CRS=EPSG%3A3857&FORMAT_OPTIONS=dpi%3A180&BBOX=1947003.9844800085%2C6242153.477880634%2C1949449.969385134%2C6244599.46278576'

response = requests.get(url)
img = Image.open(BytesIO(response.content))   # error occurs here
img.save('output.png')

我收到以下错误:

OSError: cannot identify image file <_io.BytesIO object at 0x04956510>

方法二

使用 Python 的 Selenium 库和 chromedriver。在这里,我尝试在 Web 浏览器中显示图像并使用 Selenium 库打印整个页面。

from selenium import webdriver
from PIL import Image
from io import BytesIO

url = 'https://mobec.sk/proxy/geo?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&layers=custom%3Avrbovce_elektrina&tiled=true&STYLES=&WIDTH=512&HEIGHT=512&CRS=EPSG%3A3857&FORMAT_OPTIONS=dpi%3A180&BBOX=1947003.9844800085%2C6242153.477880634%2C1949449.969385134%2C6244599.46278576'

chrome = webdriver.Chrome('path/to/chromedriver')
chrome.get(url)

png = chrome.get_screenshot_as_png()
im = Image.open(BytesIO(png))
im.save('output.png')

chrome.quit()

这个方法的问题是chromedriver驱动打开的Chrome浏览器中没有加载(显示)图片。手动将链接粘贴到普通(桌面应用)Chrome 中时,会显示图像。

【问题讨论】:

    标签: python python-requests selenium-chromedriver python-imaging-library


    【解决方案1】:

    我在两个链接上都测试了这两种方法,看起来第二个链接有问题:第一个链接工作得很好,无论是使用浏览器手动打开它还是使用其中任何一种方法;第二个没有在浏览器中打开,并且在两种方法中都出现错误(这两种方法都很好)。

    如错误消息中所述 - Could not find layer custom:vrbovce_elektrina - 在两种方法和手动粘贴中,浏览器都找不到名为 vrbovce_elektrina 的层。也许那里有错字,或者此页面上没有这样的图像/图层。

    代码不错,就是链接失效了。

    【讨论】:

    • 我就是这么想的。当我单击第二个链接时,浏览器会尝试打开图像,但会出现错误(图 1)。但是,当我复制链接并将其作为 url 粘贴到新的 Web 浏览器选项卡中时,会显示图像。你知道为什么会这样吗?
    • 老实说不知道,因为我根本无法打开第二个链接。尝试使用不同的浏览器,尝试在 selenium 中使用不同的驱动程序(chrome、phantomjs 等),但我仍然看不到图像。
    • 我在想问题是否不在于 HTTP 请求标头中传递给 Web 服务器的信息(语言、用户、...)。我试图更改标头,因此它不会获取请求是由 python 脚本发送的信息。不过不知道为什么打不开(难道只能在我的国家打开吗?为什么只有这个特定的层?)
    • 是的,我知道这很奇怪。看看其他人是否可以打开链接会很有帮助
    • 最后,我设法下载了这张图片和其他类似的图片。我不知道为什么,但是当我首先打开以下网址(方法 2)时它起作用了:“mobec.sk/vrbovce#base”(这是显示这些图像的地图的网站)。
    【解决方案2】:

    正如@Piotrek 所写,问题不在代码中。我想问题出在服务器端。这对我有用:

    1. 我用过方法二
    2. 在打开 url 链接之前,我已经打开了以下“父”url (https://mobec.sk/vrbovce#base),它使用这些图像 创建地图
    3. 在下一步中,我已经在
      中打开了图片的url链接 使用 selenium python 模块的 chrome 网络浏览器
    4. 之后,我可以截取图像

    这是对我有用的代码:

    from selenium import webdriver
    from PIL import Image
    from io import BytesIO
    
    web_driver = webdriver.Chrome('path/to/chromedriver')
    web_driver.get('https://mobec.sk/vrbovce#base')
    
    web_driver.get('https://mobec.sk/proxy/geo?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&layers=custom%3Avrbovce_elektrina&tiled=true&STYLES=&WIDTH=512&HEIGHT=512&CRS=EPSG%3A3857&FORMAT_OPTIONS=dpi%3A180&BBOX=1947003.9844800085%2C6242153.477880634%2C1949449.969385134%2C6244599.46278576')
    
    png = web_driver.get_screenshot_as_png()
    im = Image.open(BytesIO(png))
    im.save('output.png')
    
    web_driver.quit()
    

    【讨论】:

      【解决方案3】:

      使用请求,只需将响应内容写入文件即可:

      with open('image-file', 'wb') as fp: 
         fp.write(response.content)
      

      【讨论】:

        【解决方案4】:

        您可以为此使用StringIO 库。

        import requests
        from PIL import Image
        from StringIO import StringIO
        
        url = 'https://mobec.sk/proxy/geo?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng8&TRANSPARENT=true&layers=global%3Abase&tiled=true&STYLES=&WIDTH=512&HEIGHT=512&CRS=EPSG%3A3857&FORMAT_OPTIONS=dpi%3A180&BBOX=1934774.0599543825%2C6239707.492975509%2C1937220.044859508%2C6242153.477880634'
        
        response = requests.request("GET", url)
        image = Image.open(StringIO(response.content))
        image.save('output.png')
        

        对于python3;

        import requests
        from PIL import Image
        from io import BytesIO
        
        url = 'https://mobec.sk/proxy/geo?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng8&TRANSPARENT=true&layers=global%3Abase&tiled=true&STYLES=&WIDTH=512&HEIGHT=512&CRS=EPSG%3A3857&FORMAT_OPTIONS=dpi%3A180&BBOX=1934774.0599543825%2C6239707.492975509%2C1937220.044859508%2C6242153.477880634'
        
        response = requests.request("GET", url)
        image = Image.open(BytesIO(response.content))
        image.save('output.png')
        

        【讨论】:

        • "from StringIO import StringIO" 仅适用于 Python 2。在 Python 3 中使用“from io import StringIO”。但是,它也不起作用并给出以下错误消息:“TypeError initial_value must be str or None, not bytes”。
        • 我更新了我对 python3 的答案,并在repl.it 尝试了更新的代码并且工作正常。
        • 问题是代码不能与示例中列出的 url 一起使用。它适用于您从一开始就使用的 url。尝试使用“不起作用”链接,它不会运行。请参阅问题中的前 2 个链接。无论如何,感谢您提供的示例。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多