0

Как получить не-ASCII URL с помощью urlopen?

12

Я столкнулся с проблемой при попытке получить данные по URL, содержащему не-ASCII символы. Используя urllib2.urlopen, я получаю ошибку:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u0131' in position 26: ordinal not in range(128)

Я понимаю, что URL не соответствует стандартам, но у меня нет возможности его изменить.

Как мне получить доступ к ресурсу по URL, содержащему не-ASCII символы, используя Python?

Дополнение: В других словах, как можно использовать urlopen для открытия URL, похожего на следующий:

http://example.org/Ñöñ-ÅŞÇİİ/

5 ответ(ов)

0

В Python 3 для кодирования не-ASCII строки в URL вы можете использовать функцию urllib.parse.quote. Вот пример, как это сделать для китайского текста:

from urllib.request import urlopen
from urllib.parse import quote

chinese_wikipedia = 'http://zh.wikipedia.org/wiki/Wikipedia:' + quote('首页')
response = urlopen(chinese_wikipedia)

В этом коде строка '首页' кодируется в безопасный формат для использования в URL. Функция quote заменяет специальные символы и пробелы на соответствующие коды. После этого вы можете использовать urlopen, чтобы открыть сгенерированный URL.

0

В Python 3 есть библиотеки, которые могут помочь в такой ситуации. Используйте urllib.parse.urlsplit, чтобы разбить URL на его компоненты, urllib.parse.quote, чтобы корректно закодировать/эскейпировать символы Unicode, и urllib.parse.urlunsplit, чтобы объединить его обратно.

Пример кода:

>>> import urllib.parse
>>> url = 'http://example.com/unicodè'
>>> url = urllib.parse.urlsplit(url)
>>> url = list(url)
>>> url[2] = urllib.parse.quote(url[2])
>>> url = urllib.parse.urlunsplit(url)
>>> print(url)
http://example.com/unicod%C3%A8

Этот код возьмет ваш исходный URL, разобьет его на части, закодирует участок с символами Unicode и затем снова соберет URL. Надеюсь, это поможет!

0

В ответ на вопрос о преобразовании IRI в URI на Python, основываясь на ответе пользователя @darkfeline, вот функция, которая реализует это преобразование:

from urllib.parse import urlsplit, urlunsplit, quote

def iri2uri(iri):
    """
    Преобразует IRI в URI (Python 3).
    """
    uri = ''
    if isinstance(iri, str):
        (scheme, netloc, path, query, fragment) = urlsplit(iri)
        scheme = quote(scheme)
        netloc = netloc.encode('idna').decode('utf-8')
        path = quote(path)
        query = quote(query)
        fragment = quote(fragment)
        uri = urlunsplit((scheme, netloc, path, query, fragment))

    return uri

Эта функция принимает строку iri, разбивает ее на компоненты с помощью urlsplit, затем кодирует каждую часть (схема, сетевая часть, путь, запрос и фрагмент) с использованием quote, чтобы обработать специальные символы. Для сетевой части используется кодировка IDNA, чтобы гарантировать правильное представление имен. В конечном итоге, все части объединяются обратно в строку URI с использованием urlunsplit.

0

Чтобы закодировать unicode в UTF-8, а затем выполнить URL-кодирование, вы можете использовать следующий подход в Python:

  1. Сначала преобразуем строку в байты UTF-8.
  2. Затем используем функцию для URL-кодирования.

Вот пример кода:

import urllib.parse

# Ваш юникодный текст
unicode_text = "ваш текст на юникоде"

# Шаг 1: Кодируем в UTF-8
utf8_encoded = unicode_text.encode('utf-8')

# Шаг 2: Выполняем URL-кодирование
url_encoded = urllib.parse.quote(utf8_encoded)

print(url_encoded)

Объяснение шагов:

  • unicode_text.encode('utf-8') выполняет кодирование строки в байты UTF-8.
  • urllib.parse.quote() берет эти байты и выполняет URL-кодирование, заменяя неподходящие символы на их эквиваленты в формате %XX.

После выполнения этого кода вы получите строку, которая правильно закодирована как в UTF-8, так и в URL-формате.

0

Вы можете использовать метод iri2uri из библиотеки httplib2, который выполняет те же функции, что и решение, предложенное Bobin (он/она автор этого?). Этот метод преобразует IRI (Internationalized Resource Identifier) в URI (Uniform Resource Identifier), что может быть полезно, когда вам нужно обеспечить корректное использование ссылок с символами, выходящими за пределы стандартного ASCII.

Чтобы использовать iri2uri, просто импортируйте его из библиотеки httplib2 и передайте IRI в качестве аргумента. Например:

from httplib2 import iri2uri

iri = "http://example.com/path/to/resource?query=тест"
uri = iri2uri(iri)
print(uri)

Обратите внимание, что iri2uri корректно обработает все недопустимые символы, преобразуя их в допустимый формат для URI.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь