使用python中的urllib获取带有FQDN的IPv6 URL

2024-06-23 19:52:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用urllib获取一个IPv6页面。 可以使用square-brack-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()

Tags: importinfourlversionas页面openerurllib
2条回答

[更新:这一行关于python2/python3不再有效,因为问题已经更新]

首先,您似乎使用了python2。这一点很重要,因为urllib模块在python3中被拆分为多个部分并重命名。在

其次,您的代码片段似乎不正确:build\u 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请求。在

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

阅读后:

Force requests to use IPv4 / IPv6Python urllib2 force IPv4

我决定做一个DNS查找,只发送一个带有FQDN的主机头来获取内容。(VHOST需要主机头)

下面是一段丑陋的片段:

# 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中。在

相关问题 更多 >

    热门问题