域名和IP地址信息是非常基础的情报信息,目前网上有很多网站都提供了域名信息的查询、IP地址及归属地的查询。本文通过Python Flask实现域名及IP情报信息的聚合网站。

因为域名和IP地址信息会有变化,为了减少接口压力,做了本地数据库的存储,新鲜度保存一周,每次查询先从本地数据库获取信息,如果本地库信息有并且没有超过一个星期就从本地库取,没有就从其他网站获取,并更新到本地库。

一、获取域名WHOIS信息

网上提供域名WHOIS信息查询的网站有很多,这里以http://whois.chinafu.com 为例实现WHOIS信息的查询和解析。

import requests
from bs4 import BeautifulSoup
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}def getwhoisinfobychinafu(domain):ret_result = {}result=getWhoisInfoFromDB(domain)if len(result)==0:whois_service_url = 'http://whois.chinafu.com/whois.php'post_data={"domain":domain}try:post_result=requests.post(whois_service_url,post_data)if post_result.status_code == 200:ret_str = post_result.content.decode('utf-8')soup = BeautifulSoup(ret_str, 'lxml')items_tr =soup.find(name='table',attrs={'class':'listtable'}).find_all(name='tr')for item_tr in items_tr:td_item=item_tr.find(name='td')if 'colspan' in td_item.attrs:key_name='详情'key_value=td_item.find(name='div',id='tab1').textelse:key_name=item_tr.find(name='th').textkey_value=item_tr.find(name='td').textret_result[key_name]=key_valueaddchinafuWhoisInfo2DB(ret_result)except Exception as r:print('未知错误 %s' % (r))#ret_result = json.dumps(ret_result, ensure_ascii=False)else:ret_result=result[0]return ret_resultdef getWhoisInfoFromDB(domainname):whoisInfos=db.session.execute('select * from whoisinfo where domain_name="%s" and updated_time > DATE_SUB(CURDATE(), INTERVAL 1 WEEK)' % domainname).fetchall()whoisInfo_dics=[]for whoisInfo in whoisInfos:chinafuwhoisinfo_dic=chinafuwhoisinfo2dic(whoisInfo)whoisInfo_dics.append(chinafuwhoisinfo_dic)return whoisInfo_dicsdef addchinafuWhoisInfo2DB(chinafuWhoisInfo_dic):chinafuWhois=WhoisInfo()chinafuWhois.domain_name=chinafuWhoisInfo_dic.get('域名DomainName')chinafuWhois.domain_status=chinafuWhoisInfo_dic.get('域名状态Domain Status','')chinafuWhois.registrar=chinafuWhoisInfo_dic.get('注册商Sponsoring Registrar','')chinafuWhois.name_server=chinafuWhoisInfo_dic.get('DNS 服务器Name Server','')chinafuWhois.registrar_creation_date=chinafuWhoisInfo_dic.get('注册日期Registration Date','')chinafuWhois.registrar_updated_date = chinafuWhoisInfo_dic.get('更新日期Update Date', '')chinafuWhois.registrar_expiry_date = chinafuWhoisInfo_dic.get('到期日期Expiration Date', '')chinafuWhois.detail=chinafuWhoisInfo_dic.get('详情', '')[0:10000]chinafuWhois.source = '中国福网'db.session.execute('delete from whoisinfo where domain_name="%s" and source="%s"' % (chinafuWhoisInfo_dic.get('域名DomainName'), chinafuWhois.source))db.session.add(chinafuWhois)db.session.commit()

这里为了减少直接从其他网站获取WHOIS信息的压力,做了本地数据库的存储,每次先从本地数据库取WHOIS的信息,如果本地库信息有并且没有超过一个星期就从本地库取,没有就从其他网站获取,并更新到本地库。这里getWhoisInfoFromDB实现了取新鲜度为1周的数据,addchinafuWhoisInfo2DB实现将获取的信息保存到本地数据库。

二、根据域名解析出IP

根据域名解析出IP代码:

def getIPbyDomain(domain):addr=''try:myaddr = socket.getaddrinfo(domain, 'http')addr=myaddr[0][4][0]except Exception as e:print(e)return addr

三、获取IP信息

获取IP信息的API接口也有很多,有淘宝的 https://ip.taobao.com/outGetIpInfo 、IPINFO http://ipinfo.io/、IPAPI http://ip-api.com/ 以及GeoLite2离线库等。

从淘宝IP获取IP信息

