在python中使用urllib通过FQDN获取IPv6 URL



我想用urllib获取一个IPv6页面。 适用于方形布拉克 IPv6 表示法,但我不知道如何(轻松(说服 python 在我给它 FQDN 时执行 IPv6 请求 像下面的IP是:https://www.dslreports.com/whatismyip

from sys import version_info
PY3K = version_info >= (3, 0)
if PY3K:
import urllib.request as urllib
else:
import urllib2 as urllib
url = None
opener = urllib.build_opener()
opener.addheaders = [('User-agent',
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")]
url = opener.open("http://[2607:fad0:3706:1::1000]/whatismyip", timeout=3)
content = url.read()

我终于解决了我的问题。不是以最优雅的方式,但它对我有用。

阅读后:

强制请求使用 IPv4/IPv6 和 Python urllib2 强制 IPv4

我决定进行DNS查找,只需发送带有FQDN的主机标头即可获取内容。(虚拟主机需要主机标头(

这是丑陋的片段:

# Ugly hack to get either IPv4 or IPv6 response from server
parsed_uri = urlparse(server)
fqdn = "{uri.netloc}".format(uri=parsed_uri)
scheme = "{uri.scheme}".format(uri=parsed_uri)
path = "{uri.path}".format(uri=parsed_uri)
try:
ipVersion = ip_kind(fqdn[1:-1])
ip = fqdn
except ValueError:
addrs = socket.getaddrinfo(fqdn, 80)
if haveIPv6:
ipv6_addrs = [addr[4][0] for addr in addrs if addr[0] == socket.AF_INET6]
ip = "[" + ipv6_addrs[0] + "]"
else:
ipv4_addrs = [addr[4][0] for addr in addrs if addr[0] == socket.AF_INET]
ip = ipv4_addrs[0]
server = "{}://{}{}".format(scheme, ip, path)
url = urllib.Request(server, None, {'User-agent' : 'Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5'})
# Next line adds the host header
url.host = fqdn
content = urllib.urlopen(url).read()

这远非理想,它可能更干净,但它对我有用。

它在这里实现:https://github.com/SteveClement/ipgetter/tree/IPv6 这只会通过一个服务器列表,这些服务器返回您的边界网关 IP,现在也在 IPv6 中。

[更新:由于问题已更新,关于 Python 2/Python 3 的这一行不再有效]

首先,你似乎使用了Python 2。这很重要,因为 urllib 模块在 Python 3 中被拆分为多个部分并重命名。

其次,你的代码片段似乎不正确:build_opener不是urllib可用的函数。它与urllib2一起可用。

因此,我假设您的代码实际上是以下代码:

import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-agent',
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")]
url = opener.open("http://www.dslreports.com/whatismyip", timeout=3)

如果您的 DNS 解析程序正确处理 IPv6 资源记录,并且您的操作系统是使用双堆栈 IPv4/IPv6 或仅单 IPv6 堆栈构建的,并且您有正确的 IPv6 网络路径 dslreports.com,则此 Python 程序将使用 IPv6 连接到 www.dslreports.com。因此,没有必要说服python执行IPv6请求。

最新更新