引言
應(yīng)用 Java 的開源庫,編寫一個(gè)搜索引擎,這個(gè)引擎能爬取一個(gè)網(wǎng)站的內(nèi)容。并根據(jù)網(wǎng)頁內(nèi)容進(jìn)行深度爬取,獲取所有相關(guān)的網(wǎng)頁地址和內(nèi)容,用戶可以通過關(guān)鍵詞,搜索所有相關(guān)的網(wǎng)址。
具體功能
(1) 用戶可以指定爬取一個(gè)url對(duì)應(yīng)的網(wǎng)頁的內(nèi)容。
(2) 對(duì)網(wǎng)頁內(nèi)容進(jìn)行解析,并獲取其中所有的url鏈接地址。
(3) 用戶可以設(shè)定爬取深度,代表著從初始url對(duì)應(yīng)的頁面開始,可以爬取其中所有的url對(duì)應(yīng)的網(wǎng)頁內(nèi)的url,以此類推。深度越大,能爬取到的網(wǎng)站越多。
(4) 對(duì)爬取到的url內(nèi)容進(jìn)行保存、建立索引。建立索引的內(nèi)容是url地址本身,和url對(duì)應(yīng)的網(wǎng)頁標(biāo)題。
(5) 用戶可以通過關(guān)鍵詞對(duì)網(wǎng)址進(jìn)行搜索,找出有該關(guān)鍵詞的url地址。
(6) 建立索引和搜索索引的過程能智能識(shí)別中文關(guān)鍵詞,能對(duì)關(guān)鍵詞進(jìn)行分詞操作。
(7) 用戶可以指定保存索引的地址、初始url、爬取深度、進(jìn)行搜索的關(guān)鍵詞和最大匹配項(xiàng)。
開源框架
- Lucene
- Jsoup
源碼
爬蟲部分:Spider.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
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
package webCrawler.Spider; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.Scanner; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import webCrawler.Index.BuildIndex; /** * @author lannooo */ public class Spider { ArrayList<String> URLs; private String startURL; private int digLevel; /** * @param startURL 爬蟲的起始URL * @param digLevel 爬取深度 */ public Spider(String startURL, int digLevel){ this .startURL = startURL; this .digLevel = digLevel; this .URLs = new ArrayList<>(); } /** * @param level 當(dāng)前爬取的深度剩余 * @param arrayList 需要進(jìn)行下一輪爬去的URL集 * @return 從一格url集爬取到的新的URL集 * @throws IOException */ public ArrayList<String> getLevelURLs( int level, ArrayList<String> arrayList) throws IOException{ ArrayList<String> total = null ; if (level> 0 ){ total = new ArrayList<>(); for (String url: arrayList){ /*對(duì)于每個(gè)arrayList中的URL,首先解析其網(wǎng)頁內(nèi)容,并獲得里面所有URL項(xiàng)*/ for(String each: getBareLinks(url)){ total.add(each); } } /*用HashSet這個(gè)容器將total里面重復(fù)項(xiàng)刪除*/ HashSet<String> hashSet = new HashSet<>(total); total = new ArrayList<>(hashSet); } return total; } /** * 從startURL開始,爬取所有相關(guān)URLs * @throws IOException */ public void getAll() throws IOException{ ArrayList<String> newURLs; ArrayList<String> currentURLs = new ArrayList<>(); /*把startURL加入currentURLs這個(gè)列表中,從這個(gè)url開始爬*/ currentURLs.add(startURL); for(int i=digLevel; i>0; i--){ /* * 對(duì)于每一層,都要獲取一次由這個(gè)url引申出去的url集 * 然后把當(dāng)前集的已經(jīng)爬去過的url加入到總的URL集中 * 最后newURLs作為新的需要進(jìn)行深度爬取的集進(jìn)入下一輪循環(huán) */ System.out.println("Dig into level: " + (digLevel-i+1)); newURLs = getLevelURLs(i, currentURLs); for(String each: currentURLs){ URLs.add(each); } currentURLs = newURLs; } for(String each:currentURLs){ URLs.add(each); } HashSet<String> hashSet = new HashSet<>(URLs); URLs = new ArrayList<>(hashSet); } /** * @param path 保存索引的路徑 * @throws IOException */ public void storeURLsAndInfo(String path) throws IOException{ BuildIndex build = new BuildIndex(path); /* 把URLs中的所有url進(jìn)行實(shí)際網(wǎng)頁標(biāo)題的爬取*/ for(String each:URLs){ String text = getLinkText(each); if(text!=null){ build.addField("url", each); build.addField("text", text); /*將這一個(gè)entry加入索引中*/ build.pushIndex(); } } build.close(); } /** * @param url 需要獲取網(wǎng)頁標(biāo)題的url * @return 標(biāo)題內(nèi)容 * @throws IOException */ public String getLinkText(String url) throws IOException{ Document document = null; try { /*用Jsoup進(jìn)行連接,設(shè)置超時(shí)時(shí)間為3秒*/ document = Jsoup.connect(url).timeout(3000).get(); } catch (Exception e) { System.out.println("[TIMEOUT]Get title of url:"+url); return null; } String id="codetool">
| ||||||