def getipinfobytaobao(ip):taobaoIp_url = 'https://ip.taobao.com/outGetIpInfo'post_data={"ip":ip,"accessKey":"alibaba-inc"}ret_ipinfo= {}try:return_data=requests.post(taobaoIp_url,post_data)#其中返回数据中code的值的含义为,0:成功,1:服务器异常,2:请求参数异常,3:服务器繁忙,4:个人qps超出return_json=json.loads(return_data.text)if return_json['code']==0:ret_ipinfo['ip']=return_json['data']['ip']ret_ipinfo['country']=return_json['data']['country']ret_ipinfo['region']=return_json['data']['region']ret_ipinfo['org']=''ret_ipinfo['city'] = return_json['data']['city']ret_ipinfo['isp']=return_json['data']['isp']ret_ipinfo['loc'] = ''ret_ipinfo['timezone'] = ''ret_ipinfo['source']='淘宝IP'addIPInfo2DB(ret_ipinfo)except Exception as e:print('未知错误 %s' % (e))return ret_ipinfo

从ipinfo.io获取IP信息

def getipinfobyipinfo(ip):api_url='http://ipinfo.io/'+ipipinfo = {}try:req_return = requests.get(api_url)if req_return.status_code == 200:ipinfo = json.loads(req_return.text)ipinfo['source']='ipinfo.io'addIPInfo2DB(ipinfo)except Exception as e:print('未知错误 %s' % (e))return ipinfo

从ip-api.com获取IP信息

def getipinfobyipapi(ip):api_url='http://ip-api.com/json/'+ipipinfo={}try:req_return=requests.get(api_url)if req_return.status_code==200:ipinfo=json.loads(req_return.text)ipinfo['ip'] = ipipinfo['source'] = 'ip-api.com'ipinfo['loc'] = str(ipinfo['lat'])+','+str(ipinfo['lon'])addIPInfo2DB(ipinfo)except Exception as e:print('未知错误 %s' % (e))return ipinfo

从GeoLite离线库获取IP信息

如何获取GeoLite离线库及如何读取,详见:http://xiejava.ishareread.com/posts/2c5697c0/

def getipinfobygeoip2(ip):ipinfo={}dbdir=Config.geoLiteDBdirwith geoip2.database.Reader(dbdir) as reader:response = reader.city(ip)ipinfo['ip'] =ipipinfo['country'] = response.country.names['zh-CN']ipinfo['region'] =''ipinfo['city']=response.city.nameipinfo['org'] =''ipinfo['loc'] = str(response.location.latitude)+','+str(response.location.longitude)ipinfo['timezone'] = response.location.time_zoneipinfo['source'] = 'GeoIP'addIPInfo2DB(ipinfo)return ipinfo

四、搭建一个FLASK Web应用来查询聚合的域名、IP情报信息

1、FLASK Web应用的工程组织

2、配置数据及读取配置数据

1)配置数据

配置数据分别放在.env及.flaskenv中,其中.env放的是工程中用到的数据库链接等比较私密的配置信息。.flaskenv放的是Flask运行环境的信息
.env的配置信息参考如下:

DEV_DATABASE_URI = 'mysql+pymysql://dbuser:yourpassword@127.0.0.1:3306/infocol_db_dev?charset=utf8'
TEST_DATABASE_URI = 'mysql+pymysql://dbuser:yourpassword@127.0.0.1:3306/infocol_db_test?charset=utf8'
PROD_DATABASE_URI = 'mysql+pymysql://dbuser:yourpassword@127.0.0.1:3306/infocol_db?charset=utf8'SQLALCHEMY_TRACK_MODIFICATIONS = True
SECRET_KEY=your secret key

.falskenv配置信息参考如下:

FLASK_ENV=development

2)实现读取配置数据

通过config.py实现配置数据的读取及管理

import os
from dotenv import load_dotenv
basedir=os.path.abspath(os.path.dirname(__file__))
flaskenv_path=os.path.join(basedir,'.flaskenv')
env_path=os.path.join(basedir,'.env')
if os.path.exists(flaskenv_path):load_dotenv(flaskenv_path)
if os.path.exists(env_path):load_dotenv(env_path)class Config:geoLiteDBdir=os.path.join(basedir,'GeoLite2\GeoLite2-City.mmdb')flaskenv = os.getenv('FLASK_ENV','development')SECRET_KEY=os.getenv('SECRET_KEY','123!@#')SQLALCHEMY_TRACK_MODIFICATIONS=os.getenv('SQLALCHEMY_TRACK_MODIFICATIONS')SQLALCHEMY_DATABASE_URI = os.getenv('DEV_DATABASE_URI')@staticmethoddef init_app(app):passclass DevelopmentConfig(Config):DEBUG=TrueSQLALCHEMY_DATABASE_URI = os.getenv('DEV_DATABASE_URI')class TestingConfig(Config):TESTING=TrueSQLALCHEMY_DATABASE_URI = os.getenv('TEST_DATABASE_URI')class ProductionConfig(Config):SQLALCHEMY_DATABASE_URI = os.getenv('PROD_DATABASE_URI')config={'development':DevelopmentConfig,'testing':TestingConfig,'production':ProductionConfig,'default':DevelopmentConfig
}

