美创科技技术社区

注册

 

发新话题 回复该主题

用java定制化网页数据,并进行抽取 [复制链接]

1#

网络数据抽取
1.网络数据抽取    2
2.在数据库里面建测试表    3
3.通过java抽取结构化数据    4
4.通过kettle调用java    7
5.进行Job调度    9
6. 总结    10

















1.网络数据抽取

网络数据抽取是指从网络中取得大量的又利用价值的数字化信息。主要包括结构化数据抽取(Structured Data Extraction)、信息集成(Information integreation)和观点挖掘(Opinion mining)等。

结构化数据抽取(Structured Data Extraction)的目标是从Web页面中抽取结构化数据。这些结构化数据往往存储在后台数据库中,由网页按一定格式承载着展示给用户。例如论坛列表页面、Blog页面、搜索引擎结果页面等。

信息集成(Information integration)是针对结构化数据而言的。其目标是将从不同网站中抽取出的数据统一化后集成入库。其关键问题是如何从不同网站的数据表中识别出意义相同的数据并统一存储。

传统的网络数据抽取是针对抽取对象手工编写一段专门抽取的程序,因此,我们这里通过写java程序的方式,将网页信息提取出来进行处理,获得自己想要的数据,最终导入到数据库中。同时,通过ETL工具——kettle调用这个java程序,并设置任务调度,尽量使数据库里的数据与网页上的数据保持同步。





















2.在数据库里面建测试表
http://www.usd-cny.com/



Conn bzh/bzh

按照网页数据的结构需求建表

create
table currency (
currency_name varchar2(20),
spot_exchange_in varchar2(20),
oof_in varchar2(20),
spot_exchange_out varchar2(20),
middle_rate varchar2(20),
standard_price varchar2(20),
update_time varchar2(20)
);













3.通过java抽取结构化数据
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.sql.*;

public class NetBug{

private List<String[]> currencyList = new ArrayList<String[]>();
    private List<String> currencyInfo = new ArrayList<String>();
    private String[] currencyNames = {“美元 USD”,”瑞士法郎 CHF”,”新加坡元 SGD”,”瑞典克朗 SEK”,”丹麦克朗 DKK”,”挪威克朗 NOK”,
     “日元 JPY”,”加拿大元 CAD”,”澳大利亚元 AUD”,”欧元 EUR”,”澳门元 MOP”,”菲律宾比索 PHP”,
                                     “泰国铢 THB”,”新西兰元 NZD”,”英镑 GBP”,”港币 HKD”,”韩国元 KRW”,”卢布 RUB”,”林吉特 MYR”};
//对信息进行处理,获取自己需要的内容//    
    private void analyzeCurrency(List<String[]> v_currencyList) {
     for (Iterator<String[]> currencry = v_currencyList.iterator();
     currencry.hasNext(); ) {        
     getCurrency(currencry.next());
     }
    }
    

    private void getCurrency(String[] currencyContent) {
     String currencyName = null;
     int begIndex;
     int endIndex;
for (int i = 0; i < currencyNames.length; i ++) {
     if (currencyContent[2].indexOf(currencyNames) != -1){
              currencyName = currencyNames;
         }
     }
     if (currencyName == null) return;
     for (int i = 3; i <= 7; i++) {
     begIndex = currencyContent.indexOf(“\”right\”>”) + 8;
         endIndex = currencyContent.indexOf(“&nbsp”);
         currencyName += ” ” + (currencyContent.substring(begIndex,endIndex).length() == 0 ? “null”:currencyContent.substring(begIndex,endIndex));
     }
currencyInfo.add(currencyName);
    }

    private void WriteToFile(String currentTimeStr, String fileName) {
     try{
     BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));
     for (Iterator<String> currency = currencyInfo.iterator();
         currency.hasNext(); ){
         bw.write(currency.next() + ” ” + currentTimeStr + “\r\n”);
         }
bw.close();
}
catch(Exception e) {
         e.printStackTrace();
        }        
    }
    
    private void InsertIntoDb(String timeStr) throws Exception{
     Class.forName(“oracle.jdbc.driver.OracleDriver”);
Connection conn = DriverManager.getConnection(“jdbcracle:thin172.16.4.31:1521racle”, “bzh”,”bzh”);
     PreparedStatement stmt = conn.prepareStatement(“insert into currency values(?,?,?,?,?,?,?)”);/*将经过处理的数据插入到oracle数据库的bzh用户下的currency这张表中*/
     String content = null;
     String[] columnValue;
for (Iterator<String> currency = currencyInfo.iterator();
         currency.hasNext(); ){
         content = currency.next();
             columnValue = content.split(” “);
             for (int i = 0; i < columnValue.length; i++) {
             stmt.setString(i+1,columnValue);
             }
             stmt.setString(7, timeStr);
             stmt.addBatch();
         }
stmt.executeBatch();
     conn.close();
    }
    

public static void main(String[] args){
new NetBug().methodPa(args[0]);
}

public void methodPa(String strURL){
String temp;
        int loc = 0;
        String currentTimeStr = new SimpleDateFormat(“yyyy-MM-dd HHm:ss”).format(new Date());
try{
URL url = new URL(strURL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
InputStreamReader isr = new InputStreamReader(conn.getInputStream());              
BufferedReader br = new BufferedReader(isr);
            String[] currencyArray = new String[13];
while((temp = br.readLine()) != null){
if ((temp.indexOf(” <TR “) == 0) || (loc != 0)){
             currencyArray[loc] = temp;
             loc++;
             }
if (temp.indexOf(” </TR>”) == 0) {
                 loc = 0;
                 currencyList.add(currencyArray);
currencyArray = new String[13];                
             }
}
br.close();
isr.close();
            analyzeCurrency(currencyList);    
//WriteToFile(currentTimeStr, “c:\\a.txt”);
InsertIntoDb(currentTimeStr);            
}catch(Exception e){
e.printStackTrace();
}
}
}







4.通过kettle调用java

运行ketttle(打开spoon.bat)

新建转换,取名’网络数据java调用’,拖拽’生成记录’ 和 ‘Modified Java Script Value’两个控件,如下


双击’生成记录’,在这里设置变量的输入(如果单单就放一个的Modified Java Script Value虽然不会报错,但是却不能完成脚本的成功执行,所以设置变量a,通过a传递网页URL值)


将java生成的jar包,放到kettle该目录下




5.双击’Modified Java Script Value’ 控件,这里写java script进行java jar包的调用,


6.点击,运行成功,看生成日志是否报错,然后到oracle数据库里面看看数据是否如期的插入到了数据库中






5.进行Job调度
方法一:通过控件

新建作业,拖拽’STAR’ 和’Transformation’,如下


双击START,里面设置运行的时间间隔


双击Transofrmation,里面选取所需要运行的*.ktr文件


该方法虽然比较直观,但是缺点是必须保持kettle开着(这个Job必须保持运行状态)

总结
JAVA方式能够按照需求,如期的实现网络数据的挖取,至于事后的数据清洗、转换等处理,就可以交给kettle工具来实现。

这个方法缺点JAVA需要定制性开发,无法形成统一的模块,比如网页结构变了,就需要重新编译JAVA代码,重新做处理。。。
分享 转发
TOP
发新话题 回复该主题