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实现FTP服务器服务的方法
Apr 11 Python
Python 模拟购物车的实例讲解
Sep 11 Python
使用python装饰器计算函数运行时间的实例
Apr 21 Python
Linux(Redhat)安装python3.6虚拟环境(推荐)
May 05 Python
详谈Pandas中iloc和loc以及ix的区别
Jun 08 Python
python numpy 显示图像阵列的实例
Jul 02 Python
简单了解python 生成器 列表推导式 生成器表达式
Aug 22 Python
matplotlib绘制多个子图(subplot)的方法
Dec 03 Python
opencv3/C++ 平面对象识别&amp;透视变换方式
Dec 11 Python
Python通过socketserver处理多个链接
Mar 18 Python
python利用google翻译方法实例(翻译字幕文件)
Sep 21 Python
Ubuntu20下的Django安装的方法步骤
Jan 24 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
重新封装zend_soap实现http连接安全认证的php代码
2011/01/12 PHP
PHP源码之explode使用说明
2011/08/05 PHP
浅谈PHP正则中的捕获组与非捕获组
2016/07/18 PHP
php微信开发接入
2016/08/27 PHP
php 文件下载 出现下载文件内容乱码损坏的解决方法(推荐)
2016/11/16 PHP
php intval函数用法总结
2019/04/14 PHP
在chrome中window.onload事件的一些问题
2010/03/01 Javascript
用按钮控制iframe显示的网页实现方法
2013/02/04 Javascript
Javascript跨域请求的4种解决方式
2013/03/17 Javascript
JavaScript实现维吉尼亚(Vigenere)密码算法实例
2013/11/22 Javascript
js的image onload事件使用遇到的问题
2014/07/15 Javascript
js实现简单div拖拽功能实例
2015/05/12 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
2015/08/08 Javascript
JQuery动态添加Select的Option元素实现方法
2016/08/29 Javascript
微信小程序实现鼠标拖动效果示例
2017/12/01 Javascript
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
JS运动改变单物体透明度的方法分析
2018/01/23 Javascript
Webpack中雪碧图插件使用详解
2018/05/25 Javascript
JS获取月的第几周和年的第几周实例代码
2018/12/05 Javascript
jquery多级树形下拉菜单的实例代码
2019/07/09 jQuery
基于layui框架响应式布局的一些使用详解
2019/09/16 Javascript
js 数据类型判断的方法
2020/12/03 Javascript
在实例中重学JavaScript事件循环
2020/12/03 Javascript
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
2021/01/22 Vue.js
python 捕获shell脚本的输出结果实例
2017/01/04 Python
Python Flask前后端Ajax交互的方法示例
2018/07/31 Python
使用CSS3创建动态菜单效果
2015/07/10 HTML / CSS
万得城电器土耳其网站:欧洲第一大电子产品零售商
2016/10/07 全球购物
Bowflex美国官方网站:高级家庭健身器材
2017/12/22 全球购物
英国Office鞋店德国网站:在线购买鞋子、靴子和运动鞋
2018/12/19 全球购物
为什么需要版本控制?
2013/08/08 面试题
中学生个人自我评价
2014/02/06 职场文书
合伙经营协议书
2014/04/18 职场文书
为什么node.js不适合大型项目
2021/04/28 Javascript
如何解决springcloud feign 首次调用100%失败的问题
2021/06/23 Java/Android
高性能跳频抗干扰宽带自组网电台
2022/02/18 无线电