3、界面及路由

界面很简单就一个域名/IP的输入框,输入域名或IP后去查询相应的域名信息或IP信息显示到界面上。

界面用jinjia2的模板
index.html代码如下:

{% extends "bootstrap/base.html" %}
{% block title %}InfoCol{% endblock %}
{% block head %}{{ super() }}<style></style>
{% endblock %}
{% block body %}{% block navbar %}<div class="navbar navbar-inverse" role="navigation"><div class="container"><div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand" href="/">InfoCol</a></div><div class="navbar-collapse collapse"><ul class="nav navbar-nav"><li><a href="/">Home</a></li></ul></div></div></div>{% endblock %}{% block content %}<div class="container"><div class="page-header " ><form method="post" class="center-block"><div class="center-block" style="text-align:center">{{ form.hidden_tag() }}{{ form.name.label }}{{ form.name() }}{{ form.submit() }}</div></form></div><div>{% if whois_info %}<table class="table table-bordered"><tr><th colspan="2">{{ name }}的Whois信息</th></tr>{% for item in whois_info %}{% if item!='详情' %}<tr><td style="width: 20%">{{ item }}</td><td style="width: 80%">{{ whois_info[item] }}</td></tr>{% else %}<tr><td style="width: 20%"><a role="button" data-toggle="collapse" href="#collapseExample" aria-expanded="false" aria-controls="collapseExample">{{ item }}</a></td><td style="width: 80%"><div class="collapse" id="collapseExample"><div class="well">{{ whois_info[item] }}</div></div></td></tr>{% endif %}{% endfor %}</table>{% endif %}{% if ipinfos|length>0 %}<table class="table table-bordered"><tr><th>IP</th><th>国家/地区</th><th>省份</th><th>城市</th><th>机构</th><th>ISP</th><th>经纬度</th><th>来源</th></tr>{% for ipinfo in ipinfos %}<tr><td>{{ ipinfo['ip'] }}</td><td>{{ ipinfo['country'] }}</td><td>{{ ipinfo['region'] }}</td><td>{{ ipinfo['city'] }}</td><td>{{ ipinfo['org'] }}</td><td>{{ ipinfo['isp'] }}</td><td>{{ ipinfo['loc'] }}</td><td>{% if ipinfo['source']=='ipinfo.io' %}<a href="http://ipinfo.io/{{ ipinfo['ip'] }}" target="_blank">{{ ipinfo['source'] }}</a>{% elif ipinfo['source']=='ip-api.com'%}<a href="http://ip-api.com/json/{{ ipinfo['ip'] }}" target="_blank">{{ ipinfo['source'] }}</a>{% else %}{{ ipinfo['source'] }}{% endif %}</td></tr>{% endfor %}</table>{% endif %}</div></div>{% endblock %}
{% endblock %}

路由配置处理中实现了获取表单中的信息,并判断是域名还是IP如果是域名者获取whois信息,并根据域名获取IP信息。如果输入的是IP则获取IP信息,并反馈到页面上。

@index_bp.route('/',methods=['GET','POST'])
def index():name = ''ipinfos = []whois_info = ''form = InputForm()if form.validate_on_submit():name = form.name.dataif checkip(name):ipinfos = getipinfo(name)else:whois_info = getwhoisinfo(name)whois_ip = getIPbyDomain(name)if checkip(whois_ip):ipinfos = getipinfo(whois_ip)form.name.data = ''return render_template('index.html',form=form, name=name, ipinfos=ipinfos, whois_info=whois_info)

4、最终实现效果

至此通过Python快速实现了一个简单的域名、IP信息聚合网站


全部源代码:https://github.com/xiejava1018/infocollect

演示地址:http://test.ishareread.com/

博客:http://xiejava.ishareread.com/

