Как использовать кириллицу в URL?

Есть учебная задачка на Python, которая случайно прыгает по страницам англоязычной википедии:

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re

pages = set()
def getLinks(pageUrl):
    global pages
    
    html = urlopen('http://en.wikipedia.org{}'.format(pageUrl))
    bs = BeautifulSoup(html, 'html.parser')
    for link in bs.find_all('a', href=re.compile('^(/wiki/)')):
        if 'href' in link.attrs:
            if link.attrs['href'] not in pages:
                #We have encountered a new page
                newPage = link.attrs['href']
                print(newPage)
                pages.add(newPage)
                getLinks(newPage)
getLinks('')

Всё прекрасно работает. Но если я попытаюсь в качестве базового URL использовать русскоязычную вики:

html = urlopen('http://ru.wikipedia.org/wiki/Заглавная_страница{}'.format(pageUrl))

то выдаётся сообщение об ошибке: UnicodeEncodeError:

'ascii' codec can't encode characters

Ветку

Как декодировать url-encoded в кириллицу?

я читал. Там проблема другая:

  1. Преобразовать URL -> cp1251
  2. Мне наоборот : utf8 -> URL

Ответы (2 шт):

Автор решения: CrazyElf

Лучше запрашивать страницы модно-современно через requests, он с кодировками сам разберётся, и BS тоже разберётся, если ему content страницы отдать, а печатать потом в "человеческом" виде URL-и можно через unquote:

import requests
from urllib.parse import unquote
...
html = requests.get('http://ru.wikipedia.org/wiki/Заглавная_страница{}'.format(pageUrl)).content
...
print(unquote(newPage))

Остальной код не менялся.

Пример вывода:

/wiki/Википедия:Патрулирование
/wiki/Файл:Wiki_letter_w_dashed.svg
/wiki/Служебная:Поиск/Заглавная_страница/wiki/Файл:Wiki_letter_w_dashed.svg
/wiki/Служебная:Поиск/Заглавная_страница/wiki/Служебная:Поиск/Заглавная_страница/wiki/Файл:Wiki_letter_w_dashed.svg
/wiki/Служебная:Поиск/Заглавная_страница/wiki/Служебная:Поиск/Заглавная_страница/wiki/Служебная:Поиск/Заглавная_страница/wiki/Файл:Wiki_letter_w_dashed.svg
/wiki/Заглавная_страница
/wiki/Служебная:Поиск/Заглавная_страница/wiki/Заглавная_страница
...
→ Ссылка
Автор решения: gil9red

Используйте quote для замены кириллицы

В url тогда будет такая строка:

http://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0

Пример:

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


uri = 'Заглавная_страница'
pageUrl = ''
url = 'http://ru.wikipedia.org/wiki/{}{}'.format(quote(uri, 'utf-8'), pageUrl)
print(url)

html = urlopen(url)
print(html)
→ Ссылка