java實現網頁爬蟲的示例講解

java實現網頁爬蟲的示例講解

這一篇目的就是在於網頁爬蟲的實現,對資料的獲取,以便分析。

目錄:

1、爬蟲原理

2、本地檔案資料提取及分析

3、單網頁資料的讀取

4、運用正規表示式完成超連線的連線匹配和提取

5、廣度優先遍歷,多網頁的資料爬取

6、多執行緒的網頁爬取

7、總結

爬蟲實現原理

網路爬蟲基本技術處理

網路爬蟲是資料採集的一種方法,實際專案開發中,通過爬蟲做資料採集一般只有以下幾種情況:

1) 搜尋引擎

2) 競品調研

3) 輿情監控

4) 市場分析

網路爬蟲的整體執行流程:

1) 確定一個(多個)種子網頁

2) 進行資料的內容提取

3) 將網頁中的關聯網頁連線提取出來

4) 將尚未爬取的關聯網頁內容放到一個佇列中

5) 從佇列中取出一個待爬取的頁面,判斷之前是否爬過。

6) 把沒有爬過的進行爬取,並進行之前的重複操作。

7) 直到佇列中沒有新的內容,爬蟲執行結束。

這樣完成爬蟲時,會有一些概念必須知道的:

1) 深度(depth):一般來說,表示從種子頁到當前頁的開啟連線數,一般建議不要超過5層。

2) 廣度(寬度)優先和深度優先:表示爬取時的優先順序。建議使用廣度優先,按深度的層級來順序爬取。

Ⅰ  在進行網頁爬蟲前,我們先針對一個飛機事故失事的文件進行資料提取的練習,主要是溫習一下上一篇的java知識,也是為了下面爬蟲實現作一個熱身準備。

 首先分析這個文件,

,關於美國曆來每次飛機失事的資料,包含時間地點、駕駛員、死亡人數、總人數、事件描述,一共有12列,第一列是標題,下面一共有5268條資料。

 現在我要對這個檔案進行資料提取,並實現一下分析:  

根據飛機事故的資料文件來進行簡單資料統計。

1) 哪年出事故次數最多

2) 哪個時間段(上午 8 12,下午 12 18,晚上 18 24,凌晨 0 – 8 )事故出現次數最多。

3) 哪年死亡人數最多

4)哪條資料的倖存率最高。

程式碼實現:(一切知識從原始碼獲取!)


