Playwright Java:精确提取网页表格数据并按列处理的教程

Playwright Java:精确提取网页表格数据并按列处理的教程

本教程旨在解决使用Playwright Java从网页表格提取数据时,内容被误存储为单个单元格的问题。通过详细指导如何利用嵌套循环和Playwright的Locator API精确抓取每个单元格的文本内容,实现数据按列分离,为后续导出到Excel等结构化存储提供了清晰、可操作的解决方案,确保数据完整性和可用性。

引言:网页表格数据提取的挑战

在使用playwright java进行web自动化测试或数据抓取时,经常需要从网页表格中提取结构化数据。一个常见的挑战是,当尝试提取整行数据时,例如使用row.allinnertexts()方法,可能会导致该行所有单元格的内容被合并成一个字符串,最终在导出到excel工具时,所有数据挤在一个单元格中,无法实现按列分离。这大大降低了数据的可用性和分析价值。

本教程将详细介绍如何通过精确的元素定位和循环机制,确保从网页表格中提取的每一项数据都能对应到独立的列,从而为后续的数据处理和导出(如到Excel)打下坚实的基础。

问题分析:allInnerTexts()的局限性

在Playwright中,Locator.allInnerTexts()方法用于获取定位器匹配到的所有元素的内部文本列表。对于一个

(表格行)元素,如果直接对其调用allInnerTexts(),它通常会返回一个包含所有子元素(如

)文本的列表。然而,如果行内的文本被渲染为一个连续的块,或者在某些情况下,它可能将所有单元格的文本合并成一个字符串作为列表中的单个项。

例如,原始代码中的输出:

[   Airi Satou  Accountant  Tokyo   33  $162,700]

这表明row.allInnerTexts()在某些渲染下,会将一行中的所有单元格文本连接起来,形成一个包含单一长字符串的列表。这与我们期望的“每个单元格数据独立”的目标相悖。

立即学习“Java免费学习笔记(深入)”;

解决方案:精确到单元格的遍历

要解决这个问题,我们需要放弃直接获取整行文本的策略,转而采用更精细的方法:首先定位到每一行,然后在每一行内部,再遍历定位到每一个具体的单元格(

元素),并单独提取其文本内容。这可以通过嵌套循环和Playwright的Locator API结合XPath或CSS选择器来实现。

1. 核心思路

外部循环: 遍历表格中的每一行(

)。内部循环: 在每一行内部,遍历该行中的每一个数据单元格(

)。定位器: 使用String.format()动态构建XPath或CSS选择器,精确地指向tbody下的特定行和特定列的单元格。

2. 示例代码

以下是使用Playwright Java实现精确提取网页表格数据并按列处理的完整代码示例。此示例将导航到一个包含数据表格的网页,并逐行逐列地提取数据。

