java網頁數據抓取實例


原文鏈接

在很多行業中,要對行業數據進行分類匯總,及時分析行業數據,對於公司未來的發展,有很好的參照和橫向對比。所以,在實際工作,我們可能要遇到數據采集這個概念,數據采集的最終目的就是要獲得數據,提取有用的數據進行數據提取和數據分類匯總。

很多人在第一次了解數據采集的時候,可能無從下手,尤其是作為一個新手,更是感覺很是茫然,所以,在這里分享一下自己的心得,希望和大家一起分享技術,如果有什么不足,還請大家指正。寫出這篇目的,就是希望大家一起成長,我也相信技術之間沒有高低,只有互補,只有分享,才能使彼此更加成長。

在網頁數據采集的時候,我們往往要經過這幾個大的步驟:

①通過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方式進行數據提交,真正采集的時候,有些網頁結構比較復雜,可能會存在着源碼里面沒有我們所要提取的數據,關於這一點的解決方式,以后給大家進行介紹。還有,我在采集這個頁面的時候,只是采集了當前頁面的數據,它還有分頁的數據,關於這個我此處不做講解,只是提示一點,我們可以采用多線程對所有分頁的當前數據進行采集,通過線程一個采集當前頁面數據,一個進行翻頁動作,就可以采集完所有數據。

我們匹配的數據可能在項目實際開發中,要求我們對所提取的數據要進行數據儲存,方便我們下一次進行數據的查詢操作。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM