一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java 實現網絡爬蟲框架詳細代碼

Java 實現網絡爬蟲框架詳細代碼

2021-12-22 12:50冰 河 Java教程

這篇文章主要介紹了Java 實現網絡爬蟲框架,主要是用于爬取網絡上一些內容,比如超鏈接之類的,需要的朋友可以參考下面文章內容

Java 實現網絡爬蟲框架

最近在做一個搜索相關的項目,需要爬取網絡上的一些鏈接存儲到索引庫中,雖然有很多開源的強大的爬蟲框架,但本著學習的態度,自己寫了一個簡單的網絡爬蟲,以便了解其中的原理。今天,就為小伙伴們分享下這個簡單的爬蟲程序!!

一、每個類的功能介紹

  • DownloadPage.java的功能是下載此超鏈接的頁面源代碼.
  • FunctionUtils.java 的功能是提供不同的靜態方法,包括:頁面鏈接正則表達式匹配,獲取URL鏈接的元素,判斷是否創建文件,獲取頁面的Url并將其轉換為規范的Url,截取網頁網頁源文件的目標內容。
  • HrefOfPage.java 的功能是獲取頁面源代碼的超鏈接。
  • UrlDataHanding.java 的功能是整合各個給類,實現url到獲取數據到數據處理類。
  • UrlQueue.java 的未訪問Url隊列。
  • VisitedUrlQueue.java 已訪問過的URL隊列。

二、每個類的源代碼

DownloadPage.java 此類要用到HttpClient組件。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.sreach.spider;
 
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
 
/**
 * @author binghe
 */
public class DownloadPage {
 
 /**
  * 根據URL抓取網頁內容
  *
  * @param url
  * @return
  */
 public static String getContentFormUrl(String url) {
  /* 實例化一個HttpClient客戶端 */
  HttpClient client = new DefaultHttpClient();
  HttpGet getHttp = new HttpGet(url);
 
  String content = null;
 
  HttpResponse response;
  try {
   /* 獲得信息載體 */
   response = client.execute(getHttp);
   HttpEntity entity = response.getEntity();
 
   VisitedUrlQueue.addElem(url);
 
   if (entity != null) {
    /* 轉化為文本信息 */
    content = EntityUtils.toString(entity);
 
    /* 判斷是否符合下載網頁源代碼到本地的條件 */
    if (FunctionUtils.isCreateFile(url)
      && FunctionUtils.isHasGoalContent(content) != -1) {
     FunctionUtils.createFile(
       FunctionUtils.getGoalContent(content), url);
    }
   }
 
  } catch (ClientProtocolException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   client.getConnectionManager().shutdown();
  }
 
  return content;
 }
 
}

 FunctionUtils.java 此類的方法均為static方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package com.sreach.spider;
 
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author binghe
 */
public class FunctionUtils {
 
 /**
  * 匹配超鏈接的正則表達式
  */
 private static String pat = "http://www\\.oschina\\.net/code/explore/.*/\\w+\\.[a-zA-Z]+";
 private static Pattern pattern = Pattern.compile(pat);
 
 private static BufferedWriter writer = null;
 
 /**
  * 爬蟲搜索深度
  */
 public static int depth = 0;
 
 /**
  * 以"/"來分割URL,獲得超鏈接的元素
  *
  * @param url
  * @return
  */
 public static String[] divUrl(String url) {
  return url.split("/");
 }
 
 /**
  * 判斷是否創建文件
  *
  * @param url
  * @return
  */
 public static boolean isCreateFile(String url) {
  Matcher matcher = pattern.matcher(url);
 
  return matcher.matches();
 }
 