import com.microsoft.playwright.*;import com.microsoft.playwright.options.*;import java.util.ArrayList;import java.util.List;public class WebTableDataExtractor {    public static void main(String[] args) {        Playwright playwright = Playwright.create();        Browser browser = null;        try {            // 启动Chromium浏览器,并设置为无头模式(可选,生产环境推荐)            browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(true));            Page page = browser.newPage();            // 导航到目标网页            page.navigate("https://datatables.net/extensions/select/examples/initialisation/checkbox.html");            // 等待表格加载完成,确保tbody和tr元素可见            // 这是一个良好的实践,防止在元素未加载完成时尝试定位            page.waitForSelector("table#example tbody tr", new Page.WaitForSelectorOptions().setTimeout(10000));            // 定义一个列表来存储所有提取的数据行            List<List> allTableData = new ArrayList();            // 假设我们要提取表格的前10行数据            // 注意:XPath索引通常从1开始            int numberOfDataRowsToExtract = 10;            // 假设表格有5列数据(Name, Position, Office, Age, Salary)            int numberOfColumns = 5;             System.out.println("开始提取网页表格数据:");            // 外部循环:遍历每一行数据            for (int rowIndex = 1; rowIndex <= numberOfDataRowsToExtract; rowIndex++) {                List currentRowData = new ArrayList(); // 存储当前行的数据                System.out.print(String.format("正在提取第 %d 行: [", rowIndex));                // 内部循环:遍历当前行的每一个单元格                for (int colIndex = 1; colIndex <= numberOfColumns; colIndex++) {                    // 构建精确的单元格Locator                    // 使用String.format动态构建XPath,定位到特定行和列的                    // table#example tbody 确保我们定位到数据体而不是表头                    String cellXPath = String.format("table#example tbody tr[%d] td[%d]", rowIndex, colIndex);                    Locator cellLocator = page.locator(cellXPath);                    // 提取单元格的文本内容                    String cellText = cellLocator.innerText().trim(); // 使用trim()去除首尾空白                    currentRowData.add(cellText); // 将单元格数据添加到当前行列表                    System.out.print(cellText + (colIndex < numberOfColumns ? "t" : "")); // 打印并用制表符分隔                }                allTableData.add(currentRowData); // 将当前行数据添加到总数据列表                System.out.println("]");            }            System.out.println("n所有数据提取完成,准备进行后续处理(例如导出到Excel)。");            // 此时,allTableData 包含了所有按行按列分离的结构化数据            // 可以进一步使用Apache POI等库将其写入Excel        } catch (PlaywrightException e) {            System.err.println("Playwright操作失败,请检查网络连接或选择器: " + e.getMessage());        } catch (Exception e) {            System.err.println("发生未知错误: " + e.getMessage());        } finally {            // 确保在程序结束时关闭浏览器和Playwright实例            if (browser != null) {                browser.close();            }            if (playwright != null) {                playwright.close();            }        }    }}

3. 代码说明

Playwright 初始化: 标准的Playwright实例创建和浏览器启动流程。setHeadless(true)表示在后台运行浏览器,不显示UI,适合自动化脚本。导航与等待: page.navigate()用于打开目标网页。page.waitForSelector()是关键,它确保在尝试查找元素之前,表格及其内容已经加载并可见,避免ElementNotFound错误。数据结构: List<List> allTableData被用来存储所有提取到的数据。外层List代表所有行,内层List代表每一行的所有单元格数据。动态 XPath: String.format(“table#example tbody tr[%d] td[%d]”, rowIndex, colIndex)是核心。它根据当前循环的行索引(rowIndex)和列索引(colIndex)动态生成一个精确的XPath表达式,定位到表格数据区(tbody)中的特定单元格。table#example:通过ID定位到具体的表格。tbody:定位到表格的数据体部分,排除表头。tr[%d]:定位到第rowIndex行。注意XPath索引通常从1开始。td[%d]:定位到当前行的第colIndex个数据单元格。innerText(): cellLocator.innerText().trim()用于获取单个单元格的纯文本内容,trim()用于去除文本两端的空白字符,使数据更干净。错误处理与资源释放: 使用try-catch-finally块来捕获可能发生的Playwright异常或其他运行时错误,并在finally块中确保浏览器和Playwright实例被正确关闭,释放资源。

注意事项与最佳实践

选择器鲁棒性: 示例中使用的是基于ID和tbody的XPath。实际项目中,表格结构可能更复杂或动态变化。选择器应尽可能健壮,例如使用包含特定文本的

作为参考,或使用更通用的CSS选择器。

动态行/列数: 如果表格的行数或列数不固定,可以通过先定位所有行page.locator(“table#example tbody tr”).count()和所有列page.locator(“table#example tbody tr[1] td”).count()来动态获取。

分页与滚动: 对于带有分页或无限滚动的表格,需要额外的逻辑来处理翻页操作或滚动加载更多数据。

数据类型转换: 提取的所有数据都是字符串类型。如果需要进行数值计算或日期处理,务必进行适当的类型转换。

导出到Excel: 提取到的List<List>数据结构非常适合使用Apache POI等Java库导出到Excel。您可以遍历此列表,将每一行的数据写入Excel的相应单元格。

示例 Excel 导出思路 (伪代码):

// 假设 allTableData 已经填充// 创建一个Excel工作簿和工作表// XSSFWorkbook workbook = new XSSFWorkbook();// Sheet sheet = workbook.createSheet("Table Data");// int rowNum = 0;// for (List rowData : allTableData) {//     Row excelRow = sheet.createRow(rowNum++);//     int colNum = 0;//     for (String cellValue : rowData) {//         excelRow.createCell(colNum++).setCellValue(cellValue);//     }// }// 将工作簿写入文件// FileOutputStream outputStream = new FileOutputStream("output.xlsx");// workbook.write(outputStream);// workbook.close();// outputStream.close();

总结

通过本教程,我们学习了如何使用Playwright Java精确地从网页表格中提取数据,确保每个单元格的内容都能独立存储,解决了allInnerTexts()可能导致的合并问题。核心在于利用嵌套循环和动态XPath/CSS选择器,实现对表格行和单元格的精细化定位。掌握这一技术,将使您在Web数据抓取和自动化任务中能够更高效、准确地处理结构化表格数据,为后续的数据分析和报表生成奠定坚实基础。

以上就是Playwright Java:精确提取网页表格数据并按列处理的教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/50299.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月8日 16:20:35
下一篇 2025年11月8日 16:21:20

相关推荐

  • 将 Vuejs 添加到 TALL Stack 项目的好处

    将 Vue.js 添加到 TALL Stack 项目的好处 TALL 堆栈由 Tailwind CSS、Alpine.js、Laravel 和 Livewire 组成,是用于构建现代动态 Web 应用程序的强大工具包。这种组合在开发人员中特别受欢迎,他们欣赏它提供的简化的开发流程,允许以最少的努力创…

    2025年12月9日
    000
  • 如何用 PHP 调用 Java 函数?

    使用 java bridge 类库可从 php 脚本中调用 java 函数,通过以下步骤实现:使用 composer 安装 java bridge 类库。使用 setjavaclasspath() 方法配置 php 代码和 java 类路径之间的链接。使用 javaclass::callstatic…

    2025年12月9日
    000
  • 如何使用 PHP 访问 Microsoft Excel 表格?

    可以使用 phpoffice/phpspreadsheet 库访问 microsoft excel 表格,具体操作如下:安装 phpoffice/phpspreadsheet。使用 iofactory::load() 读取 excel 文件。使用 getactivesheet() 获取活动工作表。使…

    2025年12月9日
    000
  • 使用第三方 PHP 函数扩展应用程序功能

    第三方 php 函数通过 composer 安装后,可以通过 psr-4 自动加载。它们可用于扩展应用程序功能,例如使用 guzzle 进行 http 请求或使用 emailvalidator 验证电子邮件地址。通过利用第三方函数,开发人员可以轻松地在应用程序中添加新功能,而无需重新编写代码。 使用…

    2025年12月9日
    000
  • 使用第三方 PHP 函数时避免常见陷阱

    使用第三方 php 函数时,必须注意陷阱,包括:确保依赖关系明确,检查函数签名,处理错误,验证结果。这些准则可避免错误和意外行为,确保代码的可靠性和健壮性。实时案例:使用 guzzlehttp 时,请记住将响应对象转换为字符串或数组,以避免常见陷阱。 使用第三方 PHP 函数时避免常见陷阱 在使用第…

    2025年12月9日
    000
  • PHP 引用传递:加速你的函数开发流程

    引用传递允许函数通过修改变量引用来修改其参数的原始值,从而提高函数的效率,尤其适用于处理大型或复杂数据结构。语法为在参数前面加上”&”符号;实战案例中,通过引用传递数组,可以修改原始数组,而非仅打印副本。 PHP 引用传递:加速你的函数开发流程 引用传递允许函数修改其…

    2025年12月9日
    000
  • WordPress 主题开发:终极文件夹结构指南

    wordpress 是构建网站时的灵活框架。您可以构建任何类型的网站,例如 cms、电子商务、单一登陆页面等。这里我将讨论 wordpress 项目的结构,以便您可以制作自定义主题。当您为自己或客户制作网站时,流行的主题(例如 divi、astra、neve、oceanwp 等)是一些不错的选择。但…

    2025年12月9日
    000
  • PHP 函数如何扩展到移动端?

    php 函数可通过 clever stack 拓展至移动端,该平台使用 php、html5 和 css3 开发跨平台应用程序。具体步骤:安装 clever stack,创建新项目;设置 php 文件以定义路由;创建包含 ui 的视图文件;运行应用程序。 拓展 PHP 函数至移动端的秘诀 PHP 函数…

    2025年12月9日
    000
  • 引入灵活且与框架无关的 Laravel Livewire Modal 包

    引入灵活的 laravel livewire 模态包 laravel 和 livewire 彻底改变了我们用最少的 javascript 构建动态应用程序的方式。但在处理模态时,大多数解决方案往往将我们锁定在特定的设计框架中,例如 bootstrap 或 tailwind css。如果您需要灵活地选…

    2025年12月9日
    000
  • PHP 函数如何与 Java 交互

    php 函数可以通过以下步骤与 java 交互:包含 java 类创建 java 对象调用 java 方法访问 java 字段创建数组设置数组元素を活用例としては、java で数字の合計を計算するクラスを作成し、php スクリプトからこのクラスを使用して計算を実行できます。 PHP 函数如何与 Ja…

    2025年12月9日
    000
  • PHP 函数如何与 CSS 交互

    php 与 css 交互的方式包括:样式表引入、内联样式、php 内联样式、css 类处理(添加、移除、切换)。 用 PHP 函数与 CSS 交互 PHP 提供了多种方法来与 CSS 交互,包括: 样式表引入 立即学习“PHP免费学习笔记(深入)”; 使用 link 标签引入 CSS 样式表: 内联…

    2025年12月9日
    000
  • PHP 函数名称中的缩写规则

    在 php 函数命名中,缩写应遵循以下规则:1. 相同含义的缩写保持一致;2. 缩写易于理解;3. 缩写尽可能短;4. 主要单词不缩写。通过遵循这些规则,可创建更清晰的 php 函数。 PHP 函数名称中的缩写规则 在 PHP 函数命名中,缩写是常见的做法,可以帮助函数名称更简洁、表达更明确。以下是…

    2025年12月9日
    000
  • PHP 函数名称中允许使用的字符

    php 函数名称中允许字母、数字和下划线,不允许空格和特殊字符(除下划线外)。命名约定包括:以小写字母或下划线开头,使用驼峰命名法,避免与内置函数或变量冲突。 PHP 函数名称中允许使用的字符 PHP 函数名称中允许使用的字符遵循严格的规则,如下: 允许的字符: 立即学习“PHP免费学习笔记(深入)…

    2025年12月9日
    000
  • 如何访问本地php文件 如何批量产生php文件

    直接访问本地 PHP 文件:直接在浏览器输入文件路径。使用本地服务器软件,配置网站根目录指向 PHP 文件文件夹,然后通过服务器地址和文件名访问。使用 PHP 内置服务器,通过命令行启动并输入指定地址访问。批量生成 PHP 文件:使用命令行脚本循环生成文件。使用 PHP 代码循环生成文件并写入内容。…

    2025年12月9日
    000
  • win如何搭建php网站

    搭建 PHP 网站需要托管服务、文本编辑器和 Web 服务器。具体步骤包括:选择托管服务(共享虚拟主机、VPS 或专用服务器)。安装文本编辑器(记事本++、Sublime Text 或 Visual Studio Code)。安装和配置 Web 服务器(XAMPP、WAMP 或 IIS)。创建 PH…

    2025年12月9日
    000
  • 如何给服务器安装php

    要在服务器上安装 PHP,请按以下步骤操作:更新系统软件包。根据操作系统,使用相应命令安装 PHP。检查 PHP 版本。安装所需的 PHP 扩展(可选)。配置 Apache 或 Nginx 以使用 PHP。重启 Web 服务器。 如何在服务器上安装 PHP 步骤 1:更新系统 在安装 PHP 之前,…

    2025年12月9日
    000
  • 如何tomcat支持php

    Tomcat 支持 PHP 的方法有使用 Tomcat 扩展模块、使用 FastCGI 以及配置 mod_jk。其中:使用 Tomcat 扩展模块:下载 TNL 模块并配置 server.xml 文件,然后重新启动 Tomcat。使用 FastCGI:安装 PHP FastCGI,配置 server…

    2025年12月9日
    000
  • 如何更php源码网页地

    要美化 PHP 源码,可以采取以下步骤:使用代码高亮语法;缩进和换行便于阅读;添加注释说明代码逻辑;利用调试工具查找错误;使用版本控制系统管理代码;优化性能减少加载时间;加强安全性防止漏洞;将代码模块化、组织化;编写文档解释代码功能;使用 IDE 并参与代码审查。 如何更php源码网页 1. 使用代…

    2025年12月9日
    000
  • PHP 变量和函数命名的区别

    php 中变量和函数命名方式不同:变量以 $ 符号开头,使用驼峰或下划线命名法,描述性强;函数不以 $ 符号开头,仅用驼峰命名法,表示其功能。 PHP 变量和函数命名的区别 在 PHP 中,变量和函数的命名规则截然不同。理解这些差异对于编写整洁、可读性高的代码至关重要。 变量命名 立即学习“PHP免…

    2025年12月9日
    000
  • Laravel htaccess 基本指南:为什么、如何以及它能为您的应用程序做什么

    介绍 当涉及到使用 laravel 构建健壮的 web 应用程序时,.htaccess 文件通常扮演着默默无闻但至关重要的角色,特别是当您将项目托管在 apache 服务器上时。虽然它看起来只是另一个配置文件,但理解和利用 .htaccess 文件可以极大地增强应用程序的安全性、性能和整体功能。 在…

    2025年12月9日
    000

发表回复

登录后才能评论
关注微信