前段时间结合zoomeye的开发文档做了个简易的信息搜集工具ThunderSearch【项目地址 / 博客地址】,这次来讲讲具体的实现原理和开发思路

首先要能看懂开发文档,https://www.zoomeye.org/doc#user,上面介绍了一些api的使用。我们只需要调用我们想要的api就可以获取到想要的数据。

1. 登陆

根据文档,登陆方式分为两种,api-key账号/密码,我这里使用了账号密码登陆的方式,主要是获取api-key需要登陆到网页比较麻烦。登陆的目的是为了拿到access-token,在后期的api调用过程中需要将其作为请求头发送。我们先来看access-token的获取。

文档中使用curl制造http请求,在python中可以使用requests

import requests
import json
url = "https://api.zoomeye.org/user/login"
login_info = {
"username" : "xxxxx",
"password" : "xxxxx"
}
encoded_data = json.dumps(login_info)
resp = requests.post(url,encoded_data)
access_token = resp.json()['access_token']
print(access_token)

这里需要注意的是发送的data数据必须是json格式,因此需要把字典格式的info进行一个转化

再通过resp.jgon()['access_token']就能拿到token数据了。

在这个token前加上JWT(空格)作为Authorization提交。

headers = {
'Authorization':'JWT ' + access_token
}

2.调用api

以主机设备搜索为例

请求的url为https://api.zoomeye.org/host/search,请求方式为GET,四个参数中query(查询语句)为必填项

那么就可以创造如下函数

def host_search(query, page):       # 主机设备搜索
url = f'https://api.zoomeye.org/host/search?query={query}&page={page}&sub_type=v4&facets=app,os'
matches = requests.get(url, headers=headers).json()

文档中提供的返回json数据样例如下:(在上面的例子中就是matches)

{ "matches": [ {
"geoinfo": {
"asn": 45261,
"city": {
"names": {
"en": "Brisbane",
"zh-CN": "\u5e03\u91cc\u65af\u73ed"
}
},
"continent": {
"code": "OC",
"names": {
"en": "Oceania",
"zh-CN": "\u5927\u6d0b\u6d32"
}
},
"country": {
"code": "AU",
"names": {
"en": "Australia",
"zh-CN": "\u6fb3\u5927\u5229\u4e9a"
}
},
"location": {
"lat": -27.471,
"lon": 153.0243
}
},
"ip": "192.168.1.1",
"portinfo": {
"app": "",
"banner": "+OK Hello there.\r\n-ERR Invalid command.\r\n\n",
"device": "",
"extrainfo": "",
"hostname": "",
"os": "",
"port": 110,
"service": "",
"version": ""
},
"timestamp": "2016-03-09T16:14:04"
}, ... ...],
"facets": {
},
"total": 28731397
}

按照如下方式就可以拿到数据了

for each in matches['matches']:
ip = each['ip']
port = each['portinfo']['port']
country = each['geoinfo']['country']['names']['en']
os = each['portinfo']['os']
hostname = each['portinfo']['hostname']


3. 图形化

这里主要使用到了tkinter。按照如下通过面向对象的方式就能建立一个基础的GUI界面

from tkinter import *
class Application(Frame):
def __init__(self,master):
super().__init__(master)
self.master=master
self.createWidget()
self.pack() def createWidget(self):
pass if __name__=="__main__":
root = Tk()
root.title("TEST")
root.geometry('400x300+200+100')
Application(root)
root.mainloop()

4. 整合

结合多线程并发技术,最终能够实现ThunderSearch这样一个小公举


5. 总结

整体难度并不大,主要是GUI库tkinter的使用和读懂api开发文档、结合多线程并发的综合练习。

另外在tkinter的开发中遇到了一个问题,mainloop事件中的任何一个循环都要等待其结束之后主组件才会进行刷新,刷新前会一直卡住呈现假死状态。查遍S.O.,基本方法有每执行一次循环刷新界面,或者使用master等,但不能很好的解决问题,尤其是在复杂的多线程的多个循环同时执行的情况下就不好用了。

我这里是开了一个守护子线程去跑每个模块,这样和组件的mainloop事件就不冲突了,也能很好的上线程池。但总觉得有些不太好,希望有哪位懂的师傅能指点一下。

最新文章

  1. 本地项目上传到GitHub
  2. JavaScript基础知识汇总
  3. 详解SPI中的极性CPOL和相位CPHA
  4. Tesseract-OCR引擎 入门
  5. 【springBoot】springBoot集成redis的key,value序列化的相关问题
  6. jsch ssh服务器调用Linux命令或脚本的小问题
  7. 讲解DLL内容的比较详细的站点
  8. 小黑的镇魂曲(HDU2155:贪心+dfs+奇葩解法)
  9. window的cmd窗口运行git
  10. 二维树状数组(HD2642)
  11. Windows PHone 8 获取硬件信息
  12. spring简单笔记
  13. python3 Django集成Ueditor富文本编辑器
  14. [转载]Oracle Golden Gate - 概念和机制 (ogg)
  15. springboot启动配置原理之一(创建SpringApplication对象)
  16. Python使用np.c_和np.r_实现数组转换成矩阵
  17. ViewPager PagerAdapter not updating the View
  18. INTEST/EXTEST SCAN
  19. java 中的同步机制
  20. CentOS.56安装Redis监控工具RedisLive

热门文章

  1. 【LeetCode】56. Merge Intervals 解题报告(Python & C++ & Java)
  2. 【LeetCode】398. Random Pick Index 解题报告(Python & C++)
  3. 1678 lyk与gcd
  4. java泛型中<?>和<T>
  5. 第四十九个知识点:描述在IPsec和TLS后的基本想法
  6. TensorFlow.NET机器学习入门【7】采用卷积神经网络(CNN)处理Fashion-MNIST
  7. <数据结构>XDOJ261.理解哈夫曼树
  8. Error: Cannot find module '@dcloudio/uni-cli-i18n' 解决方案
  9. tcpdump统计http请求并导出URL文本
  10. Springboot+Javamail实现邮件发送