无法使用 python 连接到 *.onion 站点(<urlopen 错误 [Errno 11001] getaddrinfo failed>)

Posted

技术标签:

【中文标题】无法使用 python 连接到 *.onion 站点(<urlopen 错误 [Errno 11001] getaddrinfo failed>)【英文标题】:can't connect to *.onion sites with python (<urlopen error [Errno 11001] getaddrinfo failed>) 【发布时间】:2016-11-13 23:38:16 【问题描述】:

我正在尝试使用 python 访问 *.onion 站点。不过还没有成功。 我已经阅读了很多***问题和答案,尝试了很多不同的方法来解决这个问题:我尝试使用Python 2.7Python 3.5,尝试使用urlliburllib2requests(然后我发现requests 不适用于袜子),pysocks 等,但似乎没有任何效果。 现在我只得到以下错误:

> <urlopen error [Errno 11001] getaddrinfo failed>

不,我没有防火墙,是的,我有良好的互联网连接,是的,该网站确实存在。 我认为问题在于它是一个 *.onion 链接。

这就是我现在正在做的事情:

import socks
import socket
import urllib
import urllib.request

socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 9050)
socket.socket = socks.socksocket
r = urllib.request.urlopen("http://xmh57jrzrnw6insl.onion")
r.read()

这就是我得到的:

---------------------------------------------------------------------------
gaierror                                  Traceback (most recent call last)
C:\Users\yella\Anaconda3\lib\urllib\request.py in do_open(self, http_class, req, **http_conn_args)
   1239             try:
-> 1240                 h.request(req.get_method(), req.selector, req.data, headers)
   1241             except OSError as err: # timeout error

C:\Users\yella\Anaconda3\lib\http\client.py in request(self, method, url, body, headers)
   1082         """Send a complete request to the server."""
-> 1083         self._send_request(method, url, body, headers)
   1084 

C:\Users\yella\Anaconda3\lib\http\client.py in _send_request(self, method, url, body, headers)
   1127             body = body.encode('iso-8859-1')
-> 1128         self.endheaders(body)
   1129 

C:\Users\yella\Anaconda3\lib\http\client.py in endheaders(self, message_body)
   1078             raise CannotSendHeader()
-> 1079         self._send_output(message_body)
   1080 

C:\Users\yella\Anaconda3\lib\http\client.py in _send_output(self, message_body)
    910 
--> 911         self.send(msg)
    912         if message_body is not None:

C:\Users\yella\Anaconda3\lib\http\client.py in send(self, data)
    853             if self.auto_open:
--> 854                 self.connect()
    855             else:

C:\Users\yella\Anaconda3\lib\http\client.py in connect(self)
    825         self.sock = self._create_connection(
--> 826             (self.host,self.port), self.timeout, self.source_address)
    827         self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

C:\Users\yella\Anaconda3\lib\socket.py in create_connection(address, timeout, source_address)
    692     err = None
--> 693     for res in getaddrinfo(host, port, 0, SOCK_STREAM):
    694         af, socktype, proto, canonname, sa = res

C:\Users\yella\Anaconda3\lib\socket.py in getaddrinfo(host, port, family, type, proto, flags)
    731     addrlist = []
--> 732     for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
    733         af, socktype, proto, canonname, sa = res

gaierror: [Errno 11001] getaddrinfo failed

During handling of the above exception, another exception occurred:

URLError                                  Traceback (most recent call last)
<ipython-input-72-1e30353c3485> in <module>()
----> 1 r = urllib.request.urlopen("http://xmh57jrzrnw6insl.onion:80")
      2 r.read()

C:\Users\yella\Anaconda3\lib\urllib\request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    160     else:
    161         opener = _opener
--> 162     return opener.open(url, data, timeout)
    163 
    164 def install_opener(opener):

C:\Users\yella\Anaconda3\lib\urllib\request.py in open(self, fullurl, data, timeout)
    463             req = meth(req)
    464 
--> 465         response = self._open(req, data)
    466 
    467         # post-process response

