python使用在线API查询IP对应的地理位置信息实例


Posted in Python onJune 01, 2014

这篇文章中的内容是来源于去年我用美国的VPS搭建博客的初始阶段,那是有很多恶意访问,我就根据access log中的源IP来进行了很多统计,同时我也将访问量最高的恶意访问的源IP拿来查询其地理位置信息。所以,我就用到了根据IP查询地理位置信息的一些东西,现在将这方面积累的一点东西共享出来。

根据IP查询所在地、运营商等信息的一些API如下(根据我有限的一点经验):
1. 淘宝的API(推荐):http://ip.taobao.com/service/getIpInfo.php?ip=110.84.0.129
2. 国外freegeoip.net(推荐):http://freegeoip.net/json/110.84.0.129 这个还提供了经纬度信息(但不一定准)
3. 新浪的API:http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=110.84.0.129
4. 腾讯的网页查询:http://ip.qq.com/cgi-bin/searchip?searchip1=110.84.0.129
5. ip.cn的网页:http://www.ip.cn/index.php?ip=110.84.0.129
6. ip-api.com: http://ip-api.com/json/110.84.0.129 (看起来挺不错的,貌似直接返回中文城市信息,文档在 ip-api.com/docs/api:json)
7. http://www.locatorhq.com/ip-to-location-api/documentation.php (这个要注册才能使用,还没用过呢)

