在没有ID或标识属性的情况下填写输入字段时出现问题。(木偶戏演员)

2022-03-11 00:00:00 node.js puppeteer javascript

以下是我要键入的输入元素:

<input name="name" ng-model-options="{ debounce: 300 }" ng-model="contestantState.form.name" ng-pattern=".*" placeholder="Alice Smith" required="" style="width: 246px" type="text" class="ng-empty ng-invalid ng-invalid-required ng-valid-pattern ng-dirty ng-valid-parse ng-touched">

我的一次尝试:

 await page.type('input[name="name"]',"my name");

无论我如何尝试在此字段中键入内容,都不会发生任何情况:它保持为空,因为它无法通过其名称或类进行识别。

如何才能让木偶人在该字段中输入姓名?

我尝试这样做的网站是:https://gleam.io/hxVaH/win-a-krooked-big-eyes-too-skateboard?gsr=hxVaH-4hKgdgSzfh (全名和电子邮件字段)。


解决方案

现有答案很有用,但这应该可以完成完整的深渊翻滚并为您提供共享URL。

由于此AngularJS应用程序似乎不太使用ID和类,因此使用文本内容似乎是点击几个按钮的合理选择。

我必须使用.evaluate(el => el.click())而不是.click()成功单击其中一个按钮,如here所述。

const puppeteer = require("puppeteer");

const clickXPath = async (page, xp) => {
  await page.waitForXPath(xp);
  const [el] = await page.$x(xp);
  await el.evaluate(el => el.click());
};

const randomEmail = () => 
  Array(10).fill().map(() => 
    String.fromCharCode(~~(Math.random() * 26 + 97))
  ).join("") + 
  `${(Math.random() + "").replace(/./, "")}@gmail.com`
;

let browser;
(async () => {
  const url = "https://gleam.io/hxVaH/win-a-krooked-big-eyes-too-skateboard";
  browser = await puppeteer.launch({headless: false});
  const [page] = await browser.pages();
  await page.goto(url, {waitUntil: "networkidle0"});
  await clickXPath(page, `//span[contains(text(), "Refer Friends")]`);
  const nameSel = '[class="entry-method  expanded"] input[name="name"]';
  const emailSel = '[class="entry-method  expanded"] input[name="email"]';
  await page.waitForSelector(nameSel);
  await page.type(nameSel, "my name33");
  await page.type(emailSel, randomEmail());

  const hasText = () => page.evaluate(() => 
    !!document.querySelector(".share-link__link")?.innerText.trim()
  );

  for (let tries = 1000; !(await hasText()) && tries--;) {
    await clickXPath(page, `//span[contains(text(), "Save")]`);
    await page.waitForTimeout(100);
  }

  const shareCode = await page.$eval(".share-link__link", el => el.innerText);
  console.log(shareCode); // => https://wn.nr/w9Wz5p
})()
  .catch(err => console.error(err))
  .finally(async () => await browser.close())
;

相关文章