Python快速实现一个域名、IP信息聚合网站相关推荐

  1. windows和Linux利用Python快速搭建一个网站

    windows和Linux利用Python快速搭建一个网站 一.windows 步骤1:安装Python3(自行百度) 步骤2:在cmd窗口输入ipconfig查看本机ip地址,IPV4那一行.如:1 ...

  2. 用python快速开发一个实用的socket服务器

    用python快速开发一个实用的socket服务器 - 吴尔平 - 博客园 用python快速开发一个实用的socket服务器 首先,要明白不是所有的socket服务都需要高性能.如果要求高性能,使用 ...

  3. python 快速读取图像宽高信息

    python 快速读取图像宽高信息 1. 背景 2. 方法 2.1 仅读取图像文件头部信息 2.2 采用特定 python 包读取 1. 背景 存在100w张JPG图像,需要获取它们的宽高信息.如果用 ...

  4. phpstudy一个域名配置两个网站(一个是thinkphp5,一个是原生php)

    phpstudy一个域名配置两个网站(一个是thinkphp5,一个是原生php) 一.总结 一句话总结:把原生php的网站直接放到thinkphp5的public目录下可以解决以stem.aaaa. ...

  5. 域名解析跳转到另一个域名_github建立静态网站,域名解析和跳转

    这篇博客源自博主的csdn博客 1.注册github账号,创建仓库 仓库名称可以是两种,仓库名称格式是http://user.github.io格式.如下图的http://dajun1234.gith ...

  6. 关于一个域名下如何更换网站

    说明:建立在有域名.服务器.两个网站的基础之上. 背景: 原来的网站采用的是微企点建站的方式,对于那种拖拉拽不懂编程的人用的,现在自己开发一个更为强大的功能性网站,想把这个新网站替换掉原来的网站,而且 ...

  7. ChatGPT-Next-Web: 使用Vercel快速部署一个属于自己的 ChatGPT 网站服务

    今天给大家推荐一个非常好用的开源项目:ChatGPT-Next-Web 这个开源项目可以做到一键免费部署你的私人 ChatGPT 网页应用.只需要部署到Vercel,使用Vercel绑定自己购买的域名 ...

  8. python快速部署一个服务器_Python加Shell快速部署集群

    最近痛感在集群里逐台部署ganglia, cacti这些监控的东西很麻烦,就写了个小程序去批量自动部署.原理是通过Python的pexpect用ssh去复制文件和执行系统命令,我用它来部署gangli ...

  9. 如何用Python快速实现一个垃圾分类APP【附带微信小程序】

    嗨害大家好鸭!我是小熊猫❤ 今天这篇文章主要介绍的是: 如何利用现有的工具来实现一个垃圾分类的应用 有什么python相关报错解答自己不会的.或者源码资料/模块安装/女装大佬精通技巧 都可以来这里:( ...

  10. python自动垃圾分类_现在垃圾都得分类,如何利用Python快速实现一个垃圾分类APP?...

    最近北京开始实行垃圾分类,导致大家对垃圾的研究热度突然涨高,垃圾们也纷纷表示从来没有获得过这么高的关注度.其实,上海市去年已经开始实行,网上已经有不少成熟的教程了,像什么<垃圾分类从入门到精通& ...

最新文章

  1. [20190113]四校联考
  2. 解决安装centos 7后Windows启动项丢失
  3. boost::geometry::cross_product用法的测试程序
  4. VS配置本地IIS以域名访问
  5. [BZOJ2616] SPOJ PERIODNI
  6. ReviewForJob——深度优先搜索的应用
  7. Compass.net
  8. DirectInput手柄在Windows环境下震动实现
  9. windows批处理 复制文件和文件夹子文件夹
  10. TOP100summit:【分享实录-猫眼电影】业务纵横捭阖背后的技术拆分与融合
  11. 乌镇世界互联网大会上,百度敲响了创新动能的“牛顿摆”
  12. 设置电脑保护视力的颜色
  13. 小米电视看普通电视台,只需几步就能轻松解锁
  14. 微信小程序wx.createInnerAudioContext使用方法
  15. 第三章 系统的时域分析
  16. 什么是工程建设的BLT模式
  17. ABAQUS UEL
  18. 【STM32L系列】+NUCLEO-L011K4体验资料
  19. 音乐专业又和计算机有关的吗,计算机音乐专业介绍
  20. 扫雷游戏9*9(详细到具体每一步)

热门文章

  1. 全国大学生英语竞赛【常考词汇】
  2. Python3中的md5加密
  3. CDLINUX——minidwep-gtk
  4. java需要知道哪些英语单词_70个学习JAVA必背的英语单词,了解下
  5. 微信小程序优购商城项目总结
  6. 按计算机应用领域来分 电子邮件属于,计算机考试题库和答案.doc
  7. mac系统如何修改默认打开方式
  8. Postman下载与安装操作步骤【超详细】
  9. 常用连接服务器的ssh工具
  10. cmd imp导入dmp文件_在cmd中怎么样导入dmp文件?