package com.plane;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 飛機事故統計
* @author k04
*sunwengang  
*2017-08-11
*/
public class planeaccident {
//資料獲取存取連結串列
private static List<String> alldata=new ArrayList<>();
public static void main(String args[]){      
getData("飛行事故資料統計_Since_1908.csv");
alldata.remove(0);
//System.out.println(alldata.size());
//死亡人數最多的年份
MaxDeadYear();
//事故發生次數最多的年份
MaxAccidentsYear();
//事故各個時間段發生的次數
FrequencyPeriod();
//幸村率最高的一條資料
MaximumSurvival();    
}
/**
* 從原始檔爬取資料
* getData(String filepath)
* @param filepath
*/
public static void getData(String filepath){
File f=new File(filepath);
//行讀取資料
try{
BufferedReader br=new BufferedReader(new FileReader(f));
String line=null;
while((line=(br.readLine()))!=null){
alldata.add(line);
}
br.close();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 記錄每年對應的死亡人數
* @throws 
* 並輸出死亡人數最多的年份,及該年死亡人數
*/
public static void MaxDeadYear(){
//記錄年份對應死亡人數
Map<Integer,Integer> map=new HashMap<>();
//時間用date顯示
SimpleDateFormat sdf=new SimpleDateFormat("MM/dd/YYYY");
//迴圈所有資料
for(String data:alldata){
//用逗號將資料分離,第一個是年份,第11個是死亡人數
String[] strs=data.split(",");
if(strs[0]!=null){
//獲取年份
try {
Date date=sdf.parse(strs[0]);
int year=date.getYear();
//判斷map中是否記錄過這個資料
if(map.containsKey(year)){
//已存在,則記錄數 該年死亡人數
map.put(year, map.get(year) Integer.parseInt(strs[10]));
}else{
map.put(year, Integer.parseInt(strs[10]));
}
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
}
//System.out.println(map);
//記錄死亡人數最多的年份
int max_year=-1;
//記錄死亡人數
int dead_count=0;
//用set無序獲取map中的key值,即年份
Set<Integer> keyset=map.keySet();
//
for(int year:keyset){
//當前年事故死亡最多的年份,記錄年和次數
if(map.get(year)>dead_count&&map.get(year)<10000){
max_year=year;
dead_count=map.get(year);
}
}
System.out.println("死亡人數最多的年份:" (max_year 1901) "  死亡人數:" dead_count);
}
/**
* 記錄事故次數最多的年份
* 輸出該年及事故次數
*/
public static void MaxAccidentsYear(){
//存放年份,該年的事故次數
Map<Integer,Integer> map=new HashMap<>();
SimpleDateFormat sdf =new SimpleDateFormat("MM/dd/YYYY");
//迴圈所有資料
for(String data:alldata){
String[] strs=data.split(",");
if(strs[0]!=null){
try {
Date date=sdf.parse(strs[0]);
//獲取年份
int year=date.getYear();
//判斷是否存在記錄
if(map.containsKey(year)){
//已存在記錄, 1
map.put(year, map.get(year) 1);
}else{
map.put(year, 1);
}
} catch (Exception e) {
// TODO Auto-generated catch block            
}                        
}
}
//記錄事故次數最多的年份
int max_year=0;
//該年事故發生次數
int acc_count=0;
//迴圈所有資料,獲取事故次數最多的年份
Set<Integer> keyset=map.keySet();
for(int year:keyset){
if(map.get(year)>acc_count){
max_year=year;
acc_count=map.get(year);
}
}
//輸出結果
System.out.println("事故次數最多的年份" (max_year 1901) " 該年事故發生次數:" acc_count);
}
/**
* FrequencyPeriod()
* 各個時間段發生事故的次數
*/
public static void FrequencyPeriod(){
//key為時間段,value為發生事故次數
Map<String,Integer> map=new HashMap<>();
//String陣列存放時間段
String[] strsTime={"上午(6:00~12:00)","下午(12:00~18:00)","晚上(18:00~24:00)","凌晨(0:00~6:00)"};
//小時:分鐘
SimpleDateFormat sdf=new SimpleDateFormat("HH:mm");
for(String data:alldata){
String[] strs=data.split(",");
//判斷時間是否記錄,未記錄則忽略
if(strs[1]!=null){
try {
Date date=sdf.parse(strs[1]);
//取得小時數
int hour=date.getHours();
//判斷小時數在哪個範圍中
int index=0;
if(hour>=12&&hour<18){
index=1;
}else if(hour>=18){
index=2;
}else if(hour<6){
index=3;
}
//記錄到map中
if(map.containsKey(strsTime[index])){
map.put(strsTime[index], map.get(strsTime[index]) 1);
}else{
map.put(strsTime[index], 1);
}                              
} catch (ParseException e) {            
}        
}
}
/*
System.out.println("各時間段發生事故次數:");
for(int i=0;i<strsTime.length;i  ){    
System.out.println(strsTime[i] " : " map.get(strsTime[i]));
}    
*/
// 記錄出事故最多的時間範圍
String maxTime = null;
// 記錄出事故最多的次數
int maxCount = 0;
Set<String> keySet = map.keySet();
for (String timeScope : keySet) {
if (map.get(timeScope) > maxCount) {
// 當前年就是出事故最多的年份,記錄下年和次數
maxTime = timeScope;
maxCount = map.get(timeScope);
}
}
System.out.println("發生事故次數最多的時間段:");
System.out.println(maxTime " : " maxCount);              
}
/**
* 獲取幸村率最高的一條資料的內容
* 返回該內容及倖存率
*/
public static void MaximumSurvival(){
//存放事故資訊以及該事故的幸村率
Map<String,Float> map=new HashMap<>();
//SimpleDateFormat sdf =new SimpleDateFormat("MM/dd/YYYY");
//事故倖存率=1-死亡率,第十一個是死亡人數,第十個是總人數
float survial=0;    
//迴圈所有資料
for(String data:alldata){
try{
String[] strs=data.split(",");
//計算倖存率
float m=Float.parseFloat(strs[10]);
float n=Float.parseFloat(strs[9]);
survial=1-m/n;
map.put(data, survial);
}catch(Exception e){
}
}
//記錄事故次數最多的年份
float max_survial=0;  
//倖存率最高的資料資訊
String this_data="null";
//迴圈所有資料,獲取事故次數最多的年份
Set<String> keyset=map.keySet();
for(String data:keyset){
if(map.get(data)>max_survial){
this_data=data;
max_survial=map.get(data);
}
}
System.out.println("倖存率最高的事故是:" this_data);
System.out.println("倖存率為:" survial);
}  
}

Ⅱ  接下來我們就可以在網頁的資料上下手了。

下面先實現一個單網頁資料提取的功能。

使用的技術可以有以下幾類

1) 原生程式碼實現:

  a) URL類

2) 使用第三方的URL庫

