<p><code>requests</code>使用了<code>urllib3</code>,最终也使用了<code>httplib.HTTPConnection</code>,因此在一定程度上,来自^{s><a href="https://stackoverflow.com/questions/4623090/python-set-custom-dns-server-for-urllib-requests">https://stackoverflow.com/questions/4623090/python-set-custom-dns-server-for-urllib-requests</a></s>的技术(现在已经删除,它仅仅链接到<a href="https://stackoverflow.com/questions/2236498/tell-urllib2-to-use-custom-dns">Tell urllib2 to use custom DNS</a>)仍然适用。</p>
<p>同名的<code>urllib3.connection</code>模块子类<code>httplib.HTTPConnection</code>,用调用<code>self._new_conn</code>的方法替换了<code>.connect()</code>方法。反过来,这个委托给<code>urllib3.util.connection.create_connection()</code>。可能最容易修补<em>的</em>功能:</p>
<pre><code>from urllib3.util import connection
_orig_create_connection = connection.create_connection
def patched_create_connection(address, *args, **kwargs):
"""Wrap urllib3's create_connection to resolve the name elsewhere"""
# resolve hostname to an ip address; use your own
# resolver here, as otherwise the system resolver will be used.
host, port = address
hostname = your_dns_resolver(host)
return _orig_create_connection((hostname, port), *args, **kwargs)
connection.create_connection = patched_create_connection
</code></pre>
<p>您可以提供自己的代码来将地址的<code>host</code>部分解析为一个ip地址,而不是依赖<code>connection.create_connection()</code>调用(它包装<code>socket.create_connection()</code>)来为您解析主机名。</p>
<p>像所有的monkeypatching一样,要注意代码在以后的版本中没有明显的变化;这里的补丁是针对<code>urllib3</code>版本1.21.1创建的。但最早应该在1.9版本中使用。</p>
<hr/>
<p><em>请注意,重新编写此答案是为了与较新的<code>urllib3</code>版本一起使用,这些版本添加了更方便的修补位置。请参阅适用于<;1.9版的旧方法的编辑历史记录,该方法是对所提供的<code>urllib3</code>版本的修补程序,而不是独立安装。</em></p>