更新時(shí)間:2022-11-18 14:49:15 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2104次
我們將構(gòu)建一個(gè)使用 BFS 算法遍歷網(wǎng)頁(yè)的網(wǎng)絡(luò)爬蟲(chóng)。
爬蟲(chóng)將從訪問(wèn)包含的每個(gè) URL 的源 URL 開(kāi)始。訪問(wèn)此源 URL 中的每個(gè) URL 后,該算法將訪問(wèn)子 URL 中的每個(gè) URL 并向下訪問(wèn)鏈,直到它到達(dá)您將指定的斷點(diǎn)。
該算法將僅訪問(wèn)以前未訪問(wèn)過(guò)的 URL,以確保我們不會(huì)循環(huán)訪問(wèn)。這些 URL 代表頂點(diǎn),URL 之間的連接是邊。
首先將根 URL 添加到隊(duì)列和已訪問(wèn) URL 列表。
當(dāng)隊(duì)列不為空時(shí),從隊(duì)列中刪除 URL 并讀取其原始 HTML 內(nèi)容。
在讀取 URL 的 HTML 內(nèi)容時(shí),搜索父 HTML 中包含的任何其他 URL。
當(dāng)找到新的 URL 時(shí),通過(guò)檢查已訪問(wèn)的 URL 列表來(lái)驗(yàn)證它以前沒(méi)有被訪問(wèn)過(guò)。
將新找到的未訪問(wèn) URL 添加到隊(duì)列和已訪問(wèn) URL 列表中。
對(duì)在 HTML 內(nèi)容中找到的每個(gè)新 URL 重復(fù)步驟 4 和 5。
找到 HTML 中的所有 URL 后,從步驟 2 開(kāi)始重復(fù),直到程序到達(dá)您指定的斷點(diǎn)。
使用名稱(chēng)創(chuàng)建一個(gè) Java 類(lèi)WebCrawler并將以下代碼添加到文件中:
public class WebCrawler {
private Queue<String> urlQueue;
private List<String> visitedURLs;
public WebCrawler() {
urlQueue = new LinkedList<>();
visitedURLs = new ArrayList<>();
}
}
在上面的代碼中,我們已經(jīng)初始化了我們隨后將要使用的類(lèi)、數(shù)據(jù)結(jié)構(gòu)和構(gòu)造函數(shù)。
public void crawl(String rootURL, int breakpoint) {
urlQueue.add(rootURL);
visitedURLs.add(rootURL);
while(!urlQueue.isEmpty()){
// remove the next url string from the queue to begin traverse.
String s = urlQueue.remove();
String rawHTML = "";
try{
// create url with the string.
URL url = new URL(s);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String inputLine = in.readLine();
// read every line of the HTML content in the URL
// and concat each line to the rawHTML string until every line is read.
while(inputLine != null){
rawHTML += inputLine;
inputLine = in.readLine();
}
in.close();
} catch (Exception e){
e.printStackTrace();
}
// create a regex pattern matching a URL
// that will validate the content of HTML in search of a URL.
String urlPattern = "(www|http:|https:)+[^\s]+[\\w]";
Pattern pattern = Pattern.compile(urlPattern);
Matcher matcher = pattern.matcher(rawHTML);
// Each time the regex matches a URL in the HTML,
// add it to the queue for the next traverse and the list of visited URLs.
breakpoint = getBreakpoint(breakpoint, matcher);
// exit the outermost loop if it reaches the breakpoint.
if(breakpoint == 0){
break;
}
}
}
在該crawl()方法中,rootURL是爬蟲(chóng)的起點(diǎn),breakpoint代表您希望爬蟲(chóng)發(fā)現(xiàn)多少個(gè) URL。
該算法涉及的步驟是:
該算法首先將根 URL 添加到隊(duì)列和已訪問(wèn) URL 列表。
BufferedReader它使用API讀取 URL 的每一行 HTML 內(nèi)容。
然后,它在讀取rawHTML變量時(shí)連接每個(gè) HTML 行。
private int getBreakpoint(int breakpoint, Matcher matcher) {
while(matcher.find()){
String actualURL = matcher.group();
if(!visitedURLs.contains(actualURL)){
visitedURLs.add(actualURL);
System.out.println("Website found with URL " + actualURL);
urlQueue.add(actualURL);
}
// exit the loop if it reaches the breakpoint.
if(breakpoint == 0){
break;
}
breakpoint--;
}
return breakpoint;
}
上面的代碼執(zhí)行以下操作:
該getBreakPoint方法使用指定的正則表達(dá)式模式來(lái)發(fā)現(xiàn)rawHTML.
這些操作會(huì)不斷迭代,直到爬蟲(chóng)發(fā)現(xiàn)了您的breakpoint.
以下是應(yīng)用程序主要方法的片段:
public static void main(String[] args) {
WebCrawler crawler = new WebCrawler();
String rootURL = "https://www.section.io/engineering-education/springboot-antmatchers/";
crawler.crawl(rootURL, 100);
}
下面是運(yùn)行該程序的輸出快照:

上面快照中的 URL 是網(wǎng)絡(luò)爬蟲(chóng)從根 URL 開(kāi)始通過(guò)嵌入 URL 爬取到斷點(diǎn)的所有網(wǎng)頁(yè)中包含的一些 URL。如果大家想了解更多相關(guān)知識(shí),不妨來(lái)關(guān)注一下本站的Java在線學(xué)習(xí),里面的課程內(nèi)容從入門(mén)到精通,細(xì)致全面,通俗易懂,很適合沒(méi)有基礎(chǔ)的小伙伴學(xué)習(xí),希望對(duì)大家能夠有所幫助。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)