转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/40585565

更多相关hadoop内容访问:http://blog.csdn.net/xiaojimanman/article/category/2640707

对于博客 http://blog.csdn.net/xiaojimanman/article/details/40372189 中的计算结果 key-value (ip,出现次数),统计下各个地区运营商下的IP个数,通过这个计算结果,可以分析出用户的地理位置分布情况,为决策提供数据支持。

需求描述:

根据IP归属地,对IP进行分组求和,将结果输出到文件中。

数据格式:

此次的数据格式相对比较简单,就是博客 http://blog.csdn.net/xiaojimanman/article/details/40372189 的结果数据,一行数据格式为:

ip地址空格分隔符出现次数 例: 192.168.1.1 25

需求分析:

在实现mapreduce程序之前,需要考虑的一个问题就是IP地址和归属地之间的转换问题。我这里采用的是百度的阿拉丁接口,接口获取方法,在百度首页输入"IP",就会出现阿拉丁界面。如下图所示:

通过对该部分的网络请求分析,获取地址 http://opendata.baidu.com/api.php?query=122.49.34.58&co=&resource_id=6006&t=1414563340538&ie=utf8&oe=gbk&format=json&tn=baidu&_=1414563341538 可以获取IP的归属地,该接口返回的数据格式如下图所示:

可以通过HttpClient模拟浏览器访问该地址,分析返回结果,获取该IP地址对应的归属地。如果自己有IP库,这一步就会简单很多。

IP个归属地中间的对应关系解决了,就需要设计mapreduce的实现问题。

map的输入就是一行原始记录,首先需要对记录进行拆分,取得IP地址,在通过上面提到的接口,查询该IP的归属地;map的输出结果是key为IP归属地,value为出现次数,一行记录就是1 。输出结果如下图所示:

reduce就需要对同一个key下的记录求和即可,输出结果是key为IP归属地,value为出现次数,如下图所示:

这一篇博客在mapreduce方面和上两篇没有太大的区别,所以这里也不再详细的阐述了,这一篇主要的目的就是在mapreduce程序中使用第三方的接口。需求分析就到此为止,下面就看具体的代码实现。

代码实现:

ip归属地查询代码

/*** @Description: ip归属地查询*/
package com.lulei.crawl.ip;import java.io.IOException;
import java.util.Date;
import java.util.HashMap;import org.apache.commons.httpclient.HttpException;import com.lulei.crawl.CrawlBase;
import com.lulei.util.DoRegex;/*** @author lulei* 这里继承了自己的封装类,在类CrawlBase中实现了网络数据的获取,并将网页源代码存储在pageSourceCode中*/
public class IPInfo extends CrawlBase{private String ip;private String location;//第三方接口地址private static String ipUrl = "http://opendata.baidu.com/api.php?query=%ip%&co=&resource_id=6006&t=%t1%&ie=utf8&oe=gbk&format=json&tn=baidu&_=%t2%";private static long timeDifference = 1000L;private static HashMap<String, String> params;private static String locationRegex = "\"location\":\"(.*?)\"";//伪装浏览器static {params = new HashMap<String, String>();params.put("Referer", "http://www.baidu.com");params.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36");}public IPInfo(String ip) throws HttpException, IOException {long t1 = new Date().getTime();long t2 = t1 + timeDifference;this.ip = ip;//组装请求地址String url = ipUrl.replaceAll("%ip%", ip).replaceAll("%t1%", t1 + "").replaceAll("%t2%", t2 + "");//获取网页源代码,具体的实现,这里就不详细的介绍,自己可以写简单的HttpClient实现此功能 readPageByGet(url, "utf-8", params);//解析源代码,获取归属地setLocation();}/*** @author lulei* 解析源代码,获取归属地*/private void setLocation() {this.location = DoRegex.getFirstString(getPageSourceCode(), locationRegex, 1);}public String getIp() {return ip;}public String getLocation() {return location;}/*** @param args* @throws IOException * @throws HttpException */public static void main(String[] args) throws HttpException, IOException {// TODO Auto-generated method stubString ip = "122.49.34.58";IPInfo ipinfo = new IPInfo(ip);System.out.println("ip:" +ip );System.out.println("归属地:" + ipinfo.getLocation());}
}

