Java提取網(wǎng)頁(yè)樹(shù)節(jié)點(diǎn)URL的三種高效方法
在 Java 中獲取網(wǎng)頁(yè)上某個(gè)樹(shù)結(jié)構(gòu)的某個(gè)節(jié)點(diǎn)的所有下級(jí)節(jié)點(diǎn)的 URL,通常需要以下幾個(gè)步驟:
- 下載網(wǎng)頁(yè)內(nèi)容(HTTP 請(qǐng)求)。
- 解析 HTML 內(nèi)容(使用 HTML 解析器)。
- 定位目標(biāo)節(jié)點(diǎn)并提取其子節(jié)點(diǎn)的 URL。
常見(jiàn)的實(shí)現(xiàn)方式包括:
- 使用
Jsoup進(jìn)行 HTML 解析。 - 使用
Selenium進(jìn)行動(dòng)態(tài)頁(yè)面處理(如果頁(yè)面是通過(guò) JavaScript 動(dòng)態(tài)生成的)。 - 使用
HttpClient+Jsoup的組合進(jìn)行靜態(tài)頁(yè)面解析。
下面分別介紹這幾種方法,并提供對(duì)應(yīng)的 Maven 依賴和 Java 示例代碼
方法一:使用 Jsoup 解析靜態(tài) HTML 頁(yè)面
Maven 依賴
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.16.1</version>
</dependency>
Java 示例代碼
假設(shè)你要從一個(gè)靜態(tài) HTML 頁(yè)面中找到某個(gè)具有特定 ID 的樹(shù)節(jié)點(diǎn),并提取它的所有子節(jié)點(diǎn)的 href 屬性。
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class TreeUrlParser {
public static List<String> getChildUrls(String url, String targetNodeId) throws IOException {
Document doc = Jsoup.connect(url).get();
Element targetNode = doc.getElementById(targetNodeId);
List<String> childUrls = new ArrayList<>();
if (targetNode != null) {
Elements links = targetNode.select("a[href]");
for (Element link : links) {
String href = link.absUrl("href"); // 獲取絕對(duì)路徑
childUrls.add(href);
}
}
return childUrls;
}
public static void main(String[] args) {
try {
List<String> urls = getChildUrls("https://example.com/tree-page", "tree-node-id");
urls.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
方法二:使用 Selenium 處理動(dòng)態(tài)加載的樹(shù)結(jié)構(gòu)
如果樹(shù)結(jié)構(gòu)是通過(guò) JavaScript 動(dòng)態(tài)加載的,則需要使用瀏覽器自動(dòng)化工具如 Selenium 來(lái)渲染頁(yè)面。
Maven 依賴
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.19.0</version>
</dependency>
還需要下載 WebDriver(如 ChromeDriver)。
Java 示例代碼
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.ArrayList;
import java.util.List;
public class DynamicTreeUrlParser {
public static List<String> getChildUrls(String pageUrl, String targetNodeId) {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get(pageUrl);
WebElement targetNode = driver.findElement(By.id(targetNodeId));
List<WebElement> links = targetNode.findElements(By.tagName("a"));
List<String> childUrls = new ArrayList<>();
for (WebElement link : links) {
String href = link.getAttribute("href");
if (href != null && !href.isEmpty()) {
childUrls.add(href);
}
}
driver.quit();
return childUrls;
}
public static void main(String[] args) {
List<String> urls = getChildUrls("https://example.com/dynamic-tree-page", "tree-node-id");
urls.forEach(System.out::println);
}
}
方法三:結(jié)合 Apache HttpClient 和 Jsoup
如果你希望使用更底層的 HTTP 客戶端來(lái)控制請(qǐng)求細(xì)節(jié),可以使用 HttpClient。
Maven 依賴
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.16.1</version>
</dependency>
Java 示例代碼
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.HttpEntity;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class HttpClientJsoupParser {
public static List<String> getChildUrls(String url, String targetNodeId) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet(url);
ClassicHttpResponse response = httpClient.execute(request);
HttpEntity entity = response.getEntity();
List<String> childUrls = new ArrayList<>();
if (entity != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
StringBuilder content = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
content.append(line);
}
Document doc = Jsoup.parse(content.toString());
org.jsoup.nodes.Element targetNode = doc.getElementById(targetNodeId);
if (targetNode != null) {
targetNode.select("a[href]").forEach(link -> {
childUrls.add(link.absUrl("href"));
});
}
}
return childUrls;
}
public static void main(String[] args) {
try {
List<String> urls = getChildUrls("https://example.com/tree-page", "tree-node-id");
urls.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
}
總結(jié)
| 方法 | 工具 | 是否支持動(dòng)態(tài)內(nèi)容 | 適用場(chǎng)景 |
|---|---|---|---|
| 方法一 | Jsoup | ? 不支持 | 靜態(tài) HTML 頁(yè)面解析 |
| 方法二 | Selenium | ? 支持 | 動(dòng)態(tài) JavaScript 渲染頁(yè)面 |
| 方法三 | HttpClient + Jsoup | ? 不支持 | 更細(xì)粒度的 HTTP 請(qǐng)求控制 |
你可以根據(jù)實(shí)際需求選擇合適的方法。
到此這篇關(guān)于Java提取網(wǎng)頁(yè)樹(shù)節(jié)點(diǎn)URL的三種高效方法的文章就介紹到這了,更多相關(guān)Java提取網(wǎng)頁(yè)樹(shù)節(jié)點(diǎn)URL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis?+?Java攔截器實(shí)現(xiàn)用戶匿名和非匿名訪問(wèn)
本文主要介紹了Redis?+?Java攔截器實(shí)現(xiàn)用戶匿名和非匿名訪問(wèn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
解決JDK異常處理No appropriate protocol問(wèn)題
這篇文章主要介紹了解決JDK異常處理No appropriate protocol問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
Spring中的@PostConstruct注解使用方法解析
這篇文章主要介紹了Spring中的@PostConstruct注解使用方法解析,@PostConstruct注解是用來(lái)處理在@Autowired注入屬性后init()方法之前,對(duì)一些零散的屬性進(jìn)行賦值的注解,需要的朋友可以參考下2023-11-11
Java保留兩位小數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了 Java保留兩位小數(shù)的實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下2017-06-06
java發(fā)送heartbeat心跳包(byte轉(zhuǎn)16進(jìn)制)
這篇文章主要介紹了java發(fā)送heartbeat心跳包(byte轉(zhuǎn)16進(jìn)制),需要的朋友可以參考下2014-05-05
幾句話說(shuō)清session,cookie和token的區(qū)別及說(shuō)明
這篇文章主要介紹了幾句話說(shuō)清session,cookie和token的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
使用SpringBoot發(fā)送郵箱驗(yàn)證碼的簡(jiǎn)單實(shí)現(xiàn)
這篇文章主要介紹了使用SpringBoot發(fā)送郵箱驗(yàn)證碼的簡(jiǎn)單實(shí)現(xiàn),咱們今天來(lái)講使用QQ郵箱來(lái)發(fā)送和接收驗(yàn)證碼,首先來(lái)介紹一下它在SpringBoot項(xiàng)目中的具體應(yīng)用,需要的朋友可以參考下2023-04-04
深入解析Andoird應(yīng)用開(kāi)發(fā)中View的事件傳遞
這篇文章主要介紹了深入解析Andoird應(yīng)用開(kāi)發(fā)中View的事件傳遞,其中重點(diǎn)講解了ViewGroup的事件傳遞流程,需要的朋友可以參考下2016-02-02
springboot熱部署class XX cannot be cast&nbs
在使用DevTools進(jìn)行熱加載時(shí)遇到的`classXXcannotbecasttoclassXX`錯(cuò)誤,以及解決該問(wèn)題的方法,通過(guò)在`resources`目錄下創(chuàng)建`META-INF/spring-devtools.properties`文件,并添加相應(yīng)的配置,可以有效解決此問(wèn)題,使DevTools熱加載功能得以正常工作2025-02-02
從Mybatis-Plus開(kāi)始認(rèn)識(shí)SerializedLambda的詳細(xì)過(guò)程
這篇文章主要介紹了從Mybatis-Plus開(kāi)始認(rèn)識(shí)SerializedLambda,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07

