Puppeteer 选择表格行/选项

Posted

技术标签:

【中文标题】Puppeteer 选择表格行/选项【英文标题】:Puppeteer Select Table row/option 【发布时间】:2022-01-18 23:40:51 【问题描述】:

处理一些代码,该代码将选择一个表格选项,该选项在从下拉菜单中选择一个选项后生成。无权访问 github atm 来检查 puppeteer 文档,所以我正在寻找如何调整类似于 let optionValue = await page.$$eval('option', options => options.find(o => o.innerText === "Quality")?.value)

的行

await page.select('#selDept', optionValue); 以便使用 id 标签或“Stephen_Test”的 innerText 或隐藏单元格度量 id“1640”来选择正确的表格行。我相信选择度量 id 1640 会更好,这样我还可以将该 id 保存为变量,如果需要,以后可以在项目的其他地方使用。我只是没有使用 nodeJS/puppeteer 的经验,不知道如何将这条线调整为我正在寻找的内容,因此不胜感激。

当前的 puppeteer 代码

const puppeteer = require('puppeteer');

(async () => 
    const browser = await puppeteer.launch(headless: false);
    
    const page = await browser.newPage();
    
    await page.authenticate('username': username, 'password': password);
    
    await page.goto('http://10.10.4.80/index-test-sh.html') //this is an intranet site for the company I work at
    
    await page.waitForTimeout(4000);
    await page.waitForSelector('#selDept');
    
    await page.waitForTimeout(4000);
    let optionValue = await page.$$eval('option', options => options.find(o => o.innerText === "Quality")?.value)
    await page.select('#selDept', optionValue);
    
    await page.waitForTimeout(4000);
    let measureValue = await page.$$eval('td', td => td.find(t => t.innerText === "Stephen_Test")?.value)
    await page.select('#Output', measureValue);
    
    await page.waitForTimeout(4000);
    //await browser.close();
    
)();

表是用这个循环构建的:

for (var i = 0; i < arr.length; i++)   
        txtTable = txtTable + "<tr id='row" + i + "'>"; //altered this to have unique row ID's
        txtTable = txtTable + "<td style='width:30%;'>" + arr[i].departmentName + "</td>";      
        txtTable = txtTable + "<td id='measureId" + arr[i].measureId + "' style='display:none; width:10%;'>" + arr[i].measureId + "</td>"; //altered this to include an id using measureId  
        txtTable = txtTable + "<td style='width:40%;'>" + arr[i].qmsMeasure + "</td>";      
        txtTable = txtTable + "<td style='width:20%;'>" + arr[i].measureSltOwner + "</td>";
        txtTable = txtTable + "</tr>";
        
    ;//End Loop

选择选项后生成的HTML(大约10行,只显示我要选择的那一行)

<div class="OptionTable DisplayScrollBar">
<table id="Output">
  <thead>
    <tr>
      <th style="width: 30%;">Department Name</th>
      <th style="width: 10%;display:none;">Report ID</th>
      <th style="width: 40%;">Measure Name</th>
      <th style="width: 20%;">SLT Measure Owner</th>
    </tr>
  </thead>
  <tbody>
    <tr id="row0">
      <td style="width:30%;">Quality</td>
      <td id="measureId1640" style="display:none; width:10%;">1640</td>
      <td style="width:40%;">Stephen_Test</td>
      <td style="width:20%;">null</td>
    </tr>
  </tbody>
</div>

【问题讨论】:

Puppeteer 文档在 GitHub 上可用:pptr.dev @AnthumChris 第一次下载通常需要多长时间?已经在加载屏幕上呆了大约 10 分钟,不确定是不是要调出下载对话框或其他什么? 【参考方案1】:

第二天重新开始讨论这个问题后,我是这样完成任务的:

try 
        await page.$("#measureId1640");
        console.log("It exists!");
     catch 
        console.log("no dice");
    
let measureId = await page.$$eval('td', td => td.find(t => t.innerText === "1640")?.id); // same as optionValue line, this time we look for 1640, and then return the id attribute of that element
console.log(measureId);
await page.click('#row0')

首先,我设置了一个 try 语句,让我知道表中是否存在所需的度量/报告。

接下来,我设置了一个$$eval 来查看td 标记类型(我知道这就是$$eval 语句的这一部分现在的含义),并且对于每个标记,它将使用.find查找带有innerText1640 的标签的函数,当它找到这个时,?.id 让它返回该标签的ID。这使我可以在将来需要时使用 measureId。

完成后,我使用page.click('#row0') 选择相应的行(我对整行使用#row0,而不是尝试使用单个单元格的内部ID),这会带来正确的该报告的信息

【讨论】:

以上是关于Puppeteer 选择表格行/选项的主要内容,如果未能解决你的问题,请参考以下文章

使用 Puppeteer 等待组件上的 ID 更改

想用 Puppeteer 刮桌子。如何获取所有行,遍历行,然后为每一行获取“td”?

Puppeteer 中的选择器语法

Puppeteer:如何处理多个标签?

Puppeteer,保存网页和图像

Puppeteer/JQuery:选择器在滚动脚本中不起作用