在Python 3中更改urrlib.request.urlopen的用户代理

91

我想使用 urllib.request.urlopen('someurl') 打开一个URL:

with urllib.request.urlopen('someurl') as url:
b = url.read()

我一直收到以下错误:

urllib.error.HTTPError: HTTP Error 403: Forbidden

我理解这个错误是由于该网站不允许Python访问而导致的,以防止机器人浪费他们的网络资源,这是可以理解的。我搜索并发现需要更改urllib的用户代理才行。然而,我所找到的所有指南和解决方案都是针对urllib2的,而我正在使用Python 3,因此所有的解决方案都不起作用。

我应该如何用Python 3解决这个问题?


一个403错误可能不是由于您的用户代理造成的。 - hd1
4个回答

115

来自Python文档:

import urllib.request
req = urllib.request.Request(
    url, 
    data=None, 
    headers={
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'
    }
)

f = urllib.request.urlopen(req)
print(f.read().decode('utf-8'))

太棒了!这几乎工作得很好- 只是疑惑一下,你怎么从那个地方获取源代码?通常我会使用url.read(),但在这种情况下不起作用,因为它是一个urllib.request.Request而不是urlopen。 - user3662991
1
更新答案,这样你就可以看到如何使用它。 - Martin Konecny
import urllib.request ImportError: No module named request - User
HTTP错误 404:未找到 - Yaroslav Dukal
5
@用户,停止使用Python 2,这是Python 3。 - kb1000
我遇到了这个错误 >web_byte = req.read() AttributeError: 'bytes'对象没有'read'属性。 - Chemist

38
from urllib.request import urlopen, Request

urlopen(Request(url, headers={'User-Agent': 'Mozilla'}))

1
这很重要。我必须导入urllib.request而不仅仅是urllib。在进行这种修改后,接受的答案中的其他所有内容都有效。 - wrkyle
1
是的,你说得对,但是被接受的答案没有提到这一点,所以我想引起大家对你的回答的关注,因为它解决了被接受答案中的一个缺陷。 - wrkyle
HTTP错误404:未找到 - Yaroslav Dukal

10

我刚在这里回答了一个类似的问题:https://dev59.com/DHE95IYBdhLWcg3wUMPW#43501438

如果你不仅想访问网址,而且还想下载资源(比如说PDF文件),你可以使用以下代码:

    # proxy = ProxyHandler({'http': 'http://192.168.1.31:8888'})
    proxy = ProxyHandler({})
    opener = build_opener(proxy)
    opener.addheaders = [('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30')]
    install_opener(opener)

    result = urlretrieve(url=file_url, filename=file_name)
жҲ‘ж·»еҠ д»ЈзҗҶзҡ„еҺҹеӣ жҳҜдёәдәҶзӣ‘жҺ§Charlesдёӯзҡ„жөҒйҮҸпҝҪпҝҪиҝҷжҳҜжҲ‘еҫ—еҲ°зҡ„жөҒйҮҸпјҡ

жҹҘзңӢUser-Agent


感谢您提供了使用build_opener()返回的OpenerDirector对象的答案!那对我帮助很大。 - happyskeptic

2
主机网站拒绝来自Apache mod-security的OWASP ModSecurity Core Rules。规则900002列出了一些“不良”用户代理之一是“python-urllib2”。这就是为什么带有默认用户代理的请求失败的原因。
不幸的是,如果您使用Python的“robotparser”函数,

https://docs.python.org/3.5/library/urllib.robotparser.html?highlight=robotparser#module-urllib.robotparser

它使用默认的Python用户代理,没有参数可以更改。如果 "robotparser" 尝试读取 "robots.txt" 被拒绝(不仅是 URL 未找到),则它会将该站点的所有 URL 视为不允许访问。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接