1. 程式人生 > >如何使用Java語言實現一個網頁爬蟲

如何使用Java語言實現一個網頁爬蟲

 網路上有許多資訊,我們如何自動的獲取這些資訊呢?沒錯,網頁爬蟲~!
在這篇博文中,我將會使用java語言一步一步的編寫一個原型的網頁爬蟲,其實網頁爬蟲並沒有它聽起來那麼難。緊跟我的教程,我相信你會在馬上學會,一個小時應該可以搞定,之後你就可以享受你所獲得的大量資料。這次所編寫的是最簡單的教程,可以說是網頁爬蟲的hello world程式, 由於僅僅是原型,之後你要花更多的時間來研究並未自己來定製特定需求的爬蟲。
首先,我認為你已經掌握了下面的基礎知識:
   1.基礎的java程式設計
   2.關於sql以及mysql資料庫或者oracle資料庫
如果你不想使用資料庫的話,你可以用一個檔案來將爬到的資料儲存好。

一、我們的目標
給定一個學校的URL,例如“mit.edu”,返回包括字串“research”所有的這個學校的頁面。
一個經典的爬蟲程式步驟:
1.解析根網頁(“mit.edu”),並從這個網頁得到它所有的連結。獲取每個URL並解析HTML頁面,我會使用Jsoup來處理,Jsoup是一個好用而且方便的java庫。
2.使用步驟1返回回來的URL,解析這些URL。
3.當我們在做上面兩個步驟的時候,我們需要跟蹤哪些頁面是之前已經被處理了的,那樣的話,每個頁面只需被處理一次。這也是我們為什麼需要資料庫的原因了。

二、建立Mysql資料庫
  如果你使用的是ubuntu, 你可以使用經典的Apache, MySQL, PHP, and phpMyAdmin來操作。
  如果你是用的是windows,你可以簡單的使用

wampServer或者SQLlog並安裝,也可以使用oracle資料庫,可以使用PLSQL developer工具。
  這裡我使用mysql sqllog工具,它是使用mysql資料化的一個視覺化的GUI工具,當然你也可以使用其他的工具或者方法。
  
  

三、建立資料庫以及表
建立一個數據庫名為:Crawler,建立一個表,名為:Record

下面是一個oracle sql 指令碼

CREATE TABLE Record (--建立表
  RecordID integer NOT NULL primary key,
  URL varchar2(200
) NOT NULL );
CREATE SEQUENCE RecordID_Sequence--建立序列 INCREMENT BY 1 -- 每次加幾個 START WITH 1 -- 從1開始計數 NOMAXVALUE -- 不設定最大值 NOCYCLE; -- 一直累加,不迴圈 CREATE TRIGGER record_increase BEFORE--建立觸發器 insert ON Record FOR EACH ROW begin select RecordID_Sequence.nextval into:New.RecordID from dual; end;

如果是mysql的話,如此執行:

CREATE TABLE IF NOT EXISTS `Record` (
  `RecordID` INT(11) NOT NULL AUTO_INCREMENT,
  `URL` TEXT NOT NULL,
  PRIMARY KEY (`RecordID`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

下圖是使用pl/sql的示例圖:

sql


四、使用Java開始爬蟲
1. 下載Jsoup核心庫,點選這裡下載
“`
這裡寫圖片描述

如果使用oracle資料庫, 你需要下載oracle的JDBC驅動jar包,ojdbc14.jar包
如果使用mysql資料庫,那麼需要下載mysql-connector-java 的jar包

2. 在Eclipse中建立專案,並將Jsoup庫jar以及ojdbc14.jar也加入到Java Build Path(右鍵點選專案,選擇build path—>”Configure Build Path” –> click “Libraries” tab –> click “Add External JARs”)
3. 建立一個DB類,來處理資料庫的操作。


package crawlerDemo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DB {

    public Connection conn = null;

    public DB() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/Crawler";
            conn = DriverManager.getConnection(url, "wonderq", "root");
            System.out.println("conn built");
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public ResultSet runSql(String sql) throws SQLException {
        Statement sta = conn.createStatement();
        return sta.executeQuery(sql);
    }

    public boolean runSql2(String sql) throws SQLException {
        Statement sta = conn.createStatement();
        return sta.execute(sql);
    }

    @Override
    protected void finalize() throws Throwable {
        if (conn != null || !conn.isClosed()) {
            conn.close();
        }
    }
    public static void main(String[] args) {
        new DB();
    }
}

4.建立一個名為“Main”的類,這個類將是我們的爬蟲

package crawlerDemo;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;


public class Main {
    public static DB db = new DB();

    public static void main(String[] args) throws SQLException, IOException {
        db.runSql2("TRUNCATE Record;");
        processPage("http://www.mit.edu");
    }

    public static void processPage(String URL) throws SQLException, IOException{
        //檢查一下是否給定的URL已經在資料庫中
        String sql = "select * from Record where URL = '"+URL+"'";
        ResultSet rs = db.runSql(sql);
        if(rs.next()){

        }else{
            //將uRL儲存到資料庫中避免下次重複
            sql = "INSERT INTO  `Crawler`.`Record` " + "(`URL`) VALUES " + "(?);";
            PreparedStatement stmt = db.conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            stmt.setString(1, URL);
            stmt.execute();

            //得到有用的資訊
            Document doc = Jsoup.connect("http://www.mit.edu/").get();

            if(doc.text().contains("research")){
                System.out.println(URL);
            }

            //得到所有的連結,並遞迴呼叫
            Elements questions = doc.select("a[href]");
            for(Element link: questions){
                if(link.attr("href").contains("mit.edu"))
                    processPage(link.attr("abs:href"));
            }
        }
    }
}

現在你已經得到了自己的爬蟲,run一下, 看看結果吧。
這裡寫圖片描述


檢視mysql資料庫,如下所示:

這裡寫圖片描述