基于Java的数据采集(终结篇)

时间:2021-09-14 18:32:59

关于写过关于JAVA采集入库的三篇文章:

基于Java数据采集入库(一):http://www.cnblogs.com/lichenwei/p/3904715.html

基于Java数据采集入库(二):http://www.cnblogs.com/lichenwei/p/3905370.html

基于Java数据采集入库(三):http://www.cnblogs.com/lichenwei/p/3907007.html

分别实现了

①抓取页面信息并显示

②简单采集入库存储

③调用本地数据库查询

④远程调用实现操作(未实现)

以上这些功能都是基于本地的,有时候我们需要远程去调用这类数据,这时我们就可以用JAVA提供的RMI机制实行远程调用访问。

当然也可以用WebServices实现(PHP版本,有时间再写个JAVA版本的):http://www.cnblogs.com/lichenwei/p/3891297.html

什么是RMI?

RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。调用这样一个对象时,其参数为 "marshalled" 并将其从本地虚拟机发送到远程虚拟机(该远程虚拟机的参数为 "unmarshalled")上。该方法终止时,将编组来自远程机的结果并将结果发送到调用方的虚拟机。如果方法调用导致抛出异常,则该异常将指示给调用方。

简单了解下RMI,看下简单实现吧

1、定义远程接口

首先,我们需要写个远程接口IHello 该接口继承了远程对象Remote.

接口IHello里面有个hello的方法,用于客户端连接后 打招呼.

由于IHello继承了远程Remote对象, 所以需要抛一个 RemoteException 远程异常.

 import java.rmi.Remote;
import java.rmi.RemoteException; public interface IHello extends Remote{ public String hello(String name) throws RemoteException;
}

2、实现接口

接下来,我们实现下 该接口里的方法, 实现接口的方法在服务端.

这里的HelloImpl类 实现了接口IHello里的方法.

注意:这里HelloImpl同样继承了 UnicastRemoteObject 远程对象,这个必须写,不然服务端启动后会莫名其妙报错.

 import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject; /**
* UnicastRemoteObject 这个必须写,虽然不写代码也不会出错,但在运行服务器的时候会出现莫名错误
* @author Balla_兔子
*
*/
public class HelloImpl extends UnicastRemoteObject implements IHello { protected HelloImpl() throws RemoteException {
super();
} @Override
public String hello(String name) {
String strHello="你好!"+name+"正在访问服务端";
System.out.println(name+"正在访问服务端");
return strHello;
} }

3、编写服务端

服务端,由于RMI实现远程访问的机制是指:客户端通过在RMI注册表上寻找远程接口对象的地址(服务端地址) 达到实现远程访问的目的,

所以,我们需要在服务端创建一个远程对象的注册表,用于绑定和注册 服务端地址 和 远程接口对象,便于后期客户端能够成功找到服务端

 import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; public class Server { /**
* @param args
*/
public static void main(String[] args) {
try {
IHello hello=new HelloImpl();
int port=6666;
LocateRegistry.createRegistry(port);
String address="rmi://localhost:"+port+"/tuzi";
Naming.bind(address, hello);
System.out.println(">>>服务端启动成功");
System.out.println(">>>请启动客户端进行连接访问.."); } catch (Exception e) {
e.printStackTrace();
}
} }

4、编写客户端

客户端上同样需要定义一个 远程访问的地址 - 即服务端地址,