(第2个freegeoip.net的网站和IP数据的生成,代码在:https://github.com/fiorix/freegeoip)

为什么其中第4、5两个是网页查询也推荐了呢?是因为两方面原因,一是它们提供的信息比较准,二是使用了页面信息自动抓取(可能会用到我曾经写过的PhantomJS)也容易将其写到程序中成为API。

根据IP查询地理位置信息,我将其写成了一个较为通用的Python库(提供了前面提到的1、2、4、5等4种查询方式的API),可以根据IP查询到地域信息和ISP信息,具体代码见:
https://github.com/smilejay/python/blob/master/py2013/iplocation.py
注意其中对ip.cn网页的解析用到了webdriver和PhantomJS.

#!/usr/bin/python
# -*- coding: utf-8 -*-'''
Created on Oct 20, 2013
@summary: geography info about an IP address
@author: Jay <smile665@gmail.com> http://smilejay.com/
'''
import json, urllib2
import re
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
 
class location_freegeoip():
    '''
build the mapping of the ip address and its location.
the geo info is from <freegeoip.net>
'''
    def __init__(self, ip):
        '''
Constructor of location_freegeoip class
'''
        self.ip = ip
        self.api_format = 'json'
        self.api_url = 'http://freegeoip.net/%s/%s' % (self.api_format, self.ip)
    def get_geoinfo(self):
        """ get the geo info from the remote API.
return a dict about the location.
"""
        urlobj = urllib2.urlopen(self.api_url)
        data = urlobj.read()
        datadict = json.loads(data, encoding='utf-8')
# print datadict
        return datadict
    def get_country(self):
        key = 'country_name'
        datadict = self.get_geoinfo()
        return datadict[key]
    def get_region(self):
        key = 'region_name'
        datadict = self.get_geoinfo()
        return datadict[key]
    def get_city(self):
        key = 'city'
        datadict = self.get_geoinfo()
        return datadict[key]
class location_taobao():
    '''
build the mapping of the ip address and its location
the geo info is from Taobao
e.g. http://ip.taobao.com/service/getIpInfo.php?ip=112.111.184.63
The getIpInfo API from Taobao returns a JSON object.
'''
    def __init__(self, ip):
        self.ip = ip
        self.api_url = 'http://ip.taobao.com/service/getIpInfo.php?ip=%s' % self.ip
    def get_geoinfo(self):
        """ get the geo info from the remote API.
return a dict about the location.
"""
        urlobj = urllib2.urlopen(self.api_url)
        data = urlobj.read()
        datadict = json.loads(data, encoding='utf-8')
# print datadict
        return datadict['data']
    def get_country(self):
        key = u'country'
        datadict = self.get_geoinfo()
        return datadict[key]
    def get_region(self):
        key = 'region'
        datadict = self.get_geoinfo()
        return datadict[key]
    def get_city(self):
        key = 'city'
        datadict = self.get_geoinfo()
        return datadict[key]
    def get_isp(self):
        key = 'isp'
        datadict = self.get_geoinfo()
        return datadict[key]
 
class location_qq():
    '''
build the mapping of the ip address and its location.
the geo info is from Tencent.
Note: the content of the Tencent's API return page is encoded by 'gb2312'.
e.g. http://ip.qq.com/cgi-bin/searchip?searchip1=112.111.184.64
'''
    def __init__(self, ip):
        '''
Construction of location_ipdotcn class.
'''
        self.ip = ip
        self.api_url = 'http://ip.qq.com/cgi-bin/searchip?searchip1=%s' % ip
    def get_geoinfo(self):
        urlobj = urllib2.urlopen(self.api_url)
        data = urlobj.read().decode('gb2312').encode('utf8')
        pattern = re.compile(r'该IP所在地为:<span>(.+)</span>')
        m = re.search(pattern, data)
        if m != None:
            return m.group(1).split(' ')
        else:
            return None
    def get_region(self):
        return self.get_geoinfo()[0]
    def get_isp(self):
        return self.get_geoinfo()[1]
 
class location_ipdotcn():
    '''
build the mapping of the ip address and its location.
the geo info is from www.ip.cn
need to use PhantomJS to open the URL to render its JS
'''
    def __init__(self, ip):
        '''
Construction of location_ipdotcn class.
'''
        self.ip = ip
        self.api_url = 'http://www.ip.cn/%s' % ip
    def get_geoinfo(self):
        dcap = dict(DesiredCapabilities.PHANTOMJS)
        dcap["phantomjs.page.settings.userAgent"] = (
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/29.0 " )
        driver = webdriver.PhantomJS(executable_path='/usr/local/bin/phantomjs', desired_capabilities=dcap)
        driver.get(self.api_url)
        text = driver.find_element_by_xpath('//div[@id="result"]/div/p').text
        res = text.split('来自:')[1].split(' ')
        driver.quit()
        return res
    def get_region(self):
        return self.get_geoinfo()[0]
    def get_isp(self):
        return self.get_geoinfo()[1]
 
if __name__ == '__main__':
    ip = '110.84.0.129'
# iploc = location_taobao(ip)
# print iploc.get_geoinfo()
# print iploc.get_country()
# print iploc.get_region()
# print iploc.get_city()
# print iploc.get_isp()
# iploc = location_qq(ip)
    iploc = location_ipdotcn(ip)
# iploc.get_geoinfo()
    print iploc.get_region()
    print iploc.get_isp()
Python 相关文章推荐
用Python实现协同过滤的教程
Apr 08 Python
详解Tensorflow数据读取有三种方式(next_batch)
Feb 01 Python
Django在pycharm下修改默认启动端口的方法
Jul 26 Python
关于Pytorch的MLP模块实现方式
Jan 07 Python
Python 给下载文件显示进度条和下载时间的实现
Apr 02 Python
Python字符串格式化f-string多种功能实现
May 07 Python
pandas之分组groupby()的使用整理与总结
Jun 18 Python
浅谈matplotlib 绘制梯度下降求解过程
Jul 12 Python
python 利用opencv实现图像网络传输
Nov 12 Python
Selenium Webdriver元素定位的八种常用方式(小结)
Jan 13 Python
教你如何使用Python实现二叉树结构及三种遍历
Jun 18 Python
Python自动操作神器PyAutoGUI的使用教程
Jun 16 Python
pip 错误unused-command-line-argument-hard-error-in-future解决办法
Jun 01 #Python
2款Python内存检测工具介绍和使用方法
Jun 01 #Python
使用Python的Supervisor进行进程监控以及自动启动
May 29 #Python
python应用程序在windows下不出现cmd窗口的办法
May 29 #Python
python正则表达式re模块详细介绍
May 29 #Python
在python中的socket模块使用代理实例
May 29 #Python
python中stdout输出不缓存的设置方法
May 29 #Python
You might like
php class中self,parent,this的区别以及实例介绍
2013/04/24 PHP
PHP+Ajax实现的检测用户名功能简单示例
2019/02/12 PHP
YII2框架使用控制台命令的方法分析
2020/03/18 PHP
PHP数组基本用法与知识点总结
2020/06/02 PHP
原生js实现给指定元素的后面追加内容
2013/04/10 Javascript
JS脚本defer的作用示例介绍
2014/01/02 Javascript
JavaScript中的console.profile()函数详细介绍
2014/12/29 Javascript
js实现鼠标左右移动,图片也跟着移动效果
2017/01/25 Javascript
layui导航栏实现代码
2017/05/19 Javascript
JavaScript之json_动力节点Java学院整理
2017/06/29 Javascript
vue.js学习笔记之v-bind和v-on解析
2018/05/03 Javascript
Javascript 之封装(Package)
2018/09/14 Javascript
ajaxfileupload.js实现上传文件功能
2019/04/19 Javascript
javascript设计模式 ? 装饰模式原理与应用实例分析
2020/04/14 Javascript
解决vue项目input输入框双向绑定数据不实时生效问题
2020/08/05 Javascript
常用python数据类型转换函数总结
2014/03/11 Python
Python使用MD5加密字符串示例
2014/08/22 Python
详解用Python处理HTML转义字符的5种方式
2017/12/27 Python
在python中利用numpy求解多项式以及多项式拟合的方法
2019/07/03 Python
Python 转换文本编码实现解析
2019/08/27 Python
使用python切片实现二维数组复制示例
2019/11/26 Python
python中not、and和or的优先级与详细用法介绍
2020/11/03 Python
Python用Jira库来操作Jira
2020/12/28 Python
使用html5 canvas创建太空游戏的示例
2014/05/08 HTML / CSS
HTML5地理定位实例
2014/10/15 HTML / CSS
欧洲最大的笔和书写专家:The Pen Shop
2017/03/19 全球购物
理肤泉加拿大官网:La Roche-Posay加拿大
2018/07/06 全球购物
我有一个char * 型指针正巧指向一些int 型变量, 我想跳过它们。 为什么如下的代码((int *)p)++; 不行?
2013/05/09 面试题
策划主管的工作职责
2013/11/24 职场文书
业务部经理岗位职责
2014/01/04 职场文书
中国好声音华少广告词
2014/03/17 职场文书
程序员求职信
2014/04/16 职场文书
我的职业生涯规划:打造自己的运动帝国
2014/09/18 职场文书
党员“一帮一”活动总结
2015/05/07 职场文书
遗愿清单观后感
2015/06/09 职场文书
老干部座谈会主持词
2015/07/03 职场文书