找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 265|回复: 3

获取公网IP地址工具

[复制链接]

34

主题

0

回帖

296

积分

管理员

积分
296

最佳新人热心会员湖北省RedHat高手

发表于 2025-5-16 08:51 | 显示全部楼层 |阅读模式
(1)准备好全套Python环境(安装好Python和PyCharm两款软件,并配置好环境变量)
(2)通过PyCharm开始写获取公网IP地址的Python代码了

[Python] 纯文本查看 复制代码
import os
import sys
import json
import logging
import pystray
import requests
import threading
import configparser
import tkinter as tk
from PIL import Image
from tkinter import simpledialog, colorchooser,Menu
CONFIG_PATH = os.path.expanduser('~/.ipmonitor.ini')

class get_ip_address:
    def __init__(self):
        url = 'http://whois.pconline.com.cn/ipJson.jsp?json=true'
        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0'}
        response = requests.get(url = url,headers = headers,timeout = 8)
        data = json.loads(response.text)
        self.ltxit_ip = data['ip']
        self.ltxit_local = data['addr']

class TransparentMonitor(tk.Tk):
    def __init__(self):
        super().__init__()
        self.detector = get_ip_address()
        self.overrideredirect(True)
        self.attributes('-alpha',0.85)
        self.configure(bg='#000000')
        self.wm_attributes('-transparentcolor','#000000')
        self.create_tray_icon()  # 新增方法
        self.create_widgets()
        self.load_config()
        self.context_menu = Menu(self,tearoff=0)
        self.context_menu.add_command(label = "修改显示的字体颜色",command = self.choose_font_color)
        self.context_menu.add_command(label = "修改显示的位置",command = self.set_custom_position)
        self.bind("<Button-3>",self.show_context_menu)
        self.update_display()
        self.after(300000,self.update_display)

    def create_tray_icon(self):
        def resource_path(relative_path):
            """ 开发/打包环境通用资源路径获取 """
            if getattr(sys,'frozen', False):
                base_path = getattr(sys,'_MEIPASS',os.path.dirname(sys.executable))
            else:
                base_path = os.path.dirname(os.path.abspath(__file__))
            return os.path.join(base_path,relative_path)

        icon_path = resource_path('favicon.ico')
        image = Image.open(icon_path)  # 需准备16x16像素的PNG/ICO文件
        menu = pystray.Menu(pystray.MenuItem("修改显示的字体颜色",self.choose_font_color),pystray.MenuItem("修改显示的位置",self.set_custom_position),pystray.MenuItem("退出公网IP地址获取程序",self.safe_quit))
        self.tray_icon = pystray.Icon("IPMonitor",image,"公网IP地址获取程序", menu)
        threading.Thread(target=self.tray_icon.run).start()

    def update_display(self):
        ltxit_ip = self.detector.ltxit_ip
        ltxit_local = self.detector.ltxit_local
        display_text = '设备公网IP地址:{}\nIP地址归属:{}\n软件已申请版权保护 | 侵权必究\n联系邮箱:sunshine@vip.ltxit.com'.format(ltxit_ip,ltxit_local)
        self.display_label.config(text = display_text)
        self.after(300000,self.update_display)

    def create_widgets(self):
        self.display_label = tk.Label(self,font = ('Arial',12),bg = '#000000',fg = 'white')
        self.display_label.pack(pady=20)

    def show_context_menu(self, event):
        self.context_menu.post(event.x_root,event.y_root)

    def safe_quit(self):
        try:
            self.tray_icon.stop()
        except Exception as e:
            logging.error(f"托盘关闭失败: {str(e)}")
        finally:
            os._exit(0)

    def choose_font_color(self):
        color = colorchooser.askcolor()[1]
        if color:
            self.display_label.config(fg = color)
            self.save_config()

    def set_custom_position(self):
        """ 线程安全的坐标设置方法 """
        def show_dialog():
            self.deiconify() #确保主窗口可见(解决父窗口被隐藏的问题)
            new_x = simpledialog.askinteger("位置设置","X坐标:",parent = self,minvalue = 0,maxvalue = self.winfo_screenwidth()) #获取X坐标输入
            new_y = simpledialog.askinteger("位置设置","Y坐标:",parent = self,minvalue = 0,maxvalue = self.winfo_screenheight()) #获取Y坐标输入
            if new_x is not None and new_y is not None: #应用新坐标
                self.deiconify()  # 强制显示窗口[1](@ref)
                self.geometry(f"+{new_x}+{new_y}")
                self.lift()  # 确保窗口置顶[7](@ref)
                self.save_config()
        self.after(0,show_dialog) #在主线程执行对话框操作

    def load_config(self):
        config = configparser.ConfigParser()
        config.read(CONFIG_PATH)

        if config.has_section('POSITION'):
            x = config.getint('POSITION','x',fallback = 100)
            y = config.getint('POSITION','y',fallback = 100)
            self.geometry(f"+{x}+{y}")

        if config.has_section('DISPLAY'):
            font_color = config.get('DISPLAY','font_color',fallback = '#FFFFFF')
            self.display_label.config(fg = font_color)

    def save_config(self):
        config = configparser.ConfigParser()
        config['POSITION'] = {'x': self.winfo_x(),'y':self.winfo_y()}
        config['DISPLAY'] = {'font_color':self.display_label.cget('fg')}
        with open(CONFIG_PATH,'w') as f:
            config.write(f)

