源码
import tkinter as tk import pandas as pd import os,configparser,base64,webbrowser,requests,threading from tkinter import ttk from tkinter import messagebox class PyWinDesign: def __init__(self, 启动窗口): self.启动窗口 = 启动窗口 self.启动窗口.title('FOFA 高级搜索小工具') self.启动窗口.resizable(width=False, height=False) screenwidth = self.启动窗口.winfo_screenwidth() screenheight = self.启动窗口.winfo_screenheight() size = '%dx%d+%d+%d' % (891, 693, (screenwidth - 891) / 2, (screenheight - 693) / 2) self.启动窗口.geometry(size) self.标签1_标题 = tk.StringVar() self.标签1_标题.set('语法:') self.标签1 = ttk.Label(self.启动窗口,textvariable=self.标签1_标题,anchor=tk.W) self.标签1.place(x=27,y=21,width=38,height=32) self.编辑框1_内容 = tk.StringVar() self.编辑框1_内容.set('') self.编辑框1 = ttk.Entry(self.启动窗口,textvariable=self.编辑框1_内容,justify=tk.LEFT) self.编辑框1.place(x=71,y=21,width=561,height=32) self.按钮1_标题 = tk.StringVar() self.按钮1_标题.set('查询') self.按钮1 = ttk.Button(self.启动窗口,textvariable=self.按钮1_标题) self.按钮1.bind('<Button-1>',self.查询按钮事件) self.按钮1.place(x=685,y=21,width=80,height=32) self.按钮2_标题 = tk.StringVar() self.按钮2_标题.set('导出') self.按钮2 = ttk.Button(self.启动窗口,textvariable=self.按钮2_标题) self.按钮2.bind('<Button-1>',self.导出按钮事件) self.按钮2.place(x=784,y=21,width=80,height=32) self.标签2_标题 = tk.StringVar() self.标签2_标题.set('状态:') self.标签2 = ttk.Label(self.启动窗口,textvariable=self.标签2_标题,anchor=tk.W) self.标签2.place(x=27,y=69,width=37,height=24) self.标签3_标题 = tk.StringVar() self.标签3_标题.set('等待开始') self.标签3 = tk.Label(self.启动窗口,textvariable=self.标签3_标题,anchor=tk.W,fg='red') self.标签3.place(x=70,y=69,width=265,height=24) self.超级列表框1_滚动条_纵 = ttk.Scrollbar(self.启动窗口) self.超级列表框1_滚动条_纵.place(x=863,y=100,width=18,height=565) self.超级列表框1 = ttk.Treeview(self.启动窗口,show='headings',columns=('URL','标题','IP','端口'),yscrollcommand=self.超级列表框1_滚动条_纵.set,) self.超级列表框1.column('URL', width=200,anchor='w') self.超级列表框1.column('标题', width=200,anchor='w') self.超级列表框1.column('IP', width=100,anchor='center') self.超级列表框1.column('端口', width=50,anchor='center') self.超级列表框1.heading('URL', text='URL',anchor='center') self.超级列表框1.heading('标题', text='标题',anchor='center') self.超级列表框1.heading('IP', text='IP',anchor='center') self.超级列表框1.heading('端口', text='端口',anchor='center') self.超级列表框1_滚动条_纵.config(command=self.超级列表框1.yview) self.超级列表框1.bind('<ButtonRelease-1>', self.表项单机) self.超级列表框1.place(x=27,y=98,width=837,height=565) self.标签4_标题 = tk.StringVar() self.标签4_标题.set('Blog:') self.标签4 = tk.Label(self.启动窗口,textvariable=self.标签4_标题,anchor=tk.W) self.标签4.place(x=735,y=664,width=33,height=26) self.标签5_标题 = tk.StringVar() self.标签5_标题.set('www.mrwu.red') self.标签5 = tk.Label(self.启动窗口,textvariable=self.标签5_标题,anchor=tk.W,fg='#0000FF') self.标签5.bind('<Button-1>',self.标签事件) self.标签5.place(x=774,y=664,width=103,height=26) #全局变量定义 global cf cf = configparser.ConfigParser() #配置文件创建 def api_if(): config = os.path.exists('config.ini') if config != 1: cf.add_section("API") cf.set("API", "email",'88888@qq.com')#fofa 账号 cf.set("API", "key",'232132132123')#fofa key cf.set("API", "size",'10000')#查询条数 高级会员最高一万条 with open("config.ini","w+") as f: cf.write(f) #配置信息调用 def api(self): config = os.path.exists('config.ini') if config == 1: cf.read("config.ini") email = cf.get("API", "email") key = cf.get("API", "key") size = cf.get("API", "size") return "email=%s&key=%s&size=%s" %(email,key,size) #标签事件 def 标签事件(self,event): webbrowser.open('https://www.mrwu.red') #导出数据线程 def 导出数据线程(self): column_a_list = [] column_b_list = [] column_c_list = [] column_d_list = [] for child in self.超级列表框1.get_children(): column_a_list.append(self.超级列表框1.item(child)["values"][0]) column_b_list.append(self.超级列表框1.item(child)["values"][1]) column_c_list.append(self.超级列表框1.item(child)["values"][2]) column_d_list.append(self.超级列表框1.item(child)["values"][3]) full_treeview_data_dict = {'URL': column_a_list, '标题': column_b_list, 'IP': column_c_list, '端口': column_d_list,} treeview_df = pd.DataFrame.from_dict(full_treeview_data_dict) treeview_df.to_csv("data.csv") messagebox.showinfo("提示","导出完成,查看工具目录下") #导出数据线程 def 导出按钮事件(self,event): try: save = threading.Thread(target=self.导出数据线程,name="导出数据") except: messagebox.showinfo("提示","出现未知异常") save.start() #列表删除线程 def 列表删除线程(self): items = self.超级列表框1.get_children() [self.超级列表框1.delete(item) for item in items] #查询线程函数 def 查询线程函数(self): self.标签3_标题.set('准备中.....') api = self.api() q = base64.encodebytes(self.编辑框1_内容.get().encode()) url = 'https://fofa.so/api/v1/search/all?%s&fields=host,title,ip,port&qbase64=%s' % (api,q.decode()) html = requests.get(url) data = html.json() try: #fofa 的错误返回好像不太统一,有点混乱,所以只能写成这吊样了 if data.get('error') ==False: self.标签3_标题.set('查询中.....') data = data['results'] for x in data: self.超级列表框1.insert('', 'end', values=[x[0],x[1],x[2],x[3]]) root.update() self.标签3_标题.set('查询完成') elif data.get('errmsg') =='401 Unauthorized, make sure 1.email and apikey is correct 2.FOFA coin is enough.': messagebox.showinfo("提示","API 信息有误") self.标签3_标题.set('等待开始') elif data.get('errmsg') =='Daily data processing limit exceeded (9000/10000)!': messagebox.showinfo("提示","已经超出每天的数据处理限制") self.标签3_标题.set('等待开始') elif data.get('errmsg') =='Only one task can be run at a time!': messagebox.showinfo("提示","每次只能运行一个任务") self.标签3_标题.set('等待开始') elif data.get('errmsg') =='401 Unauthorized, make sure email and apikey is correct.': messagebox.showinfo("提示","API 信息有误") self.标签3_标题.set('等待开始') elif data.get('errmsg') =='Query invalid!': messagebox.showinfo("提示","查询语法不能为空!") self.标签3_标题.set('等待开始') elif data.get('errmsg') =='FOFA coin is not enough!': messagebox.showinfo("提示","F币不足") self.标签3_标题.set('等待开始') elif data.get('errmsg') =='Internal Server Error!': messagebox.showinfo("提示","服务器异常") self.标签3_标题.set('等待开始') except: print('error') #查询按钮事件 def 查询按钮事件(self,event): # 创建线程 try: d = threading.Thread(target=self.列表删除线程,name="列表删除") t = threading.Thread(target=self.查询线程函数,name="查询线程") except: messagebox.showinfo("提示","出现未知异常") d.start() t.start() def 表项单机(self,event): item_text = [] for x in self.超级列表框1.selection(): item_text = self.超级列表框1.item(x)["values"][0] if "http" in item_text: webbrowser.open(item_text) print(item_text) else: item_text = "http://"+item_text webbrowser.open(item_text) print(item_text) if __name__ == '__main__': PyWinDesign.api_if() root = tk.Tk() app = PyWinDesign(root) root.mainloop()
打包好的
链接:https://share.weiyun.com/5WaLbxib
密码:egm48y
说明
工具没有内置账号,初次使用需要打开工具然后在修改生成的 config.ini 配置文件中的账号和key,最后一项是搜索条数
结尾
上次的发帖让我明白 PHP 真的不适合写工具,于是最近几天疯狂学习 python ,几天练手也成功写出几个小玩意
发这些脚本文章只是单纯的记录以及希望能有师傅指出代码中的不足之处,我肯定我代码中很多地方应该有更好的写法,希望能得到师傅们的指点
这个小脚本,已知的一个问题是 查询线程函数 中的 if 判断,会出现异常,最开始是因为 if 判断的问题,后面发现还会因为数据的格式问题出现异常,搞不懂。。。
工具有时候会因为数据中的一些字符导致中断,我不知道如何实现这种数据插入出现异常后继续插入的能力,查阅了很多资料无果,只能留给师傅们了
最后,是因为我中文命名的问题吗?为什么 Python 打包 EXE 体积能这么大?why?难道是因为模块太多?还是 Python 真的不适合界面? 害....
本文作者为Mr.Wu,转载请注明,尊守博主劳动成果!
由于经常折腾代码,可能会导致个别文章内容显示错位或者别的 BUG 影响阅读; 如发现请在该文章下留言告知于我,thank you !
来看看大佬