点击后等待响应

时间:2017-11-09 17:10:49

标签: node.js ajax google-chrome puppeteer

我点击按钮,发送ajax请求并更改输入隐藏值。 我如何等待答案并追踪隐藏字段的变化?

我曾尝试过“睡觉”并获取事件,但有时你得到的数据不好,因为请求很长。

http.createServer(async (req, res) => {
if (req.url === '/') {
    if (req.method === 'GET') {
        res.writeHead(200, {
            'content-type': 'text/html; charset=utf-8',
            'cache-control': 'public,max-age=31536000',
        });
        res.end(fs.readFileSync(__dirname + '/templates/index.html'));
        return;
    } else if (req.method === 'POST') {

        let body = '';
        await req.on('data', (data) => body += data);

        body = qs.parse(body);

        let url = body.url;

        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto(url);

        let count = (selector) => page.evaluate((selector) => {
            return (document.querySelectorAll(selector)).length;
        }, selector);

        let sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

        const countM = await count(MSEL),
            countS = await count(SSEL);
        console.log(countS, countM);

        let click = (selector, number) => page.click(`${selector}:nth-child(${number})`);

        let data = [];

        for (let i = 1; i <= countS; i++) {
            await click(SSEL, i);
            sleep(SLEEP);

            for (let j = 1; j <= countM; j++) {
                await click(MSEL, j);
                sleep(SLEEP);

                const info = await page.evaluate(() => {
                    return {
                        val: document.getElementById('val').value,
                        cc: document.getElementById('cc').value
                    };
                });
                data.push(info);
            }
        }
    }

} else {
    res.writeHead(400, {
        'content-type': 'text/plain',
    });
    res.end('Something is wrong. Missing URL.');
    return;
}
}).listen(3000);

抱歉我的英文。 谢谢

1 个答案:

答案 0 :(得分:0)

在回答之前,我可以问你很多问题,

  • 什么是MSEL和SSEL?
  • 什么是网址?
  • templates / index.html中有什么内容?
  • 你得到了什么样的不良数据?
  • 为什么要在循环中循环?
  • 为什么你有睡眠()承诺,但没有等待这个承诺?
  • 将信息推送到数据时会发生什么,是否将其作为响应返回?

等等列表可以继续,但我们必须从某个地方开始,对吧?我不会写完整个代码,并为你做一切。但我会帮你理解这个问题。

你的代码中有很多部分缺失,而且因为你没有正确地写东西而有错误。

我将功能分开。我假设你有一个名为MSEL的变量,某个地方定义了SSEL。

首先,你没有回复任何东西。这是你需要注意的事情,如果你没有返回响应,那么请求永远不会结束,并导致超时。

http
  .createServer(async (req, res) => {
    if (req.url === "/") {
      if (req.method === "GET") {
        res.writeHead(200, {
          "content-type": "text/html; charset=utf-8",
          "cache-control": "public,max-age=31536000"
        });
        res.end(fs.readFileSync(__dirname + "/templates/index.html"));
        return;
      } else if (req.method === "POST") {
        let body = "";
        await req.on("data", data => (body += data));
        body = qs.parse(body);
        const returnData = await getData({ body, MSEL, SSEL }); // <-- seperate the function
        res.end(returnData); // <-- return the data
      }
    } else {
      res.writeHead(400, {
        "content-type": "text/plain"
      });
      res.end("Something is wrong. Missing URL.");
      return;
    }
  })
  .listen(3000);

这里是单独的函数,注意我在睡眠之前写了一个等待,并且稍微重构了一些位和部分,并在完成所有操作后返回函数。

async function getData({ body, MSEL, SSEL }) {
  let url = body.url;

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(url);

  let count = selector =>
    page.evaluate(selector => {
      return document.querySelectorAll(selector).length;
    }, selector);

  let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

  const countM = await count(MSEL),
    countS = await count(SSEL);

  let click = (selector, number) =>
    page.click(`${selector}:nth-child(${number})`);

  let data = [];

  for (let i = 1; i <= countS; i++) {
    await click(SSEL, i);
    await sleep(SLEEP);

    for (let j = 1; j <= countM; j++) {
      await click(MSEL, j);
      await sleep(SLEEP);

      const info = await page.evaluate(() => {
        return {
          val: document.getElementById("val").value,
          cc: document.getElementById("cc").value
        };
      });
      data.push(info);
    }
  }
  return data;
}

我所做的是重构和修改你的代码,但这不是你正在寻找的解决方案,代码可能甚至不起作用。

您需要了解承诺如何运作。在复制粘贴我的解决方案之前,请参阅以下教程,希望它能正常工作;),