对于剧作家来说,我还是个新手,对某些东西很着迷.我正在使用它来自动化一个原本需要手动输入数据的过程.具体流程如下:

  • 循环访问数组中的多个对象
  • 在页面上找到包含对象名称(Str)的类别并单击它,然后单击另一个打开对话框的按钮
  • 在打开对话框中,找到包含在也包含字符串名称的表单域中的输入(该对话框基本上是具有价格输入的多个表单),并使用新的价格值填充该输入
  • 关闭该对话框,返回项目,然后移至下一个项目

我对此过程的简化代码如下:

const playwright = require("playwright");
const state = {
  str: "",
  step: "",
};
var page;
var frameLocator;

var items = [
  {
    str: "A50",
    price: 0,
  },
  {
    str: "AP2",
    price: 23,
  },
  {
    str: "B25",
    price: 406,
  },
  {
    str: "C72",
    price: 309,
  },
  {
    str: "CB1",
    price: 0,
  },
];
var results = [];

async () => {
  const browser = await playwright.chromium.launch({
    headless: false,
    slowMo: 1000,
  });
  const url = "https://example.com";
  const context = await browser.newContext();
  page = await context.newPage();
  page.on("domcontentloaded", async (e) => {
    await page.waitForSelector("#ContentFrame");
    frameLocator = await page.locator("#ContentFrame").frameLocator(":scope");
    for (let i = 0; i < items.length; i++) {
      var result = await updatePrice(items[i].str, items[i].price);
      results.push(result);
    }
  });
};

async function updatePrice(str, price) {
  state.str = str;
  var item = {
    str: str,
    newPrice: price,
  };
  state.step = "Finding Category";
  const category = await frameLocator
    .locator(".section")
    .filter({ hasText: str });
  await category
    .elementHandle({ timeout: 5000 })
    .then(async () => {
      item.cat = await category.locator(".info-title").innerText();
      await category.click();
      await page.locator("#toolbar button").first().click();
      state.step = "Finding input";
      var input = await page
        .locator(".dialog .multifield")
        .filter({ hasText: str })
        .locator("input");
      state.step = "Updating input";
      await page.waitForTimeout(2000);
      await input.evaluateHandle((node, price) => {
        node.value = price;
      }, price);
      state.step = "Done updating input";
      await page.locator(".dialog .submit").click();
    })
    .catch(async (err) => {
      //Some other irrelevant error handling logic goes here
    });
  return item;
}

代码运行得很好,但在整个for循环中的任意点,浏览器页面都会崩溃(只会出现"页面崩溃"错误,浏览器不会关闭)--不是每次我运行循环时,而是大多数时候.您可以看到,我已经添加了一些Slomo并在填充输入之前等待一段时间,以try 降低脚本速度,但我不确定这是有帮助还是有坏处.这段代码中有什么我可以重构以减少或消除页面崩溃的地方吗?谢谢!

推荐答案

我看不出您的代码有任何问题.有时标签确实会崩溃.修复Tab键崩溃的最好办法是try 不同的浏览器,或者同一浏览器的不同版本.

Different version of Chromium

更新PlayWright以获取更新的Chromium版本

Playwright says:

每个版本的PlayWright都需要特定版本的浏览器二进制文件才能运行.根据您使用的语言,Playwright将在安装程序包时为您下载这些浏览器,或者您需要使用Playwright CLI来安装这些浏览器.

当您安装程序包时,NPM会安装浏览器二进制文件.安装新版本的playwright程序包也将更新已安装的二进制文件.这是很好的第一步.

npm i playwright@latest

然后再次try 运行您的代码.

更改Chromium频道

您可以通过在启动配置中指定channel来更改Chromium频道:

  const browser = await playwright.chromium.launch({
    headless: false,
    slowMo: 1000,
    channel: "chrome", //chrome,chrome-beta,chrome-dev,chrome-canary,msedge,msedge-beta,msedge-dev,msedge-canary
  });

Changing browsers

剧作家的作品有好几个引擎.你可以试试 firefox .

  const browser = await playwright.firefox.launch({

Javascript相关问答推荐

在JavaScript中,如何将请求的回调函数的结果合并到运行的代码中?

Flisk和JS错误:未捕获的Syntax错误:意外的令牌'<'

我应该在redux reducer中调用其他reducer函数吗?

按钮未放置在html dis位置

Bootstrap动态选项卡在切换选项卡后保持活动状态,导致元素堆叠

如何从JSON数组添加Google Maps标记—或者如何为数组添加参数到标记构造器

docx.js:如何在客户端使用文档修补程序

处理时间和字符串时MySQL表中显示的日期无效

CheckBox作为Vue3中的一个组件

使用原型判断对象是否为类的实例

Web Crypto API解密失败,RSA-OAEP

如何在.NET Core中将chtml文件链接到Java脚本文件?

使用NextJS+MongoDB+Prisma ORM获取无效请求正文,无法发布错误

第一项杀死下一项,直到数组长度在javascript中等于1

每次重新呈现时调用useState initialValue函数

如何使用Astro优化大图像?

在Vercel中部署Next.js项目时获取`ReferenceError:未定义文档`

我无法在Api Reaction本机上发出GET请求

谷歌饼图3D切片

Plotly.js栏为x轴栏添加辅助文本