使用Selenium和Java解析动态表格的分页爬取异常问题
问题描述
我想要编写程序访问CIA世界概况的国家列表页面,爬取全部262个国家的链接。使用Selenium的HtmlUnitDriver实现时,只能获取第一页内容;点击分页按钮后,重新获取的链接仍是第一页的,没有更新。
测试代码如下:
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import java.util.ArrayList; public static void main(String[] args){ WebDriver driver = new HtmlUnitDriver(); driver.get("https://www.cia.gov/the-world-factbook/countries/"); ArrayList<WebElement> links = (ArrayList<WebElement>) driver.findElements(By.className("inline-link")); System.out.println(links); WebElement button = driver.findElement(By.cssSelector("span[class='pagination__arrow-right']")); button.click(); links = (ArrayList<WebElement>) driver.findElements(By.className("inline-link")); System.out.println(links); driver.close(); }
驱动能成功定位到分页按钮,但点击后页面内容并未更新——比如原本的Croatia链接依然存在,没有变成Salvador。
解决办法
核心原因
- HtmlUnitDriver默认禁用JavaScript:该页面的分页逻辑依赖JS动态加载内容,默认配置下无法触发页面的动态更新。
- 缺少等待机制:即便启用JS,点击分页按钮后页面需要时间加载新内容,立即获取元素会拿到未更新的DOM。
修复步骤
1. 启用HtmlUnitDriver的JavaScript支持
初始化驱动时开启JS,让页面能正常执行分页的动态逻辑:
WebDriver driver = new HtmlUnitDriver(true);
2. 添加显式等待
点击按钮后,等待页面元素完成更新(比如等待第一页的特征元素消失,或新页面的特征元素出现),确保新内容加载完成后再获取链接。
修改后的完整代码
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import java.time.Duration; import java.util.ArrayList; public class CountryScraper { public static void main(String[] args){ // 启用JavaScript支持 WebDriver driver = new HtmlUnitDriver(true); driver.get("https://www.cia.gov/the-world-factbook/countries/"); // 获取第一页链接 ArrayList<WebElement> firstPageLinks = (ArrayList<WebElement>) driver.findElements(By.className("inline-link")); System.out.println("第一页链接数量:" + firstPageLinks.size()); // 定位并点击分页按钮 WebElement nextPageBtn = driver.findElement(By.cssSelector("span.pagination__arrow-right")); nextPageBtn.click(); // 显式等待,等待第一页的Croatia元素消失,确认页面更新 WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.invisibilityOfElementLocated(By.linkText("Croatia"))); // 获取第二页链接 ArrayList<WebElement> secondPageLinks = (ArrayList<WebElement>) driver.findElements(By.className("inline-link")); System.out.println("第二页链接数量:" + secondPageLinks.size()); driver.close(); } }
额外建议
- 如果HtmlUnitDriver仍有兼容性问题,建议换成ChromeDriver或FirefoxDriver,它们对JS的支持更贴近真实浏览器,能减少动态页面的适配问题。
- 爬取全部262个国家时,可以循环点击分页按钮,直到按钮处于禁用状态(比如class包含
disabled),每次等待后收集当前页的链接即可。
内容的提问来源于stack exchange,提问作者OCEAN OESTREICHER
相关产品推荐
相关产品推荐