 /**
  * 創建對應文件
  *
  * @param content
  * @param urlPath
  */
 public static void createFile(String content, String urlPath) {
  /* 分割url */
  String[] elems = divUrl(urlPath);
  StringBuffer path = new StringBuffer();
 
  File file = null;
  for (int i = 1; i < elems.length; i++) {
   if (i != elems.length - 1) {
 
    path.append(elems[i]);
    path.append(File.separator);
    file = new File("D:" + File.separator + path.toString());
 
   }
 
   if (i == elems.length - 1) {
    Pattern pattern = Pattern.compile("\\w+\\.[a-zA-Z]+");
    Matcher matcher = pattern.matcher(elems[i]);
    if ((matcher.matches())) {
     if (!file.exists()) {
      file.mkdirs();
     }
     String[] fileName = elems[i].split("\\.");
     file = new File("D:" + File.separator + path.toString()
       + File.separator + fileName[0] + ".txt");
     try {
      file.createNewFile();
      writer = new BufferedWriter(new OutputStreamWriter(
        new FileOutputStream(file)));
      writer.write(content);
      writer.flush();
      writer.close();
      System.out.println("創建文件成功");
     } catch (IOException e) {
      e.printStackTrace();
     }
 
    }
   }
 
  }
 }
 
 /**
  * 獲取頁面的超鏈接并將其轉換為正式的A標簽
  *
  * @param href
  * @return
  */
 public static String getHrefOfInOut(String href) {
  /* 內外部鏈接最終轉化為完整的鏈接格式 */
  String resultHref = null;
 
  /* 判斷是否為外部鏈接 */
  if (href.startsWith("http://")) {
   resultHref = href;
  } else {
   /* 如果是內部鏈接,則補充完整的鏈接地址,其他的格式忽略不處理,如:a href="#" rel="external nofollow"  */
   if (href.startsWith("/")) {
    resultHref = "http://www.oschina.net" + href;
   }
  }
 
  return resultHref;
 }
 
 /**
  * 截取網頁網頁源文件的目標內容
  *
  * @param content
  * @return
  */
 public static String getGoalContent(String content) {
  int sign = content.indexOf("<pre class=\"");
  String signContent = content.substring(sign);
 
  int start = signContent.indexOf(">");
  int end = signContent.indexOf("</pre>");
 
  return signContent.substring(start + 1, end);
 }
 
 /**
  * 檢查網頁源文件中是否有目標文件
  *
  * @param content
  * @return
  */
 public static int isHasGoalContent(String content) {
  return content.indexOf("<pre class=\"");
 }
 
}

HrefOfPage.java 此類為獲取頁面的超鏈接

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.sreach.spider;
/**
 * @author binghe
 *
 */
public class HrefOfPage {
 /**
  * 獲得頁面源代碼中超鏈接
  */
 public static void getHrefOfContent(String content) {
  System.out.println("開始");
  String[] contents = content.split("<a href=\"");
  for (int i = 1; i < contents.length; i++) {
   int endHref = contents[i].indexOf("\"");
 
   String aHref = FunctionUtils.getHrefOfInOut(contents[i].substring(
     0, endHref));
 
   if (aHref != null) {
    String href = FunctionUtils.getHrefOfInOut(aHref);
 
    if (!UrlQueue.isContains(href)
      && href.indexOf("/code/explore") != -1
      && !VisitedUrlQueue.isContains(href)) {
     UrlQueue.addElem(href);
    }
   }
  }
 
  System.out.println(UrlQueue.size() + "--抓取到的連接數");
  System.out.println(VisitedUrlQueue.size() + "--已處理的頁面數");
 
 }
 
}

UrlDataHanding.java 此類主要是從未訪問隊列中獲取url,下載頁面,分析url,保存已訪問url等操作,實現Runnable接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.sreach.spider;
/**
 * @author binghe
 *
 */
public class UrlDataHanding implements Runnable {
 /**
  * 下載對應頁面并分析出頁面對應的URL放在未訪問隊列中。
  *
  * @param url
  */
 public void dataHanding(String url) {
  HrefOfPage.getHrefOfContent(DownloadPage.getContentFormUrl(url));
 }
 
 public void run() {
  while (!UrlQueue.isEmpty()) {
   dataHanding(UrlQueue.outElem());
  }
 }
}

UrlQueue.java 此類主要是用來存放未訪問的URL隊列

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.sreach.spider;
 
import java.util.LinkedList;
/**
 * @author binghe
 *
 */
public class UrlQueue {
 /** 超鏈接隊列 */
 public static LinkedList<String> urlQueue = new LinkedList<String>();
 
