如何使用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,你可以簡單的使用
這裡我使用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的示例圖:
四、使用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資料庫,如下所示: