Python-Requests 从错误信息获取完整 URL

2 投票
1 回答
1056 浏览
提问于 2025-04-18 12:24

我正在尝试使用requests库来还原缩短的URL。现在我做的事情是这样的:

import requests
from contextlib import closing

def unshorten(url):
    session = requests.session()
    with closing(session.head(url)) as req:
        r = req
    if not r.headers.get('location'):  # not a redirect
        return url
    tmp_url = url
    try:
        for redir in session.resolve_redirects(r, r.request):
            if redir.status_code == 200 and not url_no_good(redir.url):  # ok!
                return redir.url
            else:
                tmp_url = redir.url
        else: # no acceptable responses :(
            return tmp_url
    except requests.exceptions.TooManyRedirects:
        return url

(url_no_good是一些测试的简写,用来确保这个URL不是,比如说,DNS引起的404页面)

我遇到了一个问题,就是某个URL重定向到了一个不再有效的网站。我不想要缩短的链接,我想要那个“坏”的URL。我用以下方法“解决”了这个问题:

ERR_PAT = re.compile(r'host=\'([\w\d\.]+)\'')
...
        try:
            for redir in session.resolve_redirects(r, r.request):
            ...
        except requests.exceptions.TooManyRedirects:
            return url
        except requests.exceptions.ConnectionError as e:
            return 'http://' + re.search(ERR_PAT, e.message.message).group(1) + e.message.url

因为对于requests的连接错误,err.message.message是错误的字符串表示,而err.message.url是URL中非域名的部分,比如说/foo/bar?baz=bloo。把错误信息的不同部分拼凑在一起感觉非常“黑科技”,我真的很想知道有没有更简单的方法来处理这种情况。

1 个回答

0

当这个异常被触发时,redir 仍然指向你上一次尝试跟随重定向的请求:

try:
    redir = r  # in case the first redirect fails
    for redir in session.resolve_redirects(r, r.request):
        if redir.status_code == 200 and not url_no_good(redir.url):  # ok!
            return redir.url
        else:
            tmp_url = redir.url
    else: # no acceptable responses :(
        return tmp_url
except requests.exceptions.TooManyRedirects:
    return url
except requests.exceptions.ConnectionError:
    return redir.headers.get('location', url)

撰写回答