  a) HttpClient庫

3) 開源爬蟲框架

  a) Heritrix

  b) Nutch

【一】

先使用URL類,來將噹噹網下搜尋機械錶的內容提取出來。


package com.exe1;
/**
* 讀取噹噹網下機械錶的資料,並進行分析
* sunwengang  2017-08-13 20:00
*/
import java.io.*;
import java.net.*;
public class URLDemo {
public static void main(String args[]){
//確定爬取的網頁地址,此處為噹噹網搜機械錶顯示的網頁
//網址為    http://search.dangdang.com/?key=%BB%FA%D0%B5%B1%ED&act=input
String strurl="http://search.dangdang.com/?key=%BB%FA%D0%B5%B1%ED&act=input";
//建立url爬取核心物件
try {
URL url=new URL(strurl);
//通過url建立與網頁的連線
URLConnection conn=url.openConnection();
//通過連結取得網頁返回的資料
InputStream is=conn.getInputStream();
System.out.println(conn.getContentEncoding());
//一般按行讀取網頁資料,並進行內容分析
//因此用BufferedReader和InputStreamReader把位元組流轉化為字元流的緩衝流
//進行轉換時,需要處理編碼格式問題
BufferedReader br=new BufferedReader(new InputStreamReader(is,"UTF-8"));
//按行讀取並列印
String line=null;
while((line=br.readLine())!=null){
System.out.println(line);
}
br.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

結果顯示:

【二】

下面嘗試將這個網頁的原始碼儲存成為本地的一個文字檔案,以便後續做離線分析。

如果想根據條件提取網頁中的內容資訊,那麼就需要使用Java的正規表示式。

正規表示式

Java.util包下提供了Pattern和Matcher這兩個類,可以根據我們給定的條件來進行資料的匹配和提取。

通過Pattern類中提供的規則字元或字串,我們需要自己拼湊出我們的匹配規則。

正規表示式最常用的地方是用來做表單提交的資料格式驗證的

常用的正規表示式規則一般分為兩類:

1) 內容匹配

  a) \d:是否是數字

  b) \w:匹配 字母、數字或下劃線

  c) .:任意字元

  d) [a-z]:字元是否在給定範圍內。

2) 數量匹配

  a) :1個或以上

  b) *:0個或以上

  c) ?:0或1次

  d) {n,m}:n-m次

匹配手機電話號碼:

規則:1\\d{10}

匹配郵件地址:

規則:\\w @\\w .\\w (\\.\\w )?

通過Pattern和Matcher的配合,我們可以把一段內容中匹配我們要求的文字提取出來,方便我們來處理。

例如:將一段內容中的電話號碼提取出來。


public class PatternDemo {
public static void main(String[] args) {
Pattern p = Pattern.compile("1\\d{10}");
String content = "<div><div class='jg666'>[轉讓]<a href='/17610866588' title='手機號碼17610866588估價評估_值多少錢_歸屬地查詢_測吉凶_數字含義_求購轉讓資訊' class='lj44'>17610866588</a>由 張雲龍 300元轉讓,聯絡電話:17610866588</div><div class='jg666'>[轉讓]<a href='/17777351513' title='手機號碼17777351513估價評估_值多少錢_歸屬地查詢_測吉凶_數字含義_求購轉讓資訊' class='lj44'>17777351513</a>由 胡俊巨集 888元轉讓,QQ:762670775,聯絡電話:17777351513,可以小砍價..</div><div class='jg666'>[求購]<a href='/15019890606' title='手機號碼15019890606估價評估_值多少錢_歸屬地查詢_測吉凶_數字含義_求購轉讓資訊' class='lj44'>15019890606</a>由 張寶紅 600元求購,聯絡電話:15026815169</div><div class='jg666'>";
Matcher m = p.matcher(content);
// System.out.println(p.matcher("[email protected]").matches());
Set<String> set = new HashSet<>();
// 通過Matcher類的group方法和find方法來進行查詢和匹配
while (m.find()) {
String value = m.group();
set.add(value);
}
System.out.println(set);
}
}

