
域名和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').text
else:
key_name=item_tr.find(name='th').text
key_value=item_tr.find(name='td').text
ret_result[key_name]=key_value
addchinafuWhoisInfo2DB(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_result
def 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_dics
def 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/'+ip
ipinfo = {}
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/'+ip
ipinfo={}
try:
req_return=requests.get(api_url)
if req_return.status_code==200:
ipinfo=json.loads(req_return.text)
ipinfo['ip'] = ip
ipinfo['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.geoLiteDBdir
with geoip2.database.Reader(dbdir) as reader:
response = reader.city(ip)
ipinfo['ip'] =ip
ipinfo['country'] = response.country.names['zh-CN']
ipinfo['region'] =''
ipinfo['city']=response.city.name
ipinfo['org'] =''
ipinfo['loc'] = str(response.location.latitude)+','+str(response.location.longitude)
ipinfo['timezone'] = response.location.time_zone
ipinfo['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=development2)实现读取配置数据
通过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,'GeoLite2GeoLite2-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')
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
DEBUG=True
SQLALCHEMY_DATAbase_URI = os.getenv('DEV_DATAbase_URI')
class TestingConfig(Config):
TESTING=True
SQLALCHEMY_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() }}
{% endblock %}
{% block body %}
{% block navbar %}
InfoCol欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)