C:\Users\yella\Anaconda3\lib\urllib\request.py in _open(self, req, data)
    481         protocol = req.type
    482         result = self._call_chain(self.handle_open, protocol, protocol +
--> 483                                   '_open', req)
    484         if result:
    485             return result

C:\Users\yella\Anaconda3\lib\urllib\request.py in _call_chain(self, chain, kind, meth_name, *args)
    441         for handler in handlers:
    442             func = getattr(handler, meth_name)
--> 443             result = func(*args)
    444             if result is not None:
    445                 return result

C:\Users\yella\Anaconda3\lib\urllib\request.py in http_open(self, req)
   1266 
   1267     def http_open(self, req):
-> 1268         return self.do_open(http.client.HTTPConnection, req)
   1269 
   1270     http_request = AbstractHTTPHandler.do_request_

C:\Users\yella\Anaconda3\lib\urllib\request.py in do_open(self, http_class, req, **http_conn_args)
   1240                 h.request(req.get_method(), req.selector, req.data, headers)
   1241             except OSError as err: # timeout error
-> 1242                 raise URLError(err)
   1243             r = h.getresponse()
   1244         except:

URLError: <urlopen error [Errno 11001] getaddrinfo failed>

我对所有这些东西都很陌生,所以我可能会遗漏一些非常简单的部分。但我将不胜感激。

ps:当尝试访问不是 *.onion 站点时,我得到以下信息:

[WinError 10061] No connection could be made because the target machine actively refused it

【问题讨论】:

最近版本的 Requests support SOCKS proxies 就好了。 Tor 本身不是 http 代理,因此如果您只是将其作为普通的 socks5 代理连接到它,它将无法解析 .onion 域。你应该看看sacharya.com/crawling-anonymously-with-tor-in-python 你试过用torsocks吗?这是 IMO 最简单的方法。 @larsks 我刚刚尝试使用请求,得到了同样的错误:requests.exceptions.ConnectionError: SOCKSHTTPConnectionPool(host='xmh57jrzrnw6insl.onion', port=80): Max retries exceeded with url: / (由 NewConnectionError 引起(': 无法建立新连接:[Errno 10061] 无法建立连接,因为目标机器主动拒绝它',)) 您的 Windows 机器上是否运行了 Tor 守护程序并监听端口 9050?从外观上看,Tor 没有在您的计算机上运行,​​或者它正在使用不同的端口。 【参考方案1】:

我在 Linux 上,但您提供的代码对我不起作用。从外观上看,Tor 上没有发生 DNS 解析(基于错误 11001 WSAHOST_NOT_FOUND)。由于 10061(连接被拒绝)错误,我也有点怀疑它实际上正在使用 Tor。

无论如何,我都能让它工作:

import urllib2
import socks
from sockshandler import SocksiPyHandler

opener = urllib2.build_opener(SocksiPyHandler(socks.SOCKS5, "127.0.0.1", 9050, True))
print opener.open("http://xmh57jrzrnw6insl.onion").read()

PySocks 在他们的docs 中说:

请注意,monkeypatching 可能不适用于所有标准模块或 所有第三方模块,通常不推荐。 Monkeypatching 通常是 Python 中的一种反模式。

猴子补丁是使用socket.socket = socks.socksocket

如果可能,将Requests 与socks5h:// 协议处理程序一起用于您的代理:

import requests
import json

proxies = 
    'http': 'socks5h://127.0.0.1:9050',
    'https': 'socks5h://127.0.0.1:9050'


data = requests.get("http://xmh57jrzrnw6insl.onion",proxies=proxies).text

print(data)

【讨论】:

以上是关于无法使用 python 连接到 *.onion 站点(<urlopen 错误 [Errno 11001] getaddrinfo failed>)的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 MYSQL 工作台连接到亚马逊 RDS

无法使用 Python 连接到 MSSQL Server 数据库

无法连接到使用 Elastic Beanstalk 创建的 RDS 实例

无法连接到recaptcha服务

无法从 SSMS 连接到 AWS 数据库

如何在没有浏览器的情况下在 python 中使用 Tor?