通過正規表示式完成超連線的連線匹配和提取

對爬取的HTML頁面來說,如果想提取連線地址,就必須找到所有超連線的標籤和對應的屬性。

超連線標籤是<a></a>,儲存連線的屬性是:href。

<a href=”…”>…</a>

規則:

<a .*href=. </a>

廣度優先遍歷

需要有一個佇列(這裡直接使用ArrayList來作為佇列)儲存所有等待爬取的連線。

還需要一個Set集合記錄下所有已經爬取過的連線。

還需要一個深度值,記錄當前爬取的網頁深度,判斷是否滿足要求

此時對當當網首頁分類裡的圖書進行深度為2的網頁爬取,參照上述對機械錶單網頁的爬取,利用遞迴的方式進行資料獲取存到E:/dangdang_book/目錄下:


package com.exe1;
/**
* 讀取噹噹網下首頁圖書的資料,並進行分析
* 爬取深度為2
* 爬去資料儲存到E:/dangdang_book/目錄下,需自行建立
* sunwengang  2017-08-13 20:00
*/
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
public class URLDemo {
//提取的資料存放到該目錄下
private static String savepath="E:/dangdang_book/";
//等待爬取的url
private static List<String> allwaiturl=new ArrayList<>();
//爬取過的url
private static Set<String> alloverurl=new HashSet<>();
//記錄所有url的深度進行爬取判斷
private static Map<String,Integer> allurldepth=new HashMap<>();
//爬取得深度
private static int maxdepth=2;
public static void main(String args[]){
//確定爬取的網頁地址,此處為噹噹網首頁上的圖書分類進去的網頁
//網址為    http://book.dangdang.com/
//    String strurl="http://search.dangdang.com/?key=%BB%FA%D0%B5%B1%ED&act=input";
String strurl="http://book.dangdang.com/";
workurl(strurl,1);
}
public static void workurl(String strurl,int depth){
//判斷當前url是否爬取過
if(!(alloverurl.contains(strurl)||depth>maxdepth)){
//建立url爬取核心物件
try {
URL url=new URL(strurl);
//通過url建立與網頁的連線
URLConnection conn=url.openConnection();
//通過連結取得網頁返回的資料
InputStream is=conn.getInputStream();
System.out.println(conn.getContentEncoding());
//一般按行讀取網頁資料,並進行內容分析
//因此用BufferedReader和InputStreamReader把位元組流轉化為字元流的緩衝流
//進行轉換時,需要處理編碼格式問題
BufferedReader br=new BufferedReader(new InputStreamReader(is,"GB2312"));
//按行讀取並列印
String line=null;
//正規表示式的匹配規則提取該網頁的連結
Pattern p=Pattern.compile("<a .*href=. </a>");
//建立一個輸出流,用於儲存檔案,檔名為執行時間,以防重複
PrintWriter pw=new PrintWriter(new File(savepath System.currentTimeMillis() ".txt"));
while((line=br.readLine())!=null){
//System.out.println(line);
//編寫正則,匹配超連結地址
pw.println(line);
Matcher m=p.matcher(line);
while(m.find()){
String href=m.group();
//找到超連結地址並擷取字串
//有無引號
href=href.substring(href.indexOf("href="));
if(href.charAt(5)=='\"'){
href=href.substring(6);
}else{
href=href.substring(5);
}
//擷取到引號或者空格或者到">"結束
try{
href=href.substring(0,href.indexOf("\""));
}catch(Exception e){
try{
href=href.substring(0,href.indexOf(" "));
}catch(Exception e1){
href=href.substring(0,href.indexOf(">"));
}
}
if(href.startsWith("http:")||href.startsWith("https:")){
//輸出該網頁存在的連結
//System.out.println(href);
//將url地址放到佇列中
allwaiturl.add(href);
allurldepth.put(href,depth 1);
}
}
}
pw.close();
br.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//將當前url歸列到alloverurl中
alloverurl.add(strurl);
System.out.println(strurl "網頁爬取完成,已爬取數量:" alloverurl.size() ",剩餘爬取數量:" allwaiturl.size());
}
//用遞迴的方法繼續爬取其他連結
String nexturl=allwaiturl.get(0);
allwaiturl.remove(0);
workurl(nexturl,allurldepth.get(nexturl));        
}
}

控制檯顯示:

本地目錄顯示:

但是,僅是深度為2的也執行不短地時間,

如果想提高爬蟲效能,那麼我們就需要使用多執行緒來處理,例如:準備好5個執行緒來同時進行爬蟲操作。

這些執行緒需要標註出當前狀態,是在等待,還是在爬取。

如果是等待狀態,那麼就需要取得集合中的一個連線,來完成爬蟲操作。

如果是爬取狀態,則在爬完以後,需要變為等待狀態。

多執行緒中如果想設定等待狀態,有一個方法可以實現:wait(),如果想從等待狀態喚醒,則可以使用notify()。

因此在多個執行緒中間我們需要一個物件來幫助我們進行執行緒之間的通訊,以便喚醒其它執行緒。

多執行緒同時處理時,容易出現執行緒不安全的問題,導致資料出現錯誤。

為了保證執行緒的安全,就需要使用同步關鍵字,來對取得連線和放入連線操作加鎖。

多執行緒爬蟲實現

需要先自定義一個執行緒的操作類,在這個操作類中判斷不同的狀態,並且根據狀態來決定是進行wait()等待,還是取得一個新的url進行處理


package com.exe1;
/**
* 讀取噹噹網下首頁圖書的資料,並進行分析
* 爬取深度為2
* 爬去資料儲存到E:/dangdang_book/目錄下,需自行建立
* 孫文剛  2017-08-13 20:00
*/
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
public class URLDemo {
//提取的資料存放到該目錄下
private static String savepath="E:/dangdang_book/";
//等待爬取的url
private static List<String> allwaiturl=new ArrayList<>();
//爬取過的url
private static Set<String> alloverurl=new HashSet<>();
//記錄所有url的深度進行爬取判斷
private static Map<String,Integer> allurldepth=new HashMap<>();
//爬取得深度
private static int maxdepth=2;
//生命物件,幫助進行執行緒的等待操作
private static Object obj=new Object();
//記錄匯流排程數5條
private static int MAX_THREAD=5;
//記錄空閒的執行緒數
private static int count=0;
public static void main(String args[]){
//確定爬取的網頁地址,此處為噹噹網首頁上的圖書分類進去的網頁
//網址為    http://book.dangdang.com/
//    String strurl="http://search.dangdang.com/?key=%BB%FA%D0%B5%B1%ED&act=input";
String strurl="http://book.dangdang.com/";
//workurl(strurl,1);
addurl(strurl,0);
for(int i=0;i<MAX_THREAD;i  ){
new URLDemo().new MyThread().start();
}
}
/**
* 網頁資料爬取
* @param strurl
* @param depth
*/
public static void workurl(String strurl,int depth){
//判斷當前url是否爬取過
if(!(alloverurl.contains(strurl)||depth>maxdepth)){
//檢測執行緒是否執行
System.out.println("當前執行:" Thread.currentThread().getName() " 爬取執行緒處理爬取:" strurl);
//建立url爬取核心物件
try {
URL url=new URL(strurl);
//通過url建立與網頁的連線
URLConnection conn=url.openConnection();
//通過連結取得網頁返回的資料
InputStream is=conn.getInputStream();
//提取text型別的資料
if(conn.getContentType().startsWith("text")){
}
System.out.println(conn.getContentEncoding());
//一般按行讀取網頁資料,並進行內容分析
//因此用BufferedReader和InputStreamReader把位元組流轉化為字元流的緩衝流
//進行轉換時,需要處理編碼格式問題
BufferedReader br=new BufferedReader(new InputStreamReader(is,"GB2312"));
//按行讀取並列印
String line=null;
//正規表示式的匹配規則提取該網頁的連結
Pattern p=Pattern.compile("<a .*href=. </a>");
//建立一個輸出流,用於儲存檔案,檔名為執行時間,以防重複
PrintWriter pw=new PrintWriter(new File(savepath System.currentTimeMillis() ".txt"));
while((line=br.readLine())!=null){
//System.out.println(line);
//編寫正則,匹配超連結地址
pw.println(line);
Matcher m=p.matcher(line);
while(m.find()){
String href=m.group();
//找到超連結地址並擷取字串
//有無引號
href=href.substring(href.indexOf("href="));
if(href.charAt(5)=='\"'){
href=href.substring(6);
}else{
href=href.substring(5);
}
//擷取到引號或者空格或者到">"結束
try{
href=href.substring(0,href.indexOf("\""));
}catch(Exception e){
try{
href=href.substring(0,href.indexOf(" "));
}catch(Exception e1){
href=href.substring(0,href.indexOf(">"));
}
}
if(href.startsWith("http:")||href.startsWith("https:")){
/*
//輸出該網頁存在的連結
//System.out.println(href);
//將url地址放到佇列中
allwaiturl.add(href);
allurldepth.put(href,depth 1);
*/
//呼叫addurl方法
addurl(href,depth);
}
}
}
pw.close();
br.close();
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
//將當前url歸列到alloverurl中    
alloverurl.add(strurl);    
System.out.println(strurl "網頁爬取完成,已爬取數量:" alloverurl.size() ",剩餘爬取數量:" allwaiturl.size());
}
/*
//用遞迴的方法繼續爬取其他連結
String nexturl=allwaiturl.get(0);
allwaiturl.remove(0);
workurl(nexturl,allurldepth.get(nexturl));
*/
if(allwaiturl.size()>0){
synchronized(obj){
obj.notify();
}
}else{
System.out.println("爬取結束.......");
}
}
/**
* 將獲取的url放入等待佇列中,同時判斷是否已經放過
* @param href
* @param depth
*/
public static synchronized void addurl(String href,int depth){
//將url放到佇列中
allwaiturl.add(href);
//判斷url是否放過
if(!allurldepth.containsKey(href)){
allurldepth.put(href, depth 1);
}
}
/**
* 移除爬取完成的url,獲取下一個未爬取得url
* @return
*/
public static synchronized String geturl(){
String nexturl=allwaiturl.get(0);
allwaiturl.remove(0);
return nexturl;
}
/**
* 執行緒分配任務
*/
public class MyThread extends Thread{
@Override
public void run(){
//設定一個死迴圈,讓執行緒一直存在
while(true){
//判斷是否新連結,有則獲取
if(allwaiturl.size()>0){
//獲取url進行處理
String url=geturl();
//呼叫workurl方法爬取
workurl(url,allurldepth.get(url));
}else{
System.out.println("當前執行緒準備就緒,等待連線爬取:" this.getName());
count  ;
//建立一個物件,讓執行緒進入等待狀態,即wait()
synchronized(obj){
try{
obj.wait();
}catch(Exception e){
}
}
count--;
}
}
}
}
}

控制檯顯示:

本地目錄顯示:

總結:

對於網頁資料爬取,用到了執行緒,類集處理,繼承,正規表示式等各方面的知識,從一個網頁以深度為主,廣度為基本進行爬取,獲取每一個網頁的原始碼,並寫入到一個本地的目錄下。

1、給出一個網頁連結,建立一個本地目錄;

2、用URL類本地連線,用字元流進行讀取,並寫入到本地;

3、利用正規表示式在按行讀取時獲取該網頁所存在的所有連結,以便進行深度 1的資料收集;

4、利用遞迴的方法,藉助容器list,Set,Map來對連結進行爬取和未爬取得劃分;

5、每次爬取一個網頁時,所獲得的所有連結在當前基礎上深度 1,並且從未爬取佇列中移除,加入到已爬取佇列中;

6、為提升效能,在進行遞迴的時候,可以利用執行緒,複寫Thread的run()方法,用多執行緒進行網頁資料爬取;

7、直到爬取得網頁深度達到你期望的深度時,爬取結束,此時可以檢視本地目錄生成的檔案;

8、後續對本地生成的檔案進行資料分析,即可獲取你想要的資訊。

藉此,我們就可以對這些資料進行歸約,分析,處理,來獲取我們想要的資訊。

這也是大資料資料收集的一個基礎。

以上這篇java實現網頁爬蟲的示例講解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援指令碼之家。

您可能感興趣的文章:

java實現一個簡單的網路爬蟲程式碼示例分享一個簡單的java爬蟲框架JAVA超級簡單的爬蟲例項講解hadoop中實現java網路爬蟲(示例講解)java 爬蟲詳解及簡單例項Java爬蟲Jsoup httpclient獲取動態生成的資料Java 爬蟲工具Jsoup詳解java網路爬蟲連線超時解決例項程式碼