HTTP请求的问题Python的 - 使用请求模块
我需要检查,如果从URL域没有指向私有IP请求之前,并返回用于HTTP连接的IP获得IP地址。
这是我的测试脚本:
import ipaddress
import requests
import socket
import sys
from urllib.parse import urlparse
def get_ip(url):
hostname = socket.gethostbyname(urlparse(url).hostname)
print('IP: {}'.format(hostname))
if hostname:
return ipaddress.IPv4Address(hostname).is_private
def get_req(url):
private_ip = get_ip(url)
if not private_ip:
try:
with requests.Session() as s:
s.max_redirects = 5
r = s.get(url, timeout=5, stream=True)
return {'url': url, 'staus_code': r.status_code}
except requests.exceptions.RequestException:
return 'ERROR'
return 'Private IP'
if __name__ == '__main__':
print(get_req(sys.argv[1]))
如果域解析为IP地址繁殖,如果网站托管背后的CloudFlare这将无法正常工作,例如:
# python test.py http://example.com
IP: 104.31.65.106
{'staus_code': 200, 'url': 'http://exmaple.com'}
从tcpdump的一个片段:
22:21:51.833221 IP 1.2.3.4.54786 > 104.31.64.106.80: Flags [S], seq 902413592, win 29200, options [mss 1460,sackOK,TS val 252001723 ecr 0,nop,wscale 7], length 0
22:21:51.835313 IP 104.31.64.106.80 > 1.2.3.4.54786: Flags [S.], seq 2314392251, ack 902413593, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 10], length 0
22:21:51.835373 IP 1.2.3.4.54786 > 104.31.64.106.80: Flags [.], ack 1, win 229, length 0
该脚本在104.31.65.106
上进行了测试,但HTTP连接为作出104.31.64.106
我看到this线程,但我不会消耗响应主体,所以the connection won't be released和实际上我的版本的请求模块没有这些属性。
有没有一种方法来达到这与requests
模块或我必须使用另一个库,如urllib
或urliib3
?
澄清:如果尝试连接到专用网络地址,我只需要阻止该请求。如果有多个选项并且选择了公共地址,那很好。
为什么没有'rsp = requests.get(...,stream = True); rsp.raw._connection.sock.getpeername()'为你工作? – Flurin
好的,所以我只是测试它,我想我可以关闭try/except块中的连接,但它看起来像流只有在服务器启用了keep-alive的情况下才起作用,否则连接立即关闭,并且我得到'AttributeError:'NoneType'对象没有属性“getpeername”。我希望在请求发出前检查IP。 – HTF
为什么所有的shenanigans都带'request.sys()作为s'然后s = requests.Session()'?那只是替换你的配置会话,放下's = ...'行。 –