HTTP 301 проблема перенаправления URL-адреса перенаправления - PullRequest
0 голосов
/ 02 июля 2018

Я использую Python request.get (), чтобы получить некоторые профили Facebook в формате HTML. Некоторые из них перенаправляют запрос на новый URL. Когда этот новый URL содержит специальные символы, такие как 'á' , метод request.get () входит в цикл перенаправления до тех пор, пока не будет сгенерировано исключение. Я нашел обходной путь для исправления строки URL перенаправления, найденной в заголовке ответа под ключом «Location», но это далеко не элегантное решение.

import requests

# This case works. Response [200]
r = requests.get('https://www.facebook.com/profile.php?id=4')
print(r)

# This fails. Redirect location has special characters.
# raises requests.exceptions.TooManyRedirects: Exceeded 30 redirects.
not_working_url = 'https://www.facebook.com/profile.php?id=100010922979377'
try:
    r = requests.get(not_working_url)
except Exception as e:
    print(e)  # Exceeded 30 redirects.

# Workaround
r = requests.get(not_working_url,
                 allow_redirects=False)
redirect_url = r.headers["Location"]
print(redirect_url)
# "https://www.facebook.com/people/Tomás-Navarro-Febre/100010922979377"
# Special character 'á' on "/Tomás_Navarro_Febre/" is displayed as 'á'.

# This fixes the string.
redirect_url = redirect_url.encode('raw_unicode_escape').decode('utf-8')
print(redirect_url)
# "https://www.facebook.com/people/Tomás-Navarro-Febre/100010922979377"

# Now it works. Response [200]
r = requests.get(redirect_url)
print(r)

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

1 Ответ

0 голосов
/ 02 июля 2018

Заголовки обычно кодируются как Latin-1, поэтому requests использует их для декодирования всех заголовков. Однако на практике заголовок Location обычно использует UTF-8. Затем вы видите Моджибаке , в данном случае данные UTF-8, декодированные как Latin-1.

По состоянию на запросы 2.14.0 (выпущено в мае 2017 г.) библиотека специально декодирует заголовок Location как UTF-8 именно для того, чтобы избежать возникшей проблемы. Обновите библиотеку ваших запросов.

Если вы не можете выполнить обновление, вы можете создать подкласс Session класса, чтобы «исправить» проблему локально:

class UTF8RedirectingSession(requests.Session):
    def get_redirect_target(self, resp):
        if resp.is_redirect:
            return resp.headers['location'].encode('latin1').decode('utf8')
        return None

затем используйте

with UTF8RedirectingSession() as session:
    response = session.get(...)
...