Не удается открыть URL Unicode с помощью Python
Используя Python 2.5.2 и Linux Debian, я пытаюсь получить контент с испанского URL, который содержит испанский символ 'í'
:
import urllib
url = u'http://mydomain.es/índice.html'
content = urllib.urlopen(url).read()
Я получаю эту ошибку:
UnicodeEncodeError: кодек "ascii" не может кодировать символ u '\ xe1' в позиции 8: порядковый номер не в диапазоне (128)
Я пытался использовать перед передачей URL, чтобы urllib это:
url = urllib.quote(url)
и это:
url = url.encode('UTF-8')
но они не работали.
Можете ли вы сказать мне, что я делаю не так?
Ответы
Ответ 1
В соответствии с применимым стандартом RFC 1378, URL-адреса могут содержать только символы ASCII. Хорошее объяснение здесь, и я цитирую:
"... Только буквенные символы [0-9a-zA-Z], специальные символы" $-_. +! * '(), "[не включая кавычки], и зарезервированные символы, используемые для их зарезервированные цели могут быть использованы unencoded в URL-адресе."
В качестве URL-адресов, которые я вам объяснил, это, вероятно, означает, что вам придется заменить этот "строчный ящик с острым акцентом" на "% ED".
Ответ 2
Это работает для меня:
#!/usr/bin/env python
# define source file encoding, see: http://www.python.org/dev/peps/pep-0263/
# -*- coding: utf-8 -*-
import urllib
url = u'http://example.com/índice.html'
content = urllib.urlopen(url.encode("UTF-8")).read()
Ответ 3
Кодирование URL-адреса как utf-8 должно работать. Интересно, правильно ли закодирован ваш исходный файл и знает ли его интерпретатор. Если ваш исходный файл python сохраняется, например, как UTF-8, то вы должны иметь
# coding=UTF-8
как первая или вторая строка.
import urllib
url = u'http://mydomain.es/índice.html'
content = urllib.urlopen(url.encode('utf-8')).read()
работает для меня.
Изменить: также помните, что текст Unicode в интерактивном сеансе Python (будь то через IDLE или консоль) чреват сложностью, связанной с кодированием. В этих случаях вы должны использовать литералы Юникода (например, в вашем случае).
Ответ 4
Это работает для меня. Убедитесь, что вы используете довольно недавнюю версию Python, и ваша кодировка файла верна.
Здесь мой код:
# -*- coding: utf-8 -*-
import urllib
url = u'http://mydomain.es/índice.html'
url = url.encode('utf-8')
content = urllib.urlopen(url).read()
(mydomain.es не существует, поэтому поиск DNS не выполняется, но к этому моменту нет проблем с unicode.)
Ответ 5
У меня сейчас похожий случай. Я пытаюсь загрузить изображения. Я получаю URL-адреса с сервера в файле JSON. Некоторые изображения содержат символы не ASCII. Это выдает ошибку:
for image in product["images"]:
filename = os.path.basename(image)
filepath = product_path + "/" + filename
urllib.request.urlretrieve(image, filepath) # error!
UnicodeEncodeError: кодек "ascii" не может кодировать символ "\ xc7" в позиции...
Я пытался использовать .encode("UTF-8")
, но не могу сказать, что это помогло:
# coding=UTF-8
import urllib
url = u"http://example.com/wp-content/uploads/2018/09/İMAGE-1.png"
url = url.encode("UTF-8")
urllib.request.urlretrieve(url, "D:\image-1.jpg")
Это просто добавляет еще одну ошибку:
TypeError: нельзя использовать строковый шаблон для байтовоподобного объекта
Затем я дал urllib.parse.quote(url)
попробовать:
import urllib
url = "http://example.com/wp-content/uploads/2018/09/İMAGE-1.png"
url = urllib.parse.quote(url)
urllib.request.urlretrieve(url, "D:\image-1.jpg")
и снова это выдает еще одну ошибку:
ValueError: неизвестный тип URL: 'http% 3A//example.com/wp-content/uploads/2018/09/% C4% B0MAGE-1.png'
В :
"http://..."
также сбежал, и я думаю, что это является причиной проблемы.
Итак, я нашел обходной путь. Я просто цитирую/избегаю пути, а не весь URL.
import urllib.request
import urllib.parse
url = "http://example.com/wp-content/uploads/2018/09/İMAGE-1.png"
url = urllib.parse.urlparse(url)
url = url.scheme + "://" + url.netloc + urllib.parse.quote(url.path)
urllib.request.urlretrieve(url, "D:\image-1.jpg")
Вот как выглядит URL: "http://example.com/wp-content/uploads/2018/09/%C4%B0MAGE-1.png"
, и теперь я могу загрузить изображение.