if __name__ == "__main__":
    app = TransparentMonitor().mainloop()

(3)上述代码在PyCharm运行没有问题后就可以通过pyinstaller命令将上面的Python代码打包成.exe文件了。
(4)通过pyinstaller命令将上面的Python代码打包成.exe文件文件之前,需要确保是在Python代码文件(.py文件)所在目录(直接在.py文件所在目录按住键盘Shift键,然后单击鼠标右键选择“在此处打开Powershell窗口”或使用cd命令进入到.py文件所在目录均可)运行pyinstaller命令

20250516092507005.jpg
最简单的程序可以直接使用“pyinstaller xxx.py”来完成打包,只不过这种简单的打包最后除了生成一个.exe文件外还有一个文件夹,这个文件夹里面是必要的库文件,后面运行.exe文件时必须带着库文件一起,否则是无法运行的。
可以看到我在pyinstaller和.py文件之间加了--onefile、--noconsole和--add-data三个参数,三个参数的作用如下:
--onefile:如参数名称的意思,就是将所有的文件(包括库文件)打包成一个.exe文件,加了此参数后最后生成的只有一个.exe文件。
--noconsole:同样如参数名称的意思,原本不加这个参数的话在运行.exe文件时会同时出现命令行窗口(console窗口),加了这个参数运行.exe文件时就不会再出现命令行窗口(console窗口)了。
--add-data:因为使用pyinstaller打包.py文件时,系统只会将.py文件打包,如果.py文件中引用了外部资源(例如:图片、音乐等),在使用pyinstaller打包.py文件时是不会将这些外部资源一起打包的,最后生成的.exe文件因为缺少这些资源自然是不能成功运行的,所以这个参数是的意思是将外部资源也进行打包。
(5)准备工作已做好,我们就直接使用“pyinstaller --onefile --noconsole --add-data "favicon.ico;." Public_Network_IP.py”命令开始打包了

[PowerShell] 纯文本查看 复制代码
pyinstaller --onefile --noconsole --add-data "favicon.ico;." Public_Network_IP.py

20250516092603006.jpg
注意:须保证favicon.ico文件与xxx.py文件处于统一目录,否则打包会报错,即使在打包时没问题后续运行生成的.exe文件时也是会报错的。
(6)待看到“completed successfully.”就表示已经打包完成,并给出了生成的.exe文件的位置。

20250516105026007.jpg
(7)打包完成后系统会自动在xxx.py文件所在目录生成“build”、“dist”两个文件夹以及“xxx.spec”文件,打开生成的.exe文件所在位置,就看到最终生成的文件了。
20250516105336008.jpg
至此完工了,拿着生成的.exe文件到其他电脑上运行看看吧。

favicon.ico

1.12 KB, 阅读权限: 30, 下载次数: 0, 下载积分: ITB -2

售价: 8 软妹币  [记录]  [购买]

托盘图标favicon.ico

评分

参与人数 2ITB +100 贡献值 +10 收起 理由
Happy + 50 + 5 原创性突出
SunShine + 50 + 5 知识掌握扎实

查看全部评分

19

主题

3

回帖

79

积分

管理员

积分
79

热心会员湖北省RedHat高手

发表于 2025-6-15 09:09 | 显示全部楼层
[Python] 纯文本查看 复制代码
import requests
import json

url = 'http://whois.pconline.com.cn/ipJson.jsp?json=true'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0'}
response = requests.get(url = url,headers = headers,timeout = 8)
data = json.loads(response.text)
ltxit_ip = data['ip']
ltxit_local = data['addr']
print('设备公网IP地址:{}'.format(ltxit_ip))
print('IP地址归属地:{}'.format(ltxit_local))

19

主题

3

回帖

79

积分

管理员

积分
79

热心会员湖北省RedHat高手

发表于 2025-6-15 09:32 | 显示全部楼层
[Python] 纯文本查看 复制代码
import requests

url = 'https://myip.ipip.net'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0'}
response = requests.get(url=url, headers=headers)
ltxit_ip = response.text.split(':')[1].split(' ')[0]
ltxit_local = response.text.split(':')[2].split('中国')[1].strip()
print('设备公网IP地址:{}'.format(ltxit_ip))
print('IP地址归属地:{}'.format(ltxit_local))

19

主题

3

回帖

79

积分

管理员

积分
79

热心会员湖北省RedHat高手

发表于 2025-6-15 09:47 | 显示全部楼层
[Python] 纯文本查看 复制代码
import requests

url = 'http://ip-api.com/json/?lang=zh-CN'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0'}
response = requests.get(url=url, headers=headers)
data = response.json()
ltxit_ip = data['query']
ltxit_local = data['regionName'] + '-' + data['city']
print('设备公网IP地址:{}'.format(ltxit_ip))
print('IP地址归属地:{}'.format(ltxit_local))

Archiver|手机版|小黑屋|LTXIT家园 ( 鄂ICP备2025089526号|鄂公网安备42110002000175号 )

GMT+8, 2025-8-3 01:14 , Processed in 0.232099 second(s), 28 queries .

Powered by LTXIT家园 X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表