无法读取 null 的 属性 'getAttribute'
Cannot read property 'getAttribute' of null
我正在使用 puppeteer 来测试我网站的前端。但是,当我在 table 中显示横幅时,我得到一个错误
我的 html table-body
如下所示:
<tbody>
<tr role="row" class="odd">
<td tabindex="0">7/9/2019</td>
<td>Product 1</td>
<td>Active</td>
<td><a href="test">Category 1</a></td>
</tr>
<tr role="row" class="even">
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
</tr>
我的 page.evaluate() 代码如下所示:
data = await page.evaluate(async () => {
let data = [];
let grabFromRow = (row, child) => {
const td = row
.querySelector(`td:nth-child(${child})`)
return td ? td.innerText.trim() : null
}
let grabLinkFromRow = (row, child) => {
const td = row
.querySelector(`td:nth-child(${child}) > a`).getAttribute("href"); // here I get the error
return td ? td : null;
};
let rows = "#producttable > tbody > tr"
let tableRows = document.querySelectorAll(rows)
for (const tr of tableRows) {
data.push({
date: grabFromRow(tr, 1),
product: grabFromRow(tr, 2),
status: grabFromRow(tr, 3),
category: grabFromRow(tr, 4),
categoryLink: grabLinkFromRow(tr, 4),
});
}
return data;
});
任何建议,如何跳过这些空行并仍然执行我的测试脚本?
感谢您的回复!
您需要先检查 a
标签是否可用,如果是,则 getAttribute 和 return 否则 return null。
const td = row.querySelector(`td:nth-child(${child}) > a`); // here I get the error
if ( td ) {
return td.getAttribute("href");
}
return null;
在一个语句中写入链式操作会导致此错误,因为如果链式中的任何一步失败,它可能 return null
或 undefined
,然后任何进一步的操作尝试将失败。在你的 grabLinkFromRow
函数中你有这一行:
const td = row.querySelector(`td:nth-child(${child}) > a`).getAttribute("href");
这里的问题是 querySelector
正在 returning null
因为行中没有 link。这意味着您正在尝试调用 null.getAttribute("href")
并因此出现错误。
你应该确保你找到 link 然后继续这样:
let grabLinkFromRow = (row, child) => {
let td;
const link = row.querySelector(`td:nth-child(${child}) > a`);
if (link) { // <-- only call getAttribute if we found a link
td = link.getAttribute("href");
}
return td ? td : null;
}
您在另一个函数 grabFromRow
中的想法是正确的,您将 td
设置为 querySelector
的结果并检查其真实性。
let grabLinkFromRow = (row, child) => {
const td = row
.querySelector(`td:nth-child(${child}) > a`);
return td ? td.getAttribute("href") : null;
};
我正在使用 puppeteer 来测试我网站的前端。但是,当我在 table 中显示横幅时,我得到一个错误
我的 html table-body
如下所示:
<tbody>
<tr role="row" class="odd">
<td tabindex="0">7/9/2019</td>
<td>Product 1</td>
<td>Active</td>
<td><a href="test">Category 1</a></td>
</tr>
<tr role="row" class="even">
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
<td style="width: 0; padding: 0"></td>
</tr>
我的 page.evaluate() 代码如下所示:
data = await page.evaluate(async () => {
let data = [];
let grabFromRow = (row, child) => {
const td = row
.querySelector(`td:nth-child(${child})`)
return td ? td.innerText.trim() : null
}
let grabLinkFromRow = (row, child) => {
const td = row
.querySelector(`td:nth-child(${child}) > a`).getAttribute("href"); // here I get the error
return td ? td : null;
};
let rows = "#producttable > tbody > tr"
let tableRows = document.querySelectorAll(rows)
for (const tr of tableRows) {
data.push({
date: grabFromRow(tr, 1),
product: grabFromRow(tr, 2),
status: grabFromRow(tr, 3),
category: grabFromRow(tr, 4),
categoryLink: grabLinkFromRow(tr, 4),
});
}
return data;
});
任何建议,如何跳过这些空行并仍然执行我的测试脚本?
感谢您的回复!
您需要先检查 a
标签是否可用,如果是,则 getAttribute 和 return 否则 return null。
const td = row.querySelector(`td:nth-child(${child}) > a`); // here I get the error
if ( td ) {
return td.getAttribute("href");
}
return null;
在一个语句中写入链式操作会导致此错误,因为如果链式中的任何一步失败,它可能 return null
或 undefined
,然后任何进一步的操作尝试将失败。在你的 grabLinkFromRow
函数中你有这一行:
const td = row.querySelector(`td:nth-child(${child}) > a`).getAttribute("href");
这里的问题是 querySelector
正在 returning null
因为行中没有 link。这意味着您正在尝试调用 null.getAttribute("href")
并因此出现错误。
你应该确保你找到 link 然后继续这样:
let grabLinkFromRow = (row, child) => {
let td;
const link = row.querySelector(`td:nth-child(${child}) > a`);
if (link) { // <-- only call getAttribute if we found a link
td = link.getAttribute("href");
}
return td ? td : null;
}
您在另一个函数 grabFromRow
中的想法是正确的,您将 td
设置为 querySelector
的结果并检查其真实性。
let grabLinkFromRow = (row, child) => {
const td = row
.querySelector(`td:nth-child(${child}) > a`);
return td ? td.getAttribute("href") : null;
};