python代码调用三方网站获取当前网络ip

        为了实现公司网路访问项目登录时免复杂校验的功能,需要获取公司网络的ip地址,但是公司没有购买固定ip,ip地址会动态变化。

        方案设计:

        1、项目中维护一个ip白名单列表,用于请求校验ip是否在白名单中。

        2、通过在公司机房允许python脚本,将获取到的ip地址通过http请求更新到项目中。

        python代码如下:
        获取当前ip为了防止失败,使用了三个不同的网站进行获取ip,当前一个失败时,会通过下一个网站获取ip,每个网站的返回格式都不一样,需要单独解析;

import time
from datetime import datetime

import requests
import schedule
import hashlib

# 获取公网IP,为了方式地址失效,使用了3个网站获取
def get_public_ip():
    ip = get_public_ip_1()
    if ip is None:
        ip = get_public_ip_2()

    if ip is None:
        ip = get_public_ip_3()

    return ip

# 第一种获取ip的方式
def get_public_ip_1():
    url = 'http://ipinfo.io/ip'
    try:
        response = requests.get(url, timeout=5)
        return response.text.strip()
    except:
        return None

# 第二种获取ip的方式
def get_public_ip_2():
    url = 'https://httpbin.org/ip'
    try:
        response = requests.get(url, timeout=5)
        data = response.json()
        return data.get('origin')
    except:
        return None

# 第三种获取ip的方式
def get_public_ip_3():
    url = 'https://v4.ident.me/json'
    try:
        response = requests.get(url, timeout=5)
        data = response.json()
        return data.get('ip').strip()
    except:
        return None


def update_ip_record_http_test(ip):
    # 测试环境地址
    url = 'http://xxxxxx'
    input_str = "ipAddr="+ ip
    # 步骤1:将字符串编码为字节数据(必须操作)
    byte_data = input_str.encode("utf-8")
    # 步骤2:计算MD5哈希值
    md5_hash = hashlib.md5(byte_data)
    # 步骤3:获取十六进制格式结果
    signature = md5_hash.hexdigest()
    try:
        headers = {"Content-Type": "application/json"}
        payload = {
            "ipAddr": ip,
            "signature": signature
        }
        response = requests.post(url, json=payload, headers=headers)
        text = response.text
        print(f"[{datetime.now()}] IP {ip}, test 更新结果: {text}")
        return None
    except:
        print(f"[{datetime.now()}] IP {ip}, test 更新异常")
        return None

def update_ip_record_http_prod(ip):
    # 生产环境地址
    url = 'https://xxxxxx'
    input_str = "ipAddr="+ ip
    # 步骤1:将字符串编码为字节数据(必须操作)
    byte_data = input_str.encode("utf-8")
    # 步骤2:计算MD5哈希值
    md5_hash = hashlib.md5(byte_data)
    # 步骤3:获取十六进制格式结果
    signature = md5_hash.hexdigest()
    try:
        headers = {"Content-Type": "application/json"}
        payload = {
            "ipAddr": ip,
            "signature": signature
        }
        response = requests.post(url, json=payload, headers=headers)
        text = response.text
        print(f"[{datetime.now()}] IP {ip}, prod 更新结果: {text}")
        return None
    except:
        print(f"[{datetime.now()}] IP {ip}, prod 更新异常")
        return None


# 定时任务
def scheduled_job():
    ip = get_public_ip()
    if ip is None:
        print("[警告] 无法获取公网IP")
    else:
        update_ip_record_http_test(ip)
        update_ip_record_http_prod(ip)


if __name__ == "__main__":
    # 立即执行一次
    scheduled_job()

    # 设置定时任务(每5分钟)
    schedule.every(5).minutes.do(scheduled_job)

    # 常驻运行
    try:
        while True:
            schedule.run_pending()
            time.sleep(1)
    except KeyboardInterrupt:
        print("\n监控已停止")

        可优化的点:

        1、http中的签名目前是md5简单处理,后续可以改为RSA。

        2、当三个网站都获取失败后,可以使用钉钉机器人发送告警信息,方便监控(钉钉群通过使用http接口发送消息-优快云博客)。

本地Python代码和Docker容器调用三方接口,相同参数加密内容和curl一致但响应不同,可能存在以下原因: ### 网络环境差异 - **代理设置**:本地环境和Docker容器的代理配置可能不同。若本地使用了代理,而Docker容器未配置相同代理,或者反之,会影响请求的路由和传输,导致三方接口响应不同。 - **网络延迟和丢包**:本地网络和Docker容器所在网络的稳定性有别。网络延迟、丢包等问题会使请求到达三方接口的间和完整性不同,从而影响响应结果。 - **IP地址限制**:三方接口可能对请求的IP地址有限制。若本地IP和Docker容器的IP处于不同网段或被三方接口区别对待,就会造成响应不一致。 ### 环境配置差异 - **Python版本和依赖库**:本地Python环境和Docker容器内的Python版本及依赖库版本可能不同。不同版本的加密库、HTTP请求库等在处理请求和加密可能存在细微差异,导致请求在传输和处理过程中产生不同。 - **系统环境变量**:本地和Docker容器的系统环境变量可能有差异,如区、字符编码等。这些环境变量可能会影响请求的编码、间戳等参数,进而影响三方接口的响应。 ### 请求头差异 - **User - Agent**:本地Python代码和Docker容器发送请求的User - Agent可能不同。三方接口可能根据User - Agent对请求进行不同处理,从而返回不同响应。 - **其他请求头**:如Accept、Accept - Encoding、Content - Type等请求头的差异,也可能使三方接口对请求的理解和处理方式不同。 ### 容器内部配置 - **容器资源限制**:Docker容器的资源(如CPU、内存、网络带宽等)可能受到限制,这会影响请求的处理速度和性能,导致与本地环境响应不同。 - **容器防火墙和安全策略**:容器内部的防火墙规则、安全策略等可能会对请求进行额外过滤或修改,影响请求的正常传输和响应。 ### 示例代码分析 以下是一个简单的Python代码示例,用于调用三方接口: ```python import requests import json url = 'https://example.com/api' data = {'param1': 'value1', 'param2': 'value2'} headers = { 'Content-Type': 'application/json' } response = requests.post(url, headers=headers, data=json.dumps(data)) print(response.text) ``` 在Docker容器中运行类似代码,需确保容器内的环境配置和请求参数与本地一致。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值