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 相关文章推荐
python3使用urllib示例取googletranslate(谷歌翻译)
Jan 23 Python
Python基于多线程操作数据库相关问题分析
Jul 11 Python
完美解决python中ndarray 默认用科学计数法显示的问题
Jul 14 Python
python3.7 使用pymssql往sqlserver插入数据的方法
Jul 08 Python
python同步windows和linux文件
Aug 29 Python
Python3连接Mysql8.0遇到的问题及处理步骤
Feb 17 Python
Python实现从N个数中找到最大的K个数
Apr 02 Python
python json.dumps() json.dump()的区别详解
Jul 14 Python
基于python模拟TCP3次握手连接及发送数据
Nov 06 Python
Django 权限管理(permissions)与用户组(group)详解
Nov 30 Python
Python控制鼠标键盘代码实例
Dec 08 Python
matplotlib绘制正余弦曲线图的实现
Feb 22 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
中东人咖啡哲学
2021/03/03 咖啡文化
PHP采集相关教程之一 CURL函数库
2010/02/15 PHP
PHP7数组的底层实现示例
2019/08/25 PHP
6个常见的 PHP 安全性攻击实例和阻止方法
2020/12/16 PHP
Javascript Cookie读写删除操作的函数
2010/03/02 Javascript
jQuery 源码分析笔记(6) jQuery.data
2011/06/08 Javascript
javascript创建和存储cookie示例
2014/01/07 Javascript
js实现图片上传并正常显示
2015/12/19 Javascript
AngularJs IE Compatibility 兼容老版本IE
2016/09/01 Javascript
AngularJS中watch监听用法分析
2016/11/04 Javascript
微信小程序实现折叠与展开文章功能
2018/06/12 Javascript
基于layui数据表格以及传数据的方式
2018/08/19 Javascript
vue+springboot实现项目的CORS跨域请求
2018/09/05 Javascript
分享一个vue项目“脚手架”项目的实现步骤
2019/05/26 Javascript
layui禁用侧边导航栏点击事件的解决方法
2019/09/25 Javascript
原生JS实现天气预报
2020/06/16 Javascript
原生js实现简单轮播图
2020/10/26 Javascript
Python 列表(List)操作方法详解
2014/03/11 Python
用python写的一个wordpress的采集程序
2016/02/27 Python
使用pandas中的DataFrame数据绘制柱状图的方法
2018/04/10 Python
Python+selenium 获取浏览器窗口坐标、句柄的方法
2018/10/14 Python
django+mysql的使用示例
2018/11/23 Python
Django中使用Celery的方法示例
2018/11/29 Python
python2.7使用scapy发送syn实例
2020/05/05 Python
Sneaker Studio波兰:购买运动鞋
2018/04/28 全球购物
Interflora澳大利亚:同日鲜花速递
2019/06/25 全球购物
美国探亲签证邀请信
2014/02/05 职场文书
家长给学校的建议书
2014/05/15 职场文书
公司晚会策划方案
2014/05/17 职场文书
党性观念心得体会
2014/09/03 职场文书
红领巾心向党演讲稿
2014/09/10 职场文书
服务整改报告
2014/11/06 职场文书
教师个人考察材料
2014/12/16 职场文书
感恩老师主题班会
2015/08/12 职场文书
mybatis源码解读之executor包语句处理功能
2022/02/15 Java/Android
Redis实战高并发之扣减库存项目
2022/04/14 Redis