我正在制作一个需要在用户在网站上注册或更新个人资料时将用户与第三方网站同步的应用程序。我已经使Puppeteer登录,然后导航到请求的页面并打开了用于用户编辑的模式。但是,由于某种原因,它没有在字段中填写信息。 XPath有效且可以正常工作,我也尝试使用普通的querySelector路径。它找到包含这两个元素的元素,但不会更新值。
这是我要实现的HTML:
<form action="user_process.php?task=edit" method="post" class="ui-modal-form wide" id="edit-user-modal" style="width:840px;">
<input type="hidden" name="userid" value="8800">
<fieldset>
<ul>
<li>
<label>Name</label>
<input type="text" placeholder="Ime i prezime" name="name" value="">
</li>
<li>
<label>User *</label>
<input type="text" placeholder="Username" name="user" value="">
</li>
<li>
<label>Password *</label>
<input type="text" placeholder="Sifra" name="pass" value="">
</li>
<li>
<label>E-mail</label>
<input type="text" placeholder="Email adresa" name="email" value="">
</li>
<li>
<label>Support</label>
<select name="support">
<option value="0">No</option>
<option value="1">Yes</option>
</select>
</li>
<li>
<label>Servers:</label><br><br>
<div class="dataTables_wrapper"><div class="dataTables_filter">Search: <input type="text"></div><table class="data-table" style="">
<thead>
<tr>
<th width="50%" style="text-align:center;vertical-align: middle;" class="sorting_disabled">Server</th>
<th width="30%" style="text-align:center;vertical-align: middle;" class="sorting_disabled">IP</th>
<th width="10%" style="text-align:center" class="sorting_disabled">WebFTP Access</th>
<th width="10%" style="text-align:center" class="sorting_disabled">View FTP Info</th>
</tr>
</thead>
<tbody><tr class="odd">
<td><label style="width: 100%;"><input type="checkbox" class="servercheckbox" style="top:-4px;" name="60203" value="1"> Xtreme COD:MW4</label></td>
<td style="text-align:right"><a target="_blank" href="gp-info.php?id=60203">176.57.142.179:27022</a> </td>
<td style="text-align:center"><input type="checkbox" class="servercheckbox" name="webftp_access[60203]" value="1"> </td>
<td style="text-align:center"><input type="checkbox" class="servercheckbox" name="view_ftpinfo[60203]" value="1"> </td>
</tr><tr class="even">
<td><label style="width: 100%;"><input type="checkbox" class="servercheckbox" style="top:-4px;" name="60205" value="1"> FDL</label></td>
<td style="text-align:right"><a target="_blank" href="gp-info.php?id=60205">193.192.58.55:1</a> </td>
<td style="text-align:center"><input type="checkbox" class="servercheckbox" name="webftp_access[60205]" value="1"> </td>
<td style="text-align:center"><input type="checkbox" class="servercheckbox" name="view_ftpinfo[60205]" value="1"> </td>
</tr><tr class="odd">
<td><label style="width: 100%;"><input type="checkbox" class="servercheckbox" style="top:-4px;" name="60353" value="1"> Xtreme CW</label></td>
<td style="text-align:right"><a target="_blank" href="gp-info.php?id=60353">193.192.59.233:27025</a> </td>
<td style="text-align:center"><input type="checkbox" class="servercheckbox" name="webftp_access[60353]" value="1"> </td>
<td style="text-align:center"><input type="checkbox" class="servercheckbox" name="view_ftpinfo[60353]" value="1"> </td>
</tr></tbody></table></div>
</li>
<li>
<button>Sacuvaj</button>
</li>
</ul>
</fieldset>
</form>
我尝试使用的伪造者代码:
第一个变体:
try {
// Wait for the table
await page.waitForXPath('//table[contains(@class, "data-table")]//tbody//tr//a[contains(text(), "Edit") and contains(@data-user, "TestName") and contains(@data-user, "[email protected]")]')
.catch(e => console.log('Edit button not found!'));
// This works - Start
const [EditButton] = await page.$x('//table[contains(@class, "data-table")]//tbody//tr//a[contains(text(), "Edit") and contains(@data-user, "TestName") and contains(@data-user, "[email protected]")]');
if(EditButton) {
console.log('Edit button is found!');
await EditButton.click();
} else throw new Error('Edit Button is not found!');
// This works - End
// This does not work - Start
const [NameInputField] = await page.$x('//form[@id="edit-user-modal"]//fieldset//ul//li//input[@name="name"]');
if (NameInputField) {
await NameInputField.focus();
await page.keyboard.type('New Test name', {delay: 1});
console.log("Name input field is found!");
} else {
console.log("Name input field is not found!");
await page.close();
}
// This does not work - End
await sleep(10000);
// This works
await page.$eval('form#edit-user-modal > fieldset > ul > li > button', (e, n) => e.click());
} catch (error) {
console.error(error);
}
第二变形:
try {
// Wait for the table
await page.waitForXPath('//table[contains(@class, "data-table")]//tbody//tr//a[contains(text(), "Edit") and contains(@data-user, "TestName") and contains(@data-user, "[email protected]")]')
.catch(e => console.log('Edit button not found!'));
// This works - Start
const [EditButton] = await page.$x('//table[contains(@class, "data-table")]//tbody//tr//a[contains(text(), "Edit") and contains(@data-user, "TestName") and contains(@data-user, "[email protected]")]');
if(EditButton) {
console.log('Edit button is found!');
await EditButton.click();
} else throw new Error('Edit Button is not found!');
// This works - End
// This does not work - Start
await page.waitForSelector('form#edit-user-modal > fieldset > ul > li > input[name="name"]');
await page.$eval('form#edit-user-modal > fieldset > ul > li > input[name="name"]', (e, n) => e.setAttribute('value', 'NewTestName'));
await page.$eval('form#edit-user-modal > fieldset > ul > li > input[name="user"]', (e, n) => e.setAttribute('value', 'NewTestUser'));
await page.$eval('form#edit-user-modal > fieldset > ul > li > input[name="pass"]', (e, n) => e.setAttribute('value', 'NewTestPassword'));
await page.$eval('form#edit-user-modal > fieldset > ul > li > input[name="email"]', (e, n) => e.setAttribute('value', '[email protected]'));
// This does not work - End
await sleep(10000);
// This works
await page.$eval('form#edit-user-modal > fieldset > ul > li > button', (e, n) => e.click());
} catch (error) {
console.error(error);
}
第三变形:
try {
// Wait for the table
await page.waitForXPath('//table[contains(@class, "data-table")]//tbody//tr//a[contains(text(), "Edit") and contains(@data-user, "TestName") and contains(@data-user, "[email protected]")]')
.catch(e => console.log('Edit button not found!'));
// This works - Start
const [EditButton] = await page.$x('//table[contains(@class, "data-table")]//tbody//tr//a[contains(text(), "Edit") and contains(@data-user, "TestName") and contains(@data-user, "[email protected]")]');
if(EditButton) {
console.log('Edit button is found!');
await EditButton.click();
} else throw new Error('Edit Button is not found!');
// This works - End
// This does not work - Start
await page.waitForSelector('form#edit-user-modal > fieldset > ul > li > input[name="name"]');
await page.type('form#edit-user-modal > fieldset > ul > li > input[name="name"]', "New Test Name", {delay: 1});
// This does not work - End
await sleep(10000);
// This works
await page.$eval('form#edit-user-modal > fieldset > ul > li > button', (e, n) => e.click());
} catch (error) {
console.error(error);
}
昨天,当XPath方法不能用于添加用户时,我已经用$ eval选择器解决了,但是对于用户编辑,它也不能正常工作。我正在关注文档,代码似乎还可以。你能帮我解决这个问题吗?谢谢。
您可以在页面中运行js,这样可能会对您有所帮助。
const result = await page.evaluate(_ => {
const element = document.querySelector(`'form#edit-user-modal > fieldset > ul > li > input[name="name"]'`);
if (element) {
element.setAttribute('value', 'NewTestName');
} else {
return 'there is no element. maybe you need to wait until dom rendered and try again. or your selector is wrong?';
}
});
console.log(result);
我已经重新安装了puppeteer并清除了NPM缓存,并且神奇地以某种方式开始工作。这真是奇怪。我还添加了超时值30000(30秒),并按照您的建议进行了正确的错误处理。感谢您的时间和帮助。如果将来有人遇到示例问题,请尝试先清除NPM缓存,然后删除node_modules,然后再次安装模块。另外,像我一样添加一些超时并使用await page.waitForSelector。