Python 3.x urllib.urlretrieve带有自定义标题
我正在尝试使用Python 3.x urllib.urlretrieve带有自定义标题,python-3.x,urllib,urlretrieve,Python 3.x,Urllib,Urlretrieve,我正在尝试使用urlretrieve检索文件,同时添加自定义头 在检查urllib.request的codesource时,我意识到urlopen可以在参数中使用request对象,而不仅仅是字符串,这样就可以放置我想要的头。 但是如果我尝试对urlretrieve做同样的操作,我会得到另一篇文章中提到的结果 我最终做的是重写我自己的urlretrieve,删除抛出错误的行(该行在我的用例中是不相关的) 它工作得很好,但我想知道是否有一种更好/更干净的方法,而不是重写我自己的urlretriev
urlretrieve
检索文件,同时添加自定义头
在检查urllib.request
的codesource时,我意识到urlopen
可以在参数中使用request
对象,而不仅仅是字符串,这样就可以放置我想要的头。
但是如果我尝试对urlretrieve
做同样的操作,我会得到另一篇文章中提到的结果
我最终做的是重写我自己的urlretrieve,删除抛出错误的行(该行在我的用例中是不相关的)
它工作得很好,但我想知道是否有一种更好/更干净的方法,而不是重写我自己的
urlretrieve
。如果可以将自定义头传递给urlopen
,那么感觉应该可以对urlretrieve
?使用urllib.request.urlretrieve()
内部urllib.request.urlopen()
(至少在Python 3中)。因此,您可以使用相同的方法来影响urlopen
的行为
调用urlopen(params)
时,它实际上首先查看特殊的全局变量urllib.request.\u opener
,如果它是None
,则urlopen
使用默认的一组opener设置变量,否则它将保持原样。在下一步中,它将调用urllib.request.\u opener.open()
(在接下来的部分中,我将urllib.request.\u opener
仅作为opener
)
opener.open()
包含不同协议的处理程序列表。调用opener.open()
时,它将执行以下操作:
urllib.request.request
对象创建(或者如果您直接提供请求
它只会使用它)请求
对象中提取协议(它是从URL方案推导出来的)
(例如protocol\u request
)-用于在连接打开之前预处理请求http\u request
-实际创建与远程服务器的连接协议\u open
-处理来自服务器的响应协议\u响应
- 有关其他方法,请参见
urllib.request.Build\u opener
)urlib.request.\u opener
(函数urlib.request.Install\u opener
)urllib.request.build\u opener
创建包含自定义处理程序的opener,并添加默认的opener,但自定义处理程序从中继承的处理程序除外
因此,要添加自定义标题,您可以编写如下内容:
import urllib.request as req
class MyHTTP(req.HTTPHandler):
def http_request(self, req):
req.headers["MyHeader"] = "Content of my header"
return super().http_request(req)
opener = req.build_opener(MyHTTP())
req.install_opener(opener)
从此时起,当您调用urllib.request.urlretrieve()
或任何使用urlopen()
的东西时,它将用于处理程序的HTTP通信。当您想返回默认处理程序时,只需调用:
import urllib.request as req
req.install_opener(req.build_opener())
老实说,我不知道它是否比您的解决方案更好/更干净,但它在
urllib
中使用了预先准备好的机制。我找到了一种方法,您只需添加几行额外的代码
import urllib.request
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
urllib.request.install_opener(opener)
urllib.request.urlretrieve("type URL here", "path/file_name")
如果您希望了解详细信息,可以参考python文档:尝试使用urllib2。有一次我也犯了同样的错误。但是在更改了urllib2之后,它会起作用。我觉得这真是太过分了,但我还是奖励你奖金,因为这是关于urllib的非常有趣的答案。无论如何,我改为使用
请求
库