人偶操纵者在选择 <td> 后单击它
Puppeteer clicking a <td> after selecting it
我测试了我的 xpath select 或 chrome 开发工具,它找到了我正在尝试 select.
的 <td>
我尝试了一些方法,使用 page.x$,然后确保元素 select 使用以下内容正确编辑:
page.waitForXPath("//td[contains(., 'All Projects')]")
.then(selector => {
page.click(selector);
})
执行确实达到了 page.click()
,我得到以下错误。我很困惑,因为我不认为我在改变环境。
UnhandledPromiseRejectionWarning: Error: JSHandles can be evaluated only in the context they were created!
编辑:这里是 HTML 代码。这是一个由 HTML table 组成的 Angular 网格。 <td>
在底部。
这是其余的代码。其他一切工作正常。对不起,如果这很笨重。
const puppeteer = require('puppeteer');
const kindle = puppeteer.devices['Kindle Fire HDX landscape'];
async function main() {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
//go to page and log in
await page.emulate(kindle);
await page.goto('http://localhost:4201/#/login');
await page.waitForSelector('input[id="usr"]');
await page.type('#usr', 'myusername');
await page.type('#pwd', '');
await page.click('button');
//wait for homepage to load
await page.waitForSelector('#menuData');
await page.click('#menuData');
await page.waitForSelector('#drCreate');
await page.click('#drCreate');
await page.waitForSelector('.mat-input-element'); //a request piece is loaded
//populate fields
var date = new Date();
await page.type('#mat-input-0', humanReadableDate(date));
date.setDate(date.getDate() + 1);
await page.type('#mat-input-1', humanReadableDate(date));
date.setDate(date.getDate() + 5)
await page.type('#mat-input-3', humanReadableDate(date));
await page.click('.pi-angle-double-right');
page.waitForXPath("//td[contains(., 'All Projects')]")
.then(selector => {
page.click(selector);
})
}
function humanReadableDate(date) {
if (!date) {
date = new Date();
}
return (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear();
}
main();
它看起来像一个无效的页面上下文。尝试这样的事情:
await page.waitForXPath("//td[contains(., 'All Projects')]")
const [ projects ] = await page.$x("//td[contains(., 'All Projects')]");
projects.click()
或简称:
page.waitForXPath("//td[contains(., 'All Projects')]").then(selector => selector.click())
问题
page.click
需要一个字符串(选择器)作为参数,但您传递的是元素句柄。
引用来自 page.waitForXPath
的文档:
returns: <Promise<?ElementHandle>> Promise which resolves when element specified by xpath string is added to DOM. Resolves to null
if waiting for hidden: true
and xpath is not found in DOM.
这意味着您不能将该函数的结果(元素句柄)提供给 page.click
。
解决方案
相反,您可以使用 elementHandle.click
:
编写这样的代码
await page.waitForXPath("//td[contains(., 'All Projects')]")
.then(elementHandle => elementHandle.click())
但我建议使用 async
/await
语法来更符合您的代码的其余部分:
const elementHandle = await page.waitForXPath("//td[contains(., 'All Projects')]");
await elementHandle.click();
我测试了我的 xpath select 或 chrome 开发工具,它找到了我正在尝试 select.
的<td>
我尝试了一些方法,使用 page.x$,然后确保元素 select 使用以下内容正确编辑:
page.waitForXPath("//td[contains(., 'All Projects')]")
.then(selector => {
page.click(selector);
})
执行确实达到了 page.click()
,我得到以下错误。我很困惑,因为我不认为我在改变环境。
UnhandledPromiseRejectionWarning: Error: JSHandles can be evaluated only in the context they were created!
编辑:这里是 HTML 代码。这是一个由 HTML table 组成的 Angular 网格。 <td>
在底部。
这是其余的代码。其他一切工作正常。对不起,如果这很笨重。
const puppeteer = require('puppeteer');
const kindle = puppeteer.devices['Kindle Fire HDX landscape'];
async function main() {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
//go to page and log in
await page.emulate(kindle);
await page.goto('http://localhost:4201/#/login');
await page.waitForSelector('input[id="usr"]');
await page.type('#usr', 'myusername');
await page.type('#pwd', '');
await page.click('button');
//wait for homepage to load
await page.waitForSelector('#menuData');
await page.click('#menuData');
await page.waitForSelector('#drCreate');
await page.click('#drCreate');
await page.waitForSelector('.mat-input-element'); //a request piece is loaded
//populate fields
var date = new Date();
await page.type('#mat-input-0', humanReadableDate(date));
date.setDate(date.getDate() + 1);
await page.type('#mat-input-1', humanReadableDate(date));
date.setDate(date.getDate() + 5)
await page.type('#mat-input-3', humanReadableDate(date));
await page.click('.pi-angle-double-right');
page.waitForXPath("//td[contains(., 'All Projects')]")
.then(selector => {
page.click(selector);
})
}
function humanReadableDate(date) {
if (!date) {
date = new Date();
}
return (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear();
}
main();
它看起来像一个无效的页面上下文。尝试这样的事情:
await page.waitForXPath("//td[contains(., 'All Projects')]")
const [ projects ] = await page.$x("//td[contains(., 'All Projects')]");
projects.click()
或简称:
page.waitForXPath("//td[contains(., 'All Projects')]").then(selector => selector.click())
问题
page.click
需要一个字符串(选择器)作为参数,但您传递的是元素句柄。
引用来自 page.waitForXPath
的文档:
returns: <Promise<?ElementHandle>> Promise which resolves when element specified by xpath string is added to DOM. Resolves to
null
if waiting forhidden: true
and xpath is not found in DOM.
这意味着您不能将该函数的结果(元素句柄)提供给 page.click
。
解决方案
相反,您可以使用 elementHandle.click
:
await page.waitForXPath("//td[contains(., 'All Projects')]")
.then(elementHandle => elementHandle.click())
但我建议使用 async
/await
语法来更符合您的代码的其余部分:
const elementHandle = await page.waitForXPath("//td[contains(., 'All Projects')]");
await elementHandle.click();