在Python 3中为urllib.request.urlopen更改用户代理
我想用 urllib.request.urlopen('someurl')
打开一个网址:
with urllib.request.urlopen('someurl') as url:
b = url.read()
但是我总是遇到以下错误:
urllib.error.HTTPError: HTTP Error 403: Forbidden
我了解到这个错误是因为网站不允许 Python 访问,以防止机器人浪费他们的网络资源,这点我能理解。我去查了一下,发现需要更改 urllib 的用户代理。不过我找到的所有关于如何更改用户代理的指南和解决方案都是针对 urllib2 的,而我使用的是 Python 3,所以这些解决方案都不适用。
我该如何在 Python 3 中解决这个问题呢?
4 个回答
这个网站拒绝访问的原因是因为使用了OWASP ModSecurity核心规则,这是一种保护网站的安全措施。规则900002列出了几个被认为是“坏”的用户代理,其中一个就是“python-urllib2”。所以,当你用默认的用户代理发送请求时,就会失败。
不幸的是,如果你使用Python的“robotparser”功能,
它会使用Python默认的用户代理,而且没有参数可以更改这个设置。如果“robotparser”尝试读取“robots.txt”文件时被拒绝(不仅仅是找不到网址),那么它就会把该网站的所有网址都视为不允许访问。
我刚刚在这里回答了一个类似的问题:https://stackoverflow.com/a/43501438/206820
如果你不仅想打开一个网址,还想下载资源(比如一个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这个工具中监控网络流量,这里是我得到的流量信息:
在编程中,有时候我们会遇到一些问题,像是代码运行不正常或者出现错误。这些问题可能是因为我们没有正确理解某些概念,或者在写代码时犯了一些小错误。
比如说,变量就像是一个储物箱,我们可以把数据放进去,随时取出来用。如果我们把一个数字放进了一个变量里,但在后面想用的时候却忘了这个变量的名字,那就会出现问题。
还有,函数就像是一个小机器,我们把一些输入放进去,它会给我们一个输出。我们需要确保输入的东西是机器能理解的,不然机器就会出错。
所以,遇到问题时,首先要冷静下来,仔细检查自己的代码,看看是不是哪里写错了,或者是不是理解错了某个概念。这样才能找到解决办法。
from urllib.request import urlopen, Request
urlopen(Request(url, headers={'User-Agent': 'Mozilla'}))
来自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'))