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文件和目录操作详解
Feb 08 Python
Python获取网页上图片下载地址的方法
Mar 11 Python
python单例模式实例分析
Apr 08 Python
python创建关联数组(字典)的方法
May 04 Python
Python数组遍历的简单实现方法小结
Apr 27 Python
使用PyInstaller将python转成可执行文件exe笔记
May 26 Python
详解windows python3.7安装numpy问题的解决方法
Aug 13 Python
关于python3中setup.py小概念解析
Aug 22 Python
Python打印特殊符号及对应编码解析
May 07 Python
Python读取ini配置文件传参的简单示例
Jan 05 Python
Jupyter notebook 更改文件打开的默认路径操作
May 21 Python
Python学习之时间包使用教程详解
Mar 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递归方法实现无限分类实例代码
2014/02/28 PHP
php简单复制文件的方法
2016/05/09 PHP
Prototype最新版(1.5 rc2)使用指南(1)
2007/01/10 Javascript
JavaScript 学习笔记(十五)
2010/01/28 Javascript
window.location.reload()方法刷新页面弹出要再次显示该网页对话框
2013/04/24 Javascript
js获取当前日期代码适用于网页头部
2013/06/27 Javascript
用js设置下拉框为只读的小技巧
2014/04/10 Javascript
用jquery.sortElements实现table排序
2014/05/04 Javascript
jQuery实现提交按钮点击后变成正在处理字样并禁止点击的方法
2015/03/24 Javascript
对象题目的一个坑 理解Javascript对象
2015/12/22 Javascript
在vue中获取dom元素内容的方法
2017/07/10 Javascript
bootstrap multiselect下拉列表功能
2017/08/22 Javascript
Angular2开发环境搭建教程之VS Code
2017/12/15 Javascript
解决vue中使用swiper插件问题及swiper在vue中的用法
2018/04/04 Javascript
JavaScript文本特效实例小结【3个示例】
2018/12/22 Javascript
JavaScript实现无限级递归树的示例代码
2019/03/29 Javascript
JS中的算法与数据结构之列表(List)实例详解
2019/08/16 Javascript
Javascript实现html转pdf高清版(提高分辨率)
2020/02/19 Javascript
谈谈JavaScript中的函数
2020/09/08 Javascript
[48:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第二场 1月29日
2021/03/11 DOTA
合并百度影音的离线数据( with python 2.3)
2015/08/04 Python
pip安装Python库时遇到的问题及解决方法
2017/11/23 Python
详解PANDAS 数据合并与重塑(join/merge篇)
2019/07/09 Python
Sneaker Studio匈牙利:购买运动鞋
2018/03/26 全球购物
StubHub美国:购买或出售您的门票
2019/07/09 全球购物
如果Session Bean得Remove方法一直都不被调用会怎么样
2012/07/14 面试题
高级人员简历的自我评价分享
2013/11/03 职场文书
广告学专业推荐信范文
2013/11/23 职场文书
历史教育专业个人求职信
2013/12/13 职场文书
写求职信有什么意义
2014/02/17 职场文书
岗位标兵事迹材料
2014/05/17 职场文书
法人身份证明书
2015/06/18 职场文书
《妈妈别哭,有我在》读后感3篇
2020/01/13 职场文书
MySQL系列之四 SQL语法
2021/07/02 MySQL
MongoDB日志切割的三种方式总结
2021/09/15 MongoDB
Python中的datetime包与time包包和模块详情
2022/02/28 Python