对一行记录的分析类

 /**  *@Description: 一行记录分析*/
package com.mapreduce.log;  import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;import com.lulei.crawl.ip.IPInfo;public class LogLine {private String ip;private String location;private boolean right = true;private IntWritable one = new IntWritable(1);public LogLine(String textLine) {//检验一行日志数据是否符合要求,如不符合,将其标识为不可用if (textLine == null || "".equals(textLine)) {this.right = false;return;}String []strs = textLine.split(" ");if (strs.length < 2) {this.right = false;return;}//ip地址在第一个位置this.ip = strs[0];setLocation();}private void setLocation() {try {IPInfo ipInfo = new IPInfo(this.ip);this.location = ipInfo.getLocation();} catch (Exception e) {// TODO Auto-generated catch block  e.printStackTrace();//如果出现网络错误,将此IP的归属地设置成“未知”this.location = "未知";} }/*** @return* @Author:lulei  * @Description: map输出key*/public Text getMapKey() {return new Text(this.location);}/*** @return* @Author:lulei  * @Description: map输出value*/public IntWritable getMapValue() {return this.one;}public boolean isRight() {return right;}}

mapreduce程序实现类

 /**  *@Description: IP归属地统计mapreduce实现   */
package com.mapreduce.log;  import java.io.IOException;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;public class IPLocationMapReduce extends Configured implements Tool{/***@Description: IP归属地统计map *@Author:lulei  *@Version:1.1.0*/public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {@Overrideprotected void map(LongWritable key, Text value, Context context)throws IOException, InterruptedException {LogLine logLine = new LogLine(value.toString());if (logLine.isRight()) {context.write(logLine.getMapKey(), logLine.getMapValue());}}}/***@Description: IP归属地统计reduce*@Author:lulei  *@Version:1.1.0*/public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {@Overrideprotected void reduce(Text key, Iterable<IntWritable> values, Context context)throws IOException, InterruptedException {int sum = 0;//对values进行求和操作for (IntWritable value : values) {sum += value.get();}context.write(key, new IntWritable(sum));}}@Overridepublic int run(String[] arg0) throws Exception {Configuration conf = new Configuration();@SuppressWarnings("deprecation")Job job = new Job(conf);job.setJobName("ipcount");job.setInputFormatClass(TextInputFormat.class);//将输出设置为TextOutputFormatjob.setOutputFormatClass(TextOutputFormat.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);//Mapper Combiner Reducerjob.setMapperClass(Map.class);job.setCombinerClass(Reduce.class);job.setReducerClass(Reduce.class);//输入 输出路径FileInputFormat.addInputPath(job, new Path(arg0[0]));FileOutputFormat.setOutputPath(job, new Path(arg0[1]));job.waitForCompletion(true);return job.isSuccessful() ? 0 : 1;}public static void main(String[] args) {// TODO Auto-generated method stub //这里没有对输入的参数做验证try {int res = ToolRunner.run(new Configuration(), new IPLocationMapReduce(), args);System.exit(res);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

上传运行:

打包、上传、运行这些步骤这里就不再详细介绍,具体可以参照博客 http://blog.csdn.net/xiaojimanman/article/details/40184581 最后一部分。

对于自己写的数据的输出结果如下图所示:

到此一个完整的mapreduce程序就完成了,关于hadoop的学习,自己还将继续~

使用hadoop实现ip地理位置统计~ip归属地和运营商相关推荐

  1. python获取手机号码归属地_Python批量获取并保存手机号归属地和运营商的示例

    从Excel读取一组手机号码,批量查询该手机号码的运营商和归属地,并将其追加到该记录的末尾. import requests import json import xlrd from xlutils. ...

  2. python自动获取号码归属地_Python批量获取并保存手机号归属地和运营商的示例

    从Excel读取一组手机号码,批量查询该手机号码的运营商和归属地,并将其追加到该记录的末尾.SAb免费资源网 import requests import json import xlrd from ...

  3. 通过python获取自己的手机话费_Python批量获取并保存手机号归属地和运营商的示例...

    从Excel读取一组手机号码,批量查询该手机号码的运营商和归属地,并将其追加到该记录的末尾. import requests import json import xlrd from xlutils. ...

  4. AJAX使用淘宝API查询手机归属地和运营商信息

    AJAX使用淘宝API查询手机归属地和运营商信息 使用给的api地址查询自己的手机号码所在地 地址: https://www.baifubao.com/callback?cmd=1059&ph ...

  5. python自动获取号码归属地_Nemo_Python:批量获取并保存手机号的归属地和运营商_Nemo社区_LinkNemo_关于分享和探索的好地方...

    从Excel读取一组手机号码,批量查询该手机号码的运营商和归属地,并将其追加到该记录的末尾. import requests import json import xlrd from xlutils. ...

  6. linux 访客日志ip,shell统计ip访问情况,要求分析访问日志分析。

    [题目要求] 有日志 1.log,部分内容如下: 112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com "/se ...

  7. 手机号归属地和运营商数据(471452条)

    简介 中国手机号前七位可以确定手机号归属地;手机后缀为csv,可导入hive.mysql等数据库.整理的数据有471452条,涵盖95%的归属地数据. 下载地址:https://download.cs ...

  8. 【大数据开发】SparkCore——统计广告topN、基站停留时间topN、ip地址统计练习

    文章目录 材料准备 一.统计广告TopN 1.1统计每⼀个省份点击TOP3的⼴告ID 1.2统计每一个省份每一个小时的TOP3广告ID 二.基站停留时间TopN 三.ip地址统计 材料准备 新建一个o ...

  9. 【大数据开发】SparkCore——利用广播变量优化ip地址统计、Spark2.x自定义累加器

    文章目录 一.Broadcast广播变量 1.1 广播变量的逻辑过程 1.2 [优化ip地址统计](https://blog.csdn.net/weixin_37090394/article/deta ...

最新文章

  1. centos7grub2 引导win10
  2. ADF Jar包循环引用会出问题
  3. 电脑开机一会就蓝屏怎么回事_客户电脑老是出现问题,三天来找三次麻烦!拆机后“真凶”大白!...
  4. 无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]
  5. 【人物专访】朱玲——我在网易云当女程序媛
  6. C语言简单题-求整数段和
  7. 为什么要学jquery
  8. 使用阿里云火车票查询接口案例——CSDN博客
  9. LeetCode-424:替换后的最长重复字符
  10. 基于共享内存、信号、命名管道和Select模型实现聊天窗口
  11. Mysql-5.5+Heartbeat-3.0.5+DRBD
  12. Oracle数据库-建库、建表空间,建用户
  13. Python+Selenium+Edge浏览器安装与简单运行(1/2)
  14. 基于SSM+Bootstrap+MYSQL演唱会网上订票系统
  15. 计算机基础知识教程excel试题,大学生计算机基础excel试题及答案
  16. 商户都在用的进销存软件,哪一个性价比最高?
  17. springboot 整合阿里云oss
  18. ubuntu18.04未发现wifi适配器,安装wifi无线网卡驱动-RTL8822BE、RTL8822CE、RTL8821CE、RTL8723DE
  19. 计算机科学博士点,全国计算机博士点排名(全国前70名)
  20. 抖音直播带货数据复盘怎么做?如何复盘提高直播间转化率?

热门文章

  1. 2021年Java开发突破20k有哪些有效的路径,你的技术真的到天花板了吗
  2. 应对程序员面试,你必须知道的八大数据结构
  3. 支付宝电话面试经过及心情
  4. win10切换出中文简体美式键盘,与按ALT+TAB切换窗口的设置方法
  5. i.MX8MP平台开发分享(IOMUX篇)- 硬件原理
  6. Qt on Android: http下载与Json解析
  7. miui系统负一屏快递详情“显示数据加载异常,请点击重试”的解决方法
  8. CENTOS7 Anaconda+Jupyter+Pyspark联合安装
  9. ARabbit:一个快速开发Android App的框架
  10. SQL中的动态SQL