69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
import re
|
||
import logging
|
||
import socket
|
||
from urllib import request, error, parse
|
||
|
||
# 匹配合法 IP 地址
|
||
regex_ip = re.compile(
|
||
r"\D*("
|
||
+ r"(?:1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\."
|
||
+ r"(?:1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\."
|
||
+ r"(?:1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\."
|
||
+ r"(?:1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)"
|
||
+ r")\D*")
|
||
|
||
# 增强鲁棒性,用多种方式获取 IP
|
||
def get_ip():
|
||
return (get_ip_by_ipip()
|
||
or get_ip_by_httpbin()
|
||
or get_ip_by_httpbin_direct_1()
|
||
or get_ip_by_httpbin_direct_2() )
|
||
|
||
# 这几个函数会在 DNS 遭受污染时失效
|
||
def get_ip_by_ipip():
|
||
url = 'http://myip.ipip.net/'
|
||
try:
|
||
resp = request.urlopen(url=url, timeout=10).read()
|
||
return regex_ip.match(resp.decode("utf-8")).group(1)
|
||
except Exception as e:
|
||
logging.warning("get_ip_by_ipip FAILED, error: %s", str(e))
|
||
return None
|
||
|
||
def get_ip_by_httpbin():
|
||
url = 'http://www.httpbin.org/ip'
|
||
try:
|
||
resp = request.urlopen(url=url, timeout=10).read()
|
||
return regex_ip.match(resp.decode("utf-8")).group(1)
|
||
except Exception as e:
|
||
logging.warning("get_ip_by_httpbin FAILED, error: %s", str(e))
|
||
return None
|
||
|
||
# 这个函数可以在本地 DNS 遭受污染的时候获取到IP
|
||
# 如需模拟DNS污染,可以在HOSTS文件里加入 127.0.0.1 www.httpbin.org
|
||
def get_ip_by_httpbin_direct_1():
|
||
url = 'http://52.5.182.176/ip'
|
||
try:
|
||
req = request.Request(url=url, method='GET', headers={'Host': 'www.httpbin.org'})
|
||
resp = request.urlopen(req).read()
|
||
return regex_ip.match(resp.decode("utf-8")).group(1)
|
||
except Exception as e:
|
||
logging.warning("get_ip_by_httpbin_direct_1 FAILED, error: %s", str(e))
|
||
return None
|
||
|
||
def get_ip_by_httpbin_direct_2():
|
||
url = 'http://52.44.230.61/ip'
|
||
try:
|
||
req = request.Request(url=url, method='GET', headers={'Host': 'www.httpbin.org'})
|
||
resp = request.urlopen(req).read()
|
||
return regex_ip.match(resp.decode("utf-8")).group(1)
|
||
except Exception as e:
|
||
logging.warning("get_ip_by_httpbin_direct_2 FAILED, error: %s", str(e))
|
||
return None
|
||
|
||
|
||
# 测试
|
||
if __name__ == '__main__':
|
||
print(get_ip() )
|
||
print(get_ip_by_ipip() )
|
||
print(get_ip_by_httpbin() )
|
||
print(get_ip_by_httpbin_direct_1() ) |