Не удалось загрузить изображение по URL-ссылке с помощью Python

Я хочу загрузить изображение из Интернета, но всегда получаю сообщение об ошибке независимо от используемого метода. Однако у меня нет проблем с загрузкой других изображений с помощью этого метода.

работает - 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

Способ 1

Использование запросов Python и библиотек 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>

Метод 2

Использование библиотеки Python Selenium и chromedriver. Здесь я пытаюсь показать изображение в веб-браузере и распечатать всю страницу, используя библиотеку 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()

Проблема с этим методом заключается в том, что изображение не загружается (не отображается) в браузере Chrome, открытом драйвером chromedriver. При ручной вставке ссылки в обычное (настольное приложение) Chrome отображается изображение.

Способ 2 – изображение не загружается в Chrome


person user21816    schedule 17.10.2018    source источник


Ответы (4)


Я проверил оба метода на обеих ссылках, и похоже, что со второй ссылкой что-то не так: первая работает отлично, либо при ручном открытии в браузере, либо с использованием любого из этих методов; второй не открывается в браузере и выдает ошибку в обоих методах (оба хороши с точки зрения кода).

Как написано в сообщении об ошибке - Could not find layer custom:vrbovce_elektrina - ни при методах, ни при ручной вставке браузер не может найти слой с именем vrbovce_elektrina. Возможно, там опечатка или такого изображения/слоя нет на этой странице.

Код хороший, только ссылка не работает.

person Piotrek    schedule 17.10.2018
comment
Вот что я думал. Когда я нажимаю на вторую ссылку, браузер пытается открыть изображение, но выдает ошибку (рис. 1). Однако, когда я копирую ссылку и вставляю ее как URL-адрес на новую вкладку веб-браузера, отображается изображение. У вас есть идеи, почему это так? - person user21816; 17.10.2018
comment
Понятия не имею, если честно, потому что вторую ссылку вообще не могу открыть. Пробовал использовать разные браузеры, пытался использовать разные драйверы в селене (chrome, phantomjs и т. д.), и я все еще не вижу изображения. - person Piotrek; 17.10.2018
comment
Я думал, что проблема не в информации, передаваемой веб-серверу в заголовке HTTP-запроса (язык, пользователь, ...). Я попытался изменить заголовок, чтобы он не получал информацию о том, что запрос был отправлен скриптом Python. Тем не менее, я не знаю, почему вы не можете его открыть (Может ли он быть открыт только в моей стране? Почему только этот конкретный слой?) - person user21816; 17.10.2018
comment
да, я знаю, что это странно. было бы полезно узнать, может ли кто-нибудь еще открыть ссылку - person Piotrek; 17.10.2018
comment
Наконец-то мне удалось скачать это и другие подобные изображения. Я не знаю почему, но это сработало, когда я сначала открыл следующий URL-адрес (метод 2): mobec.sk/ vrbovce#base (это веб-сайт, на котором показана карта из этих изображений). - person user21816; 17.10.2018
comment
рад, что это сработало. как ни странно, открытие так, как вы предложили, теперь работает и для меня :) - person Piotrek; 17.10.2018

Как писал @Piotrek, проблема была не в коде. Думаю проблема была на стороне сервера. Вот что сработало для меня:

  1. Я использовал метод 2
  2. перед открытием URL-ссылки я открыл следующий «родительский» URL-адрес (https://mobec.sk/vrbovce#base), который использует эти изображения для создания карты
  3. на следующем шаге я открыл URL-ссылку изображения в веб-браузере Chrome
    , используя модуль selenium python.
  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()
person user21816    schedule 17.10.2018

Используя запросы, просто запишите содержимое ответа в файл:

with open('image-file', 'wb') as fp: 
   fp.write(response.content)
person Vikrant Sharma    schedule 17.10.2018

Для этого вы можете использовать библиотеку 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')

для питона3;

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')
person uedemir    schedule 17.10.2018
comment
from StringIO import StringIO работает только в Python 2. В Python 3 используйте from io import StringIO. Однако это тоже не работает и выдает следующее сообщение об ошибке: TypeError initial_value должен быть str или None, а не bytes. - person user21816; 17.10.2018
comment
Я обновил свой ответ для python3 и попробовал обновленный код на repl.it и работает нормально. - person uedemir; 17.10.2018
comment
Проблема в том, что код не работает с URL-адресом, указанным в примере. Он хорошо работал с URL-адресом, который вы использовали с самого начала. Попробуй с неработающей ссылкой, не запустится. Пожалуйста, посмотрите первые 2 ссылки в вопросе. В любом случае, спасибо за предоставленный пример. - person user21816; 17.10.2018