 /** 隊列中對應最多的超鏈接數量 */
 public static final int MAX_SIZE = 10000;
 
 public synchronized static void addElem(String url) {
  urlQueue.add(url);
 }
 
 public synchronized static String outElem() {
  return urlQueue.removeFirst();
 }
 
 public synchronized static boolean isEmpty() {
  return urlQueue.isEmpty();
 }
 
 public static int size() {
  return urlQueue.size();
 }
 
 public static boolean isContains(String url) {
  return urlQueue.contains(url);
 }
 
}

VisitedUrlQueue.java 主要是保存已訪問過的URL,使用HashSet來保存,主要是考慮到每個訪問過的URL是不同。HashSet剛好符合這個要求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.sreach.spider;
 
import java.util.HashSet;
 
/**
 * 已訪問url隊列
 * @author binghe
 *
 */
public class VisitedUrlQueue {
 public static HashSet<String> visitedUrlQueue = new HashSet<String>();
 
 public synchronized static void addElem(String url) {
  visitedUrlQueue.add(url);
 }
 
 public synchronized static boolean isContains(String url) {
  return visitedUrlQueue.contains(url);
 }
 
 public synchronized static int size() {
  return visitedUrlQueue.size();
 }
}

Test.java 此類為測試類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.sql.SQLException;
 
import com.sreach.spider.UrlDataHanding;
import com.sreach.spider.UrlQueue;
/**
 * @author binghe
 *
 */
public class Test {
 public static void main(String[] args) throws SQLException {
  String url = "http://www.oschina.net/code/explore/achartengine/client/AndroidManifest.xml";
  String url1 = "http://www.oschina.net/code/explore";
  String url2 = "http://www.oschina.net/code/explore/achartengine";
  String url3 = "http://www.oschina.net/code/explore/achartengine/client";
 
  UrlQueue.addElem(url);
  UrlQueue.addElem(url1);
  UrlQueue.addElem(url2);
  UrlQueue.addElem(url3);
 
  UrlDataHanding[] url_Handings = new UrlDataHanding[10];
 
  for (int i = 0; i < 10; i++) {
   url_Handings[i] = new UrlDataHanding();
   new Thread(url_Handings[i]).start();
  }
 
 }
}

說明一下:由于我抓取的是針對oschina的,所以里面的url正則表達式不適合其他網站,需要自己修改一下。你也可以寫成xml來配置。

以上就是Java 實現網絡爬蟲框架詳細代碼的詳細內容,更多關于Java 實現網絡爬蟲框架的資料請關注服務器之家其它相關文章!

原文鏈接:https://blog.csdn.net/l1028386804/article/details/118324379

延伸 · 閱讀

精彩推薦
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
主站蜘蛛池模板: 亚洲青草视频 | 青青草国产青春综合久久 | 青草青青在线视频 | 欧美一区二区三区不卡视频 | 短篇同学新婚h系列小说 | 91视频免费观看网站 | 日本xxx片免费高清在线 | 欧美在线视频 一区二区 | 白丝vk丨tk失禁 | 色偷偷91久久综合噜噜噜 | www.色姐姐 | sese在线观看 | 欧式午夜理伦三级在线观看 | 我与么公激情性完整视频 | 红杏劫 | 久久全国免费久久青青小草 | 国产精品理论片在线观看 | 亚洲高清成人 | 楚乔传第二部全60集免费观看 | 久久内在线视频精品mp4 | 天天性综合 | 国产专区日韩精品欧美色 | 亚洲国产成人精品不卡青青草原 | 久久久GOGO无码啪啪艺术 | www.av色| 天天拍天天色 | 欧美国产日韩综合 | a国产在线| 国产精品不卡 | 男人的j伸到女人的屁股眼 男人吃奶动态图 | 欧美日韩亚毛片免费观看 | 欧美在线一二三区 | 日本 视频 在线 | 亚洲大片免费看 | 免费全看男女拍拍拍的视频 | 兽皇日本 | 故意短裙公车被强好爽在线播放 | 亚洲国产精品日韩高清秒播 | 精品久久久久久无码人妻国产馆 | 人人人人看人人人做人人 | 高清毛片一区二区三区 |