然后,通过在RMI注册表上寻找该地址;  如果找到 则建立连接.

 import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.Scanner; public class Client {
public static void main(String[] args) { int port=6666;
String address="rmi://localhost:"+port+"/tuzi";
try {
IHello hello=(IHello) Naming.lookup(address);
System.out.println("<<<客户端访问成功!");
//客户端 Client 调用 远程接口里的 sayHello 方法 并打印出来
System.out.println(hello.hello("Rabbit"));
Scanner scanner=new Scanner(System.in);
String input=scanner.next();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

运行效果图:

基于Java的数据采集(终结篇)

基于Java的数据采集(终结篇)基于Java的数据采集(终结篇)

华丽的分割线


接下来就来看看我们的程序吧,今天换种口味来采集下《2013-2014赛季常规赛排名》

这是数据网址:http://nbadata.sports.qq.com/teams_stat.aspx

基于Java的数据采集(终结篇)

先上效果图:

基于Java的数据采集(终结篇)

基于Java的数据采集(终结篇)

基于Java的数据采集(终结篇)

基于Java的数据采集(终结篇)

基于Java的数据采集(终结篇)

基于Java的数据采集(终结篇)

好了,剩下的上代码吧,具体看代码注释:

IdoAction.java (功能调用接口代码)

 package com.lcw.rmi.collection;

 import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List; public interface IdoAction extends Remote{ public void initData() throws RemoteException; public void getAllDatas() throws RemoteException; public List<String> getAllTeams() throws RemoteException; public List<String> getTeamInfo(String team) throws RemoteException; public List<String> getAllInfo() throws RemoteException; }

IdoAction.java

doActionImpl.java (接口实现类)

 package com.lcw.rmi.collection;

 import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; public class doActionImpl extends UnicastRemoteObject implements IdoAction { /**
*
*/
private static final long serialVersionUID = 1L;
private Mysql mysql;
private ResultSet resultSet; public doActionImpl() throws RemoteException {
mysql = new Mysql();
} @Override
public void getAllDatas() throws RemoteException {
// 调用采集类,获取所有数据
CollectData data = new CollectData();
data.getAllDatas();
System.out.println("数据采集成功!");
} @Override
public List<String> getAllInfo() throws RemoteException {
// 查询所有数据
String sql = "select * from data";
resultSet = mysql.querySQL(sql);
List<String> list=new ArrayList<String>();
System.out.println("当前执行命令5,正在获取NBA(2013-2014)赛季常规赛队伍所有信息..");
System.out.println("获取成功,已在客户端展示..");
try {
while(resultSet.next()) {
for (int i = 2; i < 17; i++) {
//System.out.println("++++++++++++++");调试
list.add(resultSet.getString(i));
}
System.out.println();
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
} @Override
public List<String> getAllTeams() throws RemoteException {
// 查询所有队伍名称
String sql = "select team from data";
resultSet = mysql.querySQL(sql);
List<String> list = new ArrayList<String>();
System.out.println("当前执行命令3,正在获取NBA(2013-2014)赛季常规赛队伍..");
System.out.println("获取成功,已在客户端展示..");
try {
while (resultSet.next()) {
list.add(resultSet.getString("team"));
}
} catch (SQLException e) {
System.out.println("数据库暂无信息,请执行自动化采集命令");
e.printStackTrace();
}
return list; } @Override
public List<String> getTeamInfo(String team) throws RemoteException {
// 根据队伍查询队伍信息
ResultSet resultSet = mysql.querySQL("select * from data where team='"
+ team + "'");
List<String> list=new ArrayList<String>();
System.out.println("当前执行命令4,正在获取用户所查询队伍信息..");
System.out.println("获取成功,已在客户端展示..");
try {
if (resultSet.next()) {
for (int i = 2; i < 17; i++) {
list.add(resultSet.getString(i));
}
}
System.out.println();
} catch (SQLException e) {
System.out.println("数据库暂无信息,请执行自动化采集命令");
e.printStackTrace();
}
return list;
} @Override
public void initData() throws RemoteException {
// 初始化数据库
String sql = "delete from data";
try {
mysql.updateSQL(sql);
System.out.println("数据库初始化成功!");
} catch (Exception e) {
System.out.println("数据库初始化失败!");
} } }

doActionImpl.java

CollectData.java (采集主类)

 package com.lcw.rmi.collection;

 import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class CollectData { /**
* 采集类,获取所有数据
*/
public void getAllDatas() {
String address = "http://nbadata.sports.qq.com/teams_stat.aspx";// 要采集数据的url
try {
URL url = new URL(address);
try {
InputStream inputStream = url.openStream();// 打开url,返回字节流
InputStreamReader inputStreamReader = new InputStreamReader(
inputStream, "gbk");// 将字节流转换为字符流,编码utf-8
BufferedReader reader = new BufferedReader(inputStreamReader);// 提高效率,缓存
String rankRegEx = ">\\d{1,2}</td>";// 排名正则
String teamRegEx = ">[^<>]*</a>";// 队名正则
String dataRegEx = ">\\d{1,3}(\\.)\\d{0,2}</td>";// 正常数据正则
String percentRegEX = ">\\d{1,2}(\\.)*(\\d)*%</span></td>";// 百分比数据
GetRegExData regExData = new GetRegExData();
String temp = "";// 存放临时读取数据
int flag = 0;
String tempRank = "";// 存放匹配到的返回数据
String tempTeam = "";// 存放匹配到的返回数据
String tempData = "";
String tempPercent = "";
List<String> list = new ArrayList<String>();
Mysql mysql = new Mysql();
while ((temp = reader.readLine()) != null) {
// 匹配排名
if ((tempRank = regExData.getData(rankRegEx, temp)) != "") {
tempRank = tempRank.substring(1, tempRank
.indexOf("</td>"));
// System.out.println("排名:" + tempRank);
list.add(tempRank);
flag++;
}
// 匹配球队
// 由于该正则会匹配到其他地方的数据,需给它一个标识符,让它从"找到排名位置"才开始匹配
if ((tempTeam = regExData.getData(teamRegEx, temp)) != ""
&& flag == 1) {
tempTeam = tempTeam.substring(1, tempTeam
.indexOf("</a>"));
// System.out.println("球队名称:" + tempTeam);
list.add(tempTeam);
flag = 0;
}
// 匹配正常数据
if ((tempData = regExData.getData(dataRegEx, temp)) != "") {
tempData = tempData.substring(1, tempData
.indexOf("</td>"));
// System.out.println(tempData);
list.add(tempData); }
// 匹配百分比数据
if ((tempPercent = regExData.getData(percentRegEX, temp)) != "") {
tempPercent = tempPercent.substring(1, tempPercent
.indexOf("</span></td>"));
// System.out.println(tempPercent);
list.add(tempPercent);
} }
reader.close();
Object[] arr = list.toArray();// 将集合转换为数组
int a = -15;
int b = 0;
String sql = "insert into data(rank,team,chushou1,mingzhong1,chushou2,mingzhong2,chushou3,mingzhong3,qianchang,houchang,zong,zhugong,shiwu,fangui,defen) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
for (int i = 0; i < 30; i++) {
a += 15;
b += 15;
if (b <= 450) {
Object[] arr1 = Arrays.copyOfRange(arr, a, b);
mysql.insertNewData(sql, arr1);
System.out.println("正在采集数据..当前采集数据:" + (i + 1) + "条");
}
} } catch (IOException e) {
e.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
} }

CollectData.java

GetRegExData.java (正则过滤功能类)

 package com.lcw.rmi.collection;

 import java.util.regex.Matcher;
import java.util.regex.Pattern; public class GetRegExData { public String getData(String regex, String content) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
return matcher.group();
} else {
return "";
} }
}

GetRegExData.java

Mysql.java (数据库操作类)

 package com.lcw.rmi.collection;

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; public class Mysql { private String driver = "com.mysql.jdbc.Driver";
private String url = "jdbc:mysql://localhost:3306/nba";
private String user = "root";
private String password = ""; private PreparedStatement stmt = null;
private Connection conn = null;
private ResultSet resultSet = null; /**
*
* @param insertSql
* 采集类,插入数据操作
* @param arr
*/
public void insertNewData(String insertSql, Object[] arr) { try {
Class.forName(driver).newInstance();
try {
conn = DriverManager.getConnection(url, user, password);
stmt = conn.prepareStatement(insertSql);
stmt.setString(1, arr[0].toString());
stmt.setString(2, arr[1].toString());
stmt.setString(3, arr[2].toString());
stmt.setString(4, arr[3].toString());
stmt.setString(5, arr[4].toString());
stmt.setString(6, arr[5].toString());
stmt.setString(7, arr[6].toString());
stmt.setString(8, arr[7].toString());
stmt.setString(9, arr[8].toString());
stmt.setString(10, arr[9].toString());
stmt.setString(11, arr[10].toString());
stmt.setString(12, arr[11].toString());
stmt.setString(13, arr[12].toString());
stmt.setString(14, arr[13].toString());
stmt.setString(15, arr[14].toString());
stmt.executeUpdate();
stmt.close();
conn.close(); } catch (SQLException e) {
e.printStackTrace();
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} } /**
*
* @param sql更新数据库语句
*/
public void updateSQL(String updateSql) {
try {
Class.forName(driver).newInstance();
try {
conn = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
try {
stmt = conn.prepareStatement(updateSql);
stmt.execute(updateSql);
} catch (SQLException e) {
e.printStackTrace();
} } catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} /**
*
* @param sql一般查询
*/
public ResultSet querySQL(String searchSql) {
try {
Class.forName(driver).newInstance();
try {
conn = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
try {
stmt = conn.prepareStatement(searchSql);
resultSet = stmt.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
} } catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return resultSet;
}
}

Mysql.java

Server.java (服务端类)

 package com.lcw.rmi.collection;

 import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; public class Server { /**
* @param args
*/
public static void main(String[] args) {
try {
int port = 9797;
String address = "rmi://localhost:"+port+"/nba";
IdoAction action = new doActionImpl();
LocateRegistry.createRegistry(port);
try {
Naming.bind(address, action);
System.out.println(">>>正在启动服务端..");
System.out.println(">>>服务端启动成功!");
System.out.println(">>>等待客户端连接...");
System.out.println(">>>客户端Balla_兔子已连接。");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
} catch (RemoteException e) {
e.printStackTrace();
}
} }

Server.java

Client.java (客户端类)

 package com.lcw.rmi.collection;

 import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.List;
import java.util.Scanner; public class Client { public static void main(String[] args) {
int port = 9797;
String address = "rmi://localhost:" + port + "/nba"; try {
IdoAction action = (IdoAction) Naming.lookup(address);
System.out.println("正在启动客户端..");
System.out.println("客户端启动完毕,正在连接服务端..");
System.out.println("连接成功...");
System.out.println("---------------------------"); while (true) {
System.out.println("①初始化数据库-请按 (1)");
System.out.println();
System.out.println("②自动化采集NBA(2013-2014)赛季常规赛排名数据-请按(2)");
System.out.println();
System.out.println("③查询NBA(2013-2014)赛季常规赛排名所有队伍-请按(3)");
System.out.println();
System.out.println("④查询具体球队(2013-2014)赛季常规赛排名-请按(4)");
System.out.println();
System.out.println("⑤查询具体详情-请按(5)");
System.out.println(); Scanner scanner = new Scanner(System.in);
String input = scanner.next(); if (input.equals("1")) {
System.out
.println("---------------------------------------------------------");
System.out.println("服务端数据已初始化,请按2进行数据自动化采集..");
action.initData();
System.out
.println("---------------------------------------------------------");
}
if (input.equals("2")) {
System.out
.println("---------------------------------------------------------");
System.out.println("数据自动化采集中,请稍后..");
int i=0;
while(i<10000){//延迟操作,给数据采集缓冲时间
i++;
}
System.out.println("数据采集完毕..按3,4,5进行相关操作");
action.getAllDatas();
System.out
.println("---------------------------------------------------------");
}
if (input.equals("3")) {
System.out
.println("---------------------------------------------------------");
System.out.println("正在获取NBA(2013-2014)赛季常规赛队伍,请稍后..");
System.out.println();
List<String> list = action.getAllTeams();
for (int i = 0; i < list.size(); i++) {
if (i % 5 == 0 && i != 0) {
System.out.println();
}
System.out.print(list.get(i) + "\t");
}
System.out.println(); System.out
.println("---------------------------------------------------------");
}
if (input.equals("4")) {
System.out
.println("---------------------------------------------------------");
System.out.println("请输入你要查询的队伍名称(如:76人)");
String team = scanner.next();
System.out
.print("排名\t球队\t出手\t命中率\t出手\t命中率\t出手\t命中率\t前场\t后场\t总\t助攻\t失误\t犯规\t得分");
System.out.println();
List<String> list=action.getTeamInfo(team);
for (int i = 0; i < 15; i++) {
System.out.print(list.get(i)+"\t");
}
System.out.println();
System.out
.println("---------------------------------------------------------");
}
if (input.equals("5")) {
System.out
.println("---------------------------------------------------------");
System.out.println("数据获取中,请稍后...");
System.out.println();
System.out
.print("排名\t球队\t出手\t命中率\t出手\t命中率\t出手\t命中率\t前场\t后场\t总\t助攻\t失误\t犯规\t得分");
System.out.println();
List<String> list=action.getAllInfo();
for(int i=0;i<450;i++){
if(i%15==0&&i!=0){
System.out.println();
}
System.out.print(list.get(i)+"\t");
}
System.out.println();
System.out
.println("---------------------------------------------------------");
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}

Client.java

好了,关于JAVA采集数据文章就到此为止了~ 撤··

基于Java的数据采集(终结篇)的更多相关文章

  1. 基于Java的数据采集(一)

    之前写过2篇关于PHP数据采集入库的文章: 基于PHP数据采集入库(一):http://www.cnblogs.com/lichenwei/p/3872307.html 基于PHP数据采集入库(二): ...

  2. 基于Java的数据采集(二)

    在上一篇文章<基于Java的数据采集(一)>:http://www.cnblogs.com/lichenwei/p/3904715.html 提到了如何如何读取网页源代码,并通过group ...

  3. 基于Java的数据采集(三)

    <基于Java的数据采集(一)>:http://www.cnblogs.com/lichenwei/p/3904715.html <基于Java的数据采集(二)>:http:/ ...

  4. 死磕 java集合之终结篇

    概览 我们先来看一看java中所有集合的类关系图. 这里面的类太多了,请放大看,如果放大还看不清,请再放大看,如果还是看不清,请放弃. 我们下面主要分成五个部分来逐个击破. List List中的元素 ...

  5. 基于Web Service的客户端框架搭建四:终结篇

    前言 这是这个系列的终结篇,前面3个博客介绍了一下内容: 1.使用Http Post方式调用Web Service 2.客户端框架之数据转换层 3.客户端框架之代理层 框架结构 框架是基于C#的,在V ...

  6. 看看C&num; 6&period;0中那些语法糖都干了些什么(终结篇)

    终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...

  7. 基于Java的打包jar、war、ear包的作用与区别详解

      本篇文章,小编为大家介绍,基于Java的打包jar.war.ear包的作用与区别详解.需要的朋友参考下   以最终客户的角度来看,JAR文件就是一种封装,他们不需要知道jar文件中有多少个.cla ...

  8. 基于java的设计模式入门(1)——为什么要学习设计模式

    大年初一,楼主在这里给大家拜年,祝大家码上升职加薪,码上有对象结婚,码上有车有房,幸福安康. 过完年,回学校注册报道之后,大概就要回深圳到公司开始实习了.提高自己,无非就有两种方式,一是看书学习,二是 ...

  9. WPF自定义控件与样式&lpar;15&rpar;-终结篇 &amp&semi; 系列文章索引 &amp&semi; 源码共享

    系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...

随机推荐

  1. twitter点赞动画详解

    今天在微博上看到@过气网红一丝 的一篇微博,codepen上贴出了twitter点赞那个动画效果的源码,地址 http://codepen.io/yisi/pen/LpXVJb .我看了下效果很好看, ...

  2. JAVA1种C&plus;&plus;3种继承方式

    JAVA中只有一种public继承

  3. vmware安装centos时遇到无法创建新虚拟机&colon; 不具备执行此操作的权限。

    我的问题是选择文件位置造成的,我选择在了VMware安装的位置,重新选择一个文件夹即可.

  4. 详解LUA开发工具及其环境配置

    LUA开发工具及其环境配置是本文要介绍的内容,主要是来了解并学习lua开发工具的使用和环境的配置,第一次接触LUA的话,就跟本人一起学习吧.看我能不能忽悠到你. LUA是语言,那么一定有编写的工具.第 ...

  5. nginx php7 配置 备用

    yum install epel-* -y yum install -y wget unzip gcc gcc-c++ make zlib zlib-devel pcre pcre-devel lib ...

  6. sql for xml 输出结果带单引号出现转成&amp&semi;apos的解决方案

    select '''' + ID +''',' from  表 for xml path('') 此SQL语句,输出结果如‘1’,’2‘,’3‘, 但是在因xml会出现path转译的问题将‘转成&am ...

  7. Scalable MySQL Cluster with Master-Slave Replication&comma; ProxySQL Load Balancing and Orchestrator

    MySQL is one of the most popular open-source relational databases, used by lots of projects around t ...

  8. 详解C&num;泛型(一)

    一.C#中的泛型引入了类型参数的概念,类似于C++中的模板,类型参数可以使类型或方法中的一个或多个类型的指定推迟到实例化或调用时,使用泛型可以更大程度的重用代码.保护类型安全性并提高性能:可以创建自定 ...

  9. PHP独立环境搭建细节

    一.安装前准备: 准备安装软件此处以以下软件为例: Appache:httpd-2.2.21-win32-x86-openssl-0.9.8r.msi MySQL: mysql-5.5.21-win ...

  10. Microsoft Orleans 之安装

    先决条件 Orleans 是一个.net 类库集,为了使用它,你需要.net 4.5.1 或者更高版本,开发工具集需要visual studio 2015 或者更高版本或者其他支持的开发工具,不支持V ...