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之用while来循环
Oct 02 Python
Python实现去除代码前行号的方法
Mar 10 Python
Python数据类型详解(三)元祖:tuple
May 08 Python
用Python写一个无界面的2048小游戏
May 24 Python
python和pygame实现简单俄罗斯方块游戏
Feb 19 Python
Python 忽略warning的输出方法
Oct 18 Python
Python中shapefile转换geojson的示例
Jan 03 Python
Python3内置模块pprint让打印比print更美观详解
Jun 02 Python
python 发送json数据操作实例分析
Oct 15 Python
Python序列对象与String类型内置方法详解
Oct 22 Python
python实现简单的tcp 文件下载
Sep 16 Python
python爬虫请求头的使用
Dec 01 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开启gzip页面压缩实例代码
2010/03/11 PHP
Python中使用django form表单验证的方法
2017/01/16 PHP
PHP提取字符串中的手机号正则表达式怎么写
2017/07/17 PHP
Laravel5.7 Eloquent ORM快速入门详解
2019/04/12 PHP
php设计模式之组合模式实例详解【星际争霸游戏案例】
2020/03/27 PHP
JavaScript 学习历程和心得分享
2010/12/12 Javascript
jquery如何实现在加载完iframe的内容后再进行操作
2013/09/10 Javascript
javascript数组去重方法终极总结
2014/06/05 Javascript
让人蛋疼的JavaScript语法特性
2014/09/30 Javascript
jquery html动态添加的元素绑定事件详解
2016/05/24 Javascript
原生js实现弹出层效果
2017/01/20 Javascript
js实现导航吸顶效果
2017/02/24 Javascript
微信小程序canvas写字板效果及实例
2017/06/15 Javascript
jQuery封装placeholder效果实现方法,让低版本浏览器支持该效果
2017/07/08 jQuery
写gulp遇到的ES6问题详解
2018/12/03 Javascript
小程序server请求微信服务器超时的解决方法
2019/05/21 Javascript
微信小程序实现吸顶效果
2020/01/08 Javascript
Python安装使用命令行交互模块pexpect的基础教程
2016/05/12 Python
Python实现从log日志中提取ip的方法【正则提取】
2018/03/31 Python
python实现跨excel的工作表sheet之间的复制方法
2018/05/03 Python
python实现石头剪刀布小游戏
2021/01/20 Python
实例介绍Python中整型
2019/02/11 Python
python sorted函数原理解析及练习
2020/02/10 Python
Python基于pandas爬取网页表格数据
2020/05/11 Python
使用python采集Excel表中某一格数据
2020/05/14 Python
Python之字典对象的几种创建方法
2020/09/30 Python
如何基于Python和Flask编写Prometheus监控
2020/11/25 Python
自荐信包含哪些内容
2013/10/30 职场文书
会计人员岗位职责
2014/03/19 职场文书
大学学风建设方案
2014/05/04 职场文书
环保倡议书怎么写
2014/05/16 职场文书
我的职业生涯规划:打造自己的运动帝国
2014/09/18 职场文书
试用期转正工作总结2015
2015/05/28 职场文书
党员转正大会主持词
2015/07/02 职场文书
解决MySQL Varchar 类型尾部空格的问题
2022/04/06 MySQL
使用Cargo工具高效创建Rust项目
2022/08/14 Javascript