Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x urllib.urlretrieve带有自定义标题_Python 3.x_Urllib_Urlretrieve - Fatal编程技术网

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()
时,它将执行以下操作:

  • 从URL
    urllib.request.request
    对象创建(或者如果您直接提供
    请求
    它只会使用它)
  • 请求
    对象中提取协议(它是从URL方案推导出来的)
  • 根据协议,它将尝试查找并使用以下方法:
    • protocol\u request
      (例如
      http\u request
      )-用于在连接打开之前预处理请求
    • 协议\u open
      -实际创建与远程服务器的连接
    • 协议\u响应
      -处理来自服务器的响应
    • 有关其他方法,请参见
  • 对于您自己的开场白,您必须执行以下3个步骤:

  • 创建自己的处理程序
  • 处理程序的生成列表包含自定义处理程序(函数
    urllib.request.Build\u opener
  • 将新的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的非常有趣的答案。无论如何,我改为使用
    请求