urllib.urlretrieve 自定义 header
urllib.urlretrieve with custom header
我正在尝试使用 urlretrieve
检索文件,同时添加自定义 header。
在检查 urllib.request
的代码源时,我意识到 urlopen
可以在参数中使用 Request
object 而不仅仅是字符串,允许将 header 我想要。
但是,如果我尝试对 urlretrieve
执行相同的操作,我会得到另一个 post 中提到的 。
我最终做的是重写我自己的 urlretrieve,删除抛出错误的行(该行与我的用例无关)。
它工作正常 但我想知道是否有 better/cleaner 的方法,而不是重写我的拥有 urlretrieve
。如果可以将自定义 header 传递给 urlopen
,感觉应该可以对 urlretrieve
?
做同样的事情
urllib.request.urlretrieve()
在 urllib.request.urlopen()
里面使用(至少在 Python 3)。因此,您可以使用相同的方式来影响 urlopen
.
的行为
当调用 urlopen(params)
时,它实际上首先查看特殊的全局变量 urllib.request._opener
,如果它是 None
,则 urlopen
将变量设置为默认值开瓶器否则它将保持原样。在下一步中,它将调用 urllib.request._opener.open(<urlopen_params>)
(在接下来的部分中,我将 urllib.request._opener
仅称为 opener
)。
opener.open()
包含不同协议的处理程序列表。当调用 opener.open()
时,它将执行以下操作:
- 从 URL
urllib.request.Request
object 创建(或者如果您直接提供 Request
它将直接使用它)。
- 从
Request
object 中提取协议(它从 URL 方案推导出来)。
- 根据协议,它将尝试查找并使用这些方法:
protocol_request
(例如http_request
)-它用于pre-process连接打开前的请求。
protocol_open
- 实际创建与远程服务器的连接
protocol_response
- 处理来自服务器的响应
- 其他方法请看Python's documentation
对于您自己的开瓶器,您必须执行这 3 个步骤:
- 创建自己的处理程序
- 构建处理程序列表包含您的自定义处理程序(函数
urllib.request.build_opener
)
- 将新的 opener 安装到
urllib.request._opener
(函数 urllib.request.install_opener
)
urllib.request.build_opener
创建包含您的自定义处理程序的开启器,并添加默认开启器,但您的自定义处理程序从中继承的处理程序除外。
所以要添加自定义 header 你可以这样写:
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())
老实说,我不知道它是否是 better/cleaner 解决方案,但它使用 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 文档:https://docs.python.org/3/library/urllib.request.html
我正在尝试使用 urlretrieve
检索文件,同时添加自定义 header。
在检查 urllib.request
的代码源时,我意识到 urlopen
可以在参数中使用 Request
object 而不仅仅是字符串,允许将 header 我想要。
但是,如果我尝试对 urlretrieve
执行相同的操作,我会得到另一个 post 中提到的
我最终做的是重写我自己的 urlretrieve,删除抛出错误的行(该行与我的用例无关)。
它工作正常 但我想知道是否有 better/cleaner 的方法,而不是重写我的拥有 urlretrieve
。如果可以将自定义 header 传递给 urlopen
,感觉应该可以对 urlretrieve
?
urllib.request.urlretrieve()
在 urllib.request.urlopen()
里面使用(至少在 Python 3)。因此,您可以使用相同的方式来影响 urlopen
.
当调用 urlopen(params)
时,它实际上首先查看特殊的全局变量 urllib.request._opener
,如果它是 None
,则 urlopen
将变量设置为默认值开瓶器否则它将保持原样。在下一步中,它将调用 urllib.request._opener.open(<urlopen_params>)
(在接下来的部分中,我将 urllib.request._opener
仅称为 opener
)。
opener.open()
包含不同协议的处理程序列表。当调用 opener.open()
时,它将执行以下操作:
- 从 URL
urllib.request.Request
object 创建(或者如果您直接提供Request
它将直接使用它)。 - 从
Request
object 中提取协议(它从 URL 方案推导出来)。 - 根据协议,它将尝试查找并使用这些方法:
protocol_request
(例如http_request
)-它用于pre-process连接打开前的请求。protocol_open
- 实际创建与远程服务器的连接protocol_response
- 处理来自服务器的响应- 其他方法请看Python's documentation
对于您自己的开瓶器,您必须执行这 3 个步骤:
- 创建自己的处理程序
- 构建处理程序列表包含您的自定义处理程序(函数
urllib.request.build_opener
) - 将新的 opener 安装到
urllib.request._opener
(函数urllib.request.install_opener
)
urllib.request.build_opener
创建包含您的自定义处理程序的开启器,并添加默认开启器,但您的自定义处理程序从中继承的处理程序除外。
所以要添加自定义 header 你可以这样写:
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())
老实说,我不知道它是否是 better/cleaner 解决方案,但它使用 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 文档:https://docs.python.org/3/library/urllib.request.html