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 匹配任意字符(包括换行符)的正则表达式写法
Oct 29 Python
Python with的用法
Aug 22 Python
Python MySQLdb模块连接操作mysql数据库实例
Apr 08 Python
详解在Python中处理异常的教程
May 24 Python
Python中表示字符串的三种方法
Sep 06 Python
使用DataFrame删除行和列的实例讲解
Apr 08 Python
Python(TensorFlow框架)实现手写数字识别系统的方法
May 29 Python
python实现括号匹配的思路详解
Aug 23 Python
pycharm运行和调试不显示结果的解决方法
Nov 30 Python
python实现对输入的密文加密
Mar 20 Python
python退出循环的方法
Jun 18 Python
Python绘制散乱的点构成的图的方法
Apr 21 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 UTF8编码内的繁简转换类
2009/07/20 PHP
第4章 数据处理-php字符串的处理-郑阿奇(续)
2011/07/04 PHP
使用php判断服务器是否支持Gzip压缩功能
2013/09/24 PHP
PHP精确计算功能示例
2016/11/29 PHP
关于php unset对json_encode的影响详解
2018/11/14 PHP
PHP实现通过文本文件统计页面访问量功能示例
2019/02/13 PHP
利用js的Node遍历找到repeater的一个字段实例介绍
2013/04/25 Javascript
js中return false(阻止)的用法
2013/08/14 Javascript
html文本框提示效果的示例代码
2014/06/28 Javascript
jQuery动态修改字体大小的方法【测试可用】
2016/09/09 Javascript
thinkjs之页面跳转同步异步操作
2017/02/05 Javascript
AngularJS实现动态添加Option的方法
2017/05/17 Javascript
详解vue项目的构建,打包,发布全过程
2017/11/23 Javascript
vue-cli 打包使用history模式的后端配置实例
2018/09/20 Javascript
jquery登录的异步验证操作示例
2019/05/09 jQuery
Vue的生命周期操作示例
2019/09/17 Javascript
在Vue中获取自定义属性方法:data-id的实例
2020/09/09 Javascript
npm ci命令的基本使用方法
2020/09/20 Javascript
[02:53]2018年度DOTA2最佳战队-完美盛典
2018/12/17 DOTA
python with提前退出遇到的坑与解决方案
2018/01/05 Python
Python文件读写保存操作的示例代码
2018/09/14 Python
Python 获取windows桌面路径的5种方法小结
2019/07/15 Python
python 基于dlib库的人脸检测的实现
2019/11/08 Python
python 导入数据及作图的实现
2019/12/03 Python
python读写文件write和flush的实现方式
2020/02/21 Python
Python: tkinter窗口屏幕居中,设置窗口最大,最小尺寸实例
2020/03/04 Python
css3动画效果小结(推荐)
2016/07/25 HTML / CSS
利用简洁的图片预加载组件提升html5移动页面的用户体验
2016/03/11 HTML / CSS
html5组织内容_动力节点Java学院整理
2017/07/10 HTML / CSS
李维斯德国官方网上商店:Levi’s德国
2016/09/10 全球购物
Subside Sports德国:足球球衣和球迷商品
2019/06/08 全球购物
正宗的日本零食和糖果订阅盒:Bokksu
2019/11/21 全球购物
《乞巧》教学反思
2014/02/27 职场文书
《乡下孩子》教学反思
2014/04/17 职场文书
上课说话检讨书
2015/01/27 职场文书
Golang并发工具Singleflight
2022/05/06 Golang