在很多行業中,要對行業數據進行分類匯總,及時分析行業數據,對於公司未來的發展,有很好的參照和橫向對比。所以,在實際工作,我們可能要遇到數據采集這個概念,數據采集的最終目的就是要獲得數據,提取有用的數據進行數據提取和數據分類匯總。
很多人在第一次了解數據采集的時候,可能無從下手,尤其是作為一個新手,更是感覺很是茫然,所以,在這里分享一下自己的心得,希望和大家一起分享技術,如果有什么不足,還請大家指正。寫出這篇目的,就是希望大家一起成長,我也相信技術之間沒有高低,只有互補,只有分享,才能使彼此更加成長。
在網頁數據采集的時候,我們往往要經過這幾個大的步驟:
①通過URL地址讀取目標網頁②獲得網頁源碼③通過網頁源碼抽取我們要提取的目的數據④對數據進行格式轉換,獲得我們需要的數據。
這是一個示意圖,希望大家了解

了解了基本流程,下來,我以一個案例具體實現如何提取我們需要的數據,對於數據提取可以用正則表達式進行提取,也可以用httpclient+jsoup進行提取,此處,暫且不講解httpclient+jsou提取網頁數據的做法,以后會對httpclient+jsoup進行專門的講解,此處,先開始講解如何用正則表達式對數據進行提取。
我在這里找到一個網站:http://www.ic.NET.cn/userSite/publicQuote/quotes_list.PHP 我們要對里面的數據進行提取操作,我們要提取的最終結果是產品的型號、數量、報價、供應商,首先,我們看到這個網站整個頁面預覽

其次我們看網頁源碼結構:

上面源碼可以很清楚的可以看到整個網頁源碼結構,下來我們就對整個網頁數據進行提取
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HTMLPageParser {
public static void main(String[] args) throws Exception {
//目的網頁URL地址
getURLInfo("http://www.ic.net.cn/userSite/publicQuote/quotes_list.php","utf-8");
}
public static List<Product> getURLInfo(String urlInfo,String charset) throws Exception {
//讀取目的網頁URL地址,獲取網頁源碼
URL url = new URL(urlInfo);
HttpURLConnection httpUrl = (HttpURLConnection)url.openConnection();
InputStream is = httpUrl.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is,"utf-8"));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
//這里是對鏈接進行處理
line = line.replaceAll("</?a[^>]*>", "");
//這里是對樣式進行處理
line = line.replaceAll("<(\\w+)[^>]*>", "<$1>");
sb.append(line);
}
is.close();
br.close();
//獲得網頁源碼
return getDataStructure(sb.toString().trim());
}
static Pattern proInfo
= Pattern.compile("<div>(.*?)</div>\\s*<div>(.*?)</div>\\s*<div>(.*?)</div>\\s*<div>(.*?)</div>\\s*<div>(.*?)</div>", Pattern.DOTALL);
private static List<Product> getDataStructure(String str) {
//運用正則表達式對獲取的網頁源碼進行數據匹配,提取我們所要的數據,在以后的過程中,我們可以采用httpclient+jsoup,
//現在暫時運用正則表達式對數據進行抽取提取
String[] info = str.split("</li>");
List<Product> list = new ArrayList<Product>();
for (String s : info) {
Matcher m = proInfo.matcher(s);
Product p = null;
if (m.find()) {
p = new Product();
//設置產品型號
String[] ss = m.group(1).trim().replace(" ", "").split(">");
p.setProStyle(ss[1]);
//設置產品數量
p.setProAmount(m.group(2).trim().replace(" ", ""));
//設置產品報價
p.setProPrice(m.group(4).trim().replace(" ", ""));
//設置產品供應商
p.setProSupplier(m.group(5).trim().replace(" ", ""));
list.add(p);
}
}
//這里對集合里面不是我們要提取的數據進行移除
list.remove(0);
for (int i = 0; i < list.size(); i++) {
System.out.println("產品型號:"+list.get(i).getProStyle()+",產品數量:"+list.get(i).getProAmount()
+",產品報價:"+list.get(i).getProPrice()+",產品供應商:"+list.get(i).getProSupplier());
}
return list;
}
}
class Product {
private String proStyle;//產品型號
private String proAmount;//產品數量
private String proPrice;//產品報價
private String proSupplier;//產品供應商
public String getProStyle() {
return proStyle;
}
public void setProStyle(String proStyle) {
this.proStyle = proStyle;
}
public String getProSupplier() {
return proSupplier;
}
public void setProSupplier(String proSupplier) {
this.proSupplier = proSupplier;
}
public String getProAmount() {
return proAmount;
}
public void setProAmount(String proAmount) {
this.proAmount = proAmount;
}
public String getProPrice() {
return proPrice;
}
public void setProPrice(String proPrice) {
this.proPrice = proPrice;
}
public Product() {
}
@Override
public String toString() {
return "Product [proAmount=" + proAmount + ", proPrice=" + proPrice
+ ", proStyle=" + proStyle + ", proSupplier=" + proSupplier
+ "]";
}
}
好了,運行上面程序,我們得到下面的數據,就是我們要獲得的最終數據

獲得數據成功,這就是我們要獲得最終的數據結果,最后我要說的是,此處這個網頁算是比較簡單的,而且,網頁源碼可以看到源數據,並且此方式是以get方式進行數據提交,真正采集的時候,有些網頁結構比較復雜,可能會存在着源碼里面沒有我們所要提取的數據,關於這一點的解決方式,以后給大家進行介紹。還有,我在采集這個頁面的時候,只是采集了當前頁面的數據,它還有分頁的數據,關於這個我此處不做講解,只是提示一點,我們可以采用多線程對所有分頁的當前數據進行采集,通過線程一個采集當前頁面數據,一個進行翻頁動作,就可以采集完所有數據。
我們匹配的數據可能在項目實際開發中,要求我們對所提取的數據要進行數據儲存,方便我們下一次進行數據的查詢操作。

