用于网络抓取的 Java 版 Puppeteer
在本文中,我将向你展示如何设置和使用 Puppeteer 在 Java 中进行网络搜刮。我还将分享一些有用的技巧,让你的搜刮过程更顺畅、更高效。让我们直接开始吧!
什么是 Puppeteer?
Puppeteer 是一个 Node.js 库,它提供了一个高级 API,用于使用 Chrome DevTools 协议控制无头 Chrome 或 Chromium 浏览器。无头意味着浏览器运行时没有 图形用户界面Puppeteer 允许开发人员自动执行浏览器操作,如页面导航、表单提交、屏幕捕获甚至网页刮擦。Puppeteer 允许开发人员自动执行浏览器操作,如页面导航、表单提交、屏幕捕获,甚至网络扫描。
虽然 Puppeteer 是为 Node.js 设计的,但您也可以借助 Puppeteer 的 Java 封装器 Jvppeteer 在 Java 中使用它。 Jvppeteer 让你可以用 Java 与无头浏览器交互,在 Java 生态系统中提供与 Puppeteer 类似的功能。
在您继续阅读之前,我建议您先阅读我的文章,了解 最佳 Java 网络搜索库.
为什么使用 Puppeteer 进行网络抓取?
Puppeteer 是网络刮擦的理想选择有几个原因:
- JavaScript 渲染:许多现代网站在很大程度上依赖 JavaScript 来动态加载内容。Puppeteer 允许你在浏览器中执行 JavaScript,并检索初始 HTML 中可能没有的数据。
- 页面互动:Puppeteer 可让您与网页互动、点击按钮、填写表格以及执行其他模拟真实用户行为的操作。
- 屏幕截图和 PDF 文件:Puppeteer 可以截图并生成 PDF 网页,这对于存档或捕捉可视内容非常有用。
- 无头浏览器:由于 Puppeteer 默认使用无头浏览器,因此运行时没有图形界面,速度更快,资源消耗更少。
在 Java 中设置 Jvppeteer 以进行网络抓取
由于 Puppeteer 在 Java 中没有原生版本,你需要使用 Jvppeteer,它是 Puppeteer 的 Java 封装器。请按照以下步骤设置 Jvppeteer 以进行网络刮擦:
第 1 步:安装 Jvppeteer 依赖项
第一步是在 Java 项目中添加 Jvppeteer 依赖项。如果使用 Maven,请在 pom.xml 文件中添加以下代码段:
<dependency>
<groupId>io.github.fanyong920</groupId>
<artifactId>jvppeteer</artifactId>
<version>3.3.2</version>
</dependency>
查看官方 GitHub 代码库,确保使用的是最新版本的 Jvppeteer。
第 2 步:创建 Java 项目
接下来,使用您喜欢的集成开发环境创建一个 Java 项目。在本教程中,我们将使用 Visual Studio Code,但您也可以使用 IntelliJ IDEA 或 Eclipse 等任何 Java IDE。确保将 IDE 配置为使用 JDK 11 或更新版本,因为 Jvppeteer 要求使用 JDK 11 或更新版本。
第 3 步:编写网络抓取程序
现在,让我们使用 Jvppeteer 编写一个简单的网络搜刮程序。下面的 Java 代码演示了如何启动无头 Chrome 浏览器、导航到目标网页并检索 HTML 内容:
package com.example;
import com.ruiyun.jvppeteer.api.core.Browser;
import com.ruiyun.jvppeteer.api.core.Page.Page.Page.Page;
import com.ruiyun.jvppeteer.cdp.core.Puppeteer;
import com.ruiyun.jvppeteer.cdp.entities.LaunchOptions;
public class Main {
public static void main(String[] args) {
System.out.println("启动浏览器......");
// 初始化启动选项
启动选项 启动选项 = LaunchOptions.builder()
.headless(true) // 以无头模式运行
.build();
try (浏览器 cdpBrowser = Puppeteer.launch(launchOptions)) {
// 打开新页面
页次 page = cdpBrowser.newPage();
// 导航到目标 URL
page.goTo("https://www.example.com");
// 读取页面的 HTML 内容
String 页面内容 = page.content();
System.out.println(pageContent);
} catch (异常 e) {
e.printStackTrace();
}
}
}
步骤 4:从页面解析数据
既然已经获取了页面的 HTML 内容,就可以对其进行解析,以提取所需的数据。在本教程中,我们将使用用于 HTML 解析的 Java 库 JSoup 来提取所需数据。
在 pom.xml 文件中添加 JSoup:
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.18.3</version>
</dependency>
接下来,修改 Main.java 文件,以解析 HTML 内容并提取产品名称、价格和图片 URL:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Main {
public static void main(String[] args) {
// 启动 Puppeteer 浏览器并抓取 HTML 内容(与之前相同)
String 页面内容 = ...; // 假设页面内容是从 Puppeteer 获取的
// 使用 JSoup 解析 HTML
Document document = Jsoup.parse(pageContent);
Elements products = document.select(".产品"); // 选择产品元素
// 提取数据
for (Element product : products) {
String name = product.select(".产品名称").text();
String price = product.select(".产品价格").text();
String image = product.select(".产品图像").attr("src");
System.out.println("产品名称:" name);
System.out.println("价格" 价格);
System.out.println("图像 URL:" 图像);
System.out.println(" - - - - - - - - - - - ");
}
}
}
第 5 步:将数据导出到 CSV 文件
在对数据进行刮擦和解析后,您可能希望将其导出为 CSV 文件,以便于分析。使用 Java 内置的 FileWriter 类将数据保存到 CSV 文件中。
以下是如何修改代码以将数据导出到 CSV 文件的方法:
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Main {
private static List productData = new 数组列表();
public static void main(String[] args) {
// 抓取和解析数据(与之前相同)
// 存储产品详细信息
productData.add(new String[]{名称、价格、图像});
// 将数据导出为 CSV
exportDataToCsv("products.csv");
}
private static void exportDataToCsv(字符串 filePath) {
try (文件写入器 作家 = new 文件写入器(filePath)) {
writer.append("产品名称、价格、图片 URLn");
// 写入数据行
for (String[] row : productData) {
writer.append(String.join(",", row));
writer.append("n");
}
System.out.println("数据保存到" filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
步骤 6:处理动态内容和无限滚动
许多现代网站使用无限滚动功能,在您向下滚动页面时动态加载内容。要抓取此类页面,需要模拟滚动到页面底部来加载所有内容。
以下代码演示了如何在 Java 中使用 Puppeteer 处理无限滚动:
长 最后高度 = ((Number) page.evaluate("() => document.body.scrollHeight")).longValue();
while (true) {
// 向下滚动
page.evaluate("window.scrollTo(0,document.body.scrollHeight)");
// Wait for new content to load
Thread.sleep(3000);
// 获取新的滚动高度
长 新高度 = ((Number) page.evaluate("() => document.body.scrollHeight")).longValue();
if (newHeight == lastHeight) {
break; // 如果没有新内容,则停止滚动
}
lastHeight = newHeight;
}
第 7 步:截图
有时,你需要在搜索过程中截取网页截图。Puppeteer 允许你以各种方式截取屏幕截图:
- 整页截图:捕捉整个页面,包括需要滚动的部分。
- 可见区域截图:只截取网页的可见部分。
- 元素截图:捕捉特定的 HTML 元素。
下面介绍如何使用 Puppeteer 截取整页屏幕截图:
截图选项 截图选项 = new 截图选项();
screenshotOptions.setPath("full_page.png");
screenshotOptions.setOmitBackground(true);
screenshotOptions.setFullPage(true);
page.screenshot(screenshotOptions);
步骤 8:避免受阻
刮擦网站时常见的挑战之一就是被屏蔽。许多网站使用反僵尸措施来检测和阻止搜刮者。为了避免被拦截,你可以
- 使用代理: 轮流代理 可以帮助隐藏你的真实 IP 地址。
- 设置用户代理:设置自定义 User-Agent 标头,以模拟真实浏览器。
- 使用 Bright Data API:Bright Data 提供的 API 可绕过反机器人限制,让您可以无限制地进行刮擦。
下面是一个使用 Bright Data 绕过 AntiBot 挑战的示例:
String apiUrl = "https://api.brightdata.com/v1/?apikey=&url=https%3A%2F%2Fwww.scrapingcourse.com%2Fantibot-challenge&js_render=true&premium_proxy=true";
String response = 请求.get(apiUrl)
.execute().returnContent().asString();
System.out.println(response);
结论
Java 版 Puppeteer 是一款强大的网络搜刮工具,尤其是与 Jvppeteer 结合使用时。无论您是需要抓取静态数据还是处理动态内容,Puppeteer 都能提供灵活高效的解决方案。按照本指南中的步骤,你可以创建一个功能齐全的网络搜刮器,处理无限滚动、截图,并避免在搜刮时被拦截。