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 = ...'行。 –