tôi sử dụng phương pháp tương tự như https://stackoverflow.com/a/33046939/5059062, nhưng thay vì vá ra một phần trong socket
mà làm cho các yêu cầu DNS để nó chỉ không IPv6 hoặc IPv4, cho mỗi yêu cầu, có nghĩa là điều này có thể được sử dụng trong urllib
cũng hiệu quả như trong requests
.
Điều này có thể không tốt nếu chương trình của bạn cũng sử dụng các đường ống unix và những thứ khác, vì vậy tôi đôn đốc thận trọng với monkeypatching.
import requests
import socket
from unittest.mock import patch
import re
orig_getaddrinfo = socket.getaddrinfo
def getaddrinfoIPv6(host, port, family=0, type=0, proto=0, flags=0):
return orig_getaddrinfo(host=host, port=port, family=socket.AF_INET6, type=type, proto=proto, flags=flags)
def getaddrinfoIPv4(host, port, family=0, type=0, proto=0, flags=0):
return orig_getaddrinfo(host=host, port=port, family=socket.AF_INET, type=type, proto=proto, flags=flags)
with patch('socket.getaddrinfo', side_effect=getaddrinfoIPv6):
r = requests.get('http://ip6.me')
print('ipv6: '+re.search(r'\+3>(.*?)</',r.content.decode('utf-8')).group(1))
with patch('socket.getaddrinfo', side_effect=getaddrinfoIPv4):
r = requests.get('http://ip6.me')
print('ipv4: '+re.search(r'\+3>(.*?)</',r.content.decode('utf-8')).group(1))
và không requests
:
import urllib.request
import socket
from unittest.mock import patch
import re
orig_getaddrinfo = socket.getaddrinfo
def getaddrinfoIPv6(host, port, family=0, type=0, proto=0, flags=0):
return orig_getaddrinfo(host=host, port=port, family=socket.AF_INET6, type=type, proto=proto, flags=flags)
def getaddrinfoIPv4(host, port, family=0, type=0, proto=0, flags=0):
return orig_getaddrinfo(host=host, port=port, family=socket.AF_INET, type=type, proto=proto, flags=flags)
with patch('socket.getaddrinfo', side_effect=getaddrinfoIPv6):
r = urllib.request.urlopen('http://ip6.me')
print('ipv6: '+re.search(r'\+3>(.*?)</',r.read().decode('utf-8')).group(1))
with patch('socket.getaddrinfo', side_effect=getaddrinfoIPv4):
r = urllib.request.urlopen('http://ip6.me')
print('ipv4: '+re.search(r'\+3>(.*?)</',r.read().decode('utf-8')).group(1))
Tested trong 3.5.2
Rất tiếc, tôi vẫn nhận được câu trả lời IPv4. Tôi đã thử 'print (requests.get ('https://icanhazip.com') .text)'. – ominug
Thật không may, tôi không có quyền truy cập vào bất kỳ điều gì với ipv6 tại thời điểm này; Tôi đã thêm một tuyên bố in và một tuyên bố kết nối chỉ để đảm bảo rằng tôi đã không bỏ lỡ một cái gì đó với cách một đi về monkeypatching đối tượng HTTPConnection – Foon
Ok, tôi đã thử nó một lần nữa. Phương thức kết nối không được gọi. – ominug