POST 如何在 puppeteer 中请求?

how do POST request in puppeteer?

(async() => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://www.example.com/search');
    const data = await page.content();
    browser.close();
    res.send(data);
})();

我为发送 get 请求执行此代码。我不明白我应该如何发送 post 请求?

正确 "order" 可能有点挑战。文档中没有那么多示例……示例文件夹中的存储库中有一些有趣的项目,您绝对应该看看。

https://github.com/GoogleChrome/puppeteer/tree/master/examples

这是例子;将以下内容放入异步块中:

    // Create browser instance, and give it a first tab
    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    // Allows you to intercept a request; must appear before
    // your first page.goto()
    await page.setRequestInterception(true);

    // Request intercept handler... will be triggered with 
    // each page.goto() statement
    page.on('request', interceptedRequest => {

        // Here, is where you change the request method and 
        // add your post data
        var data = {
            'method': 'POST',
            'postData': 'paramFoo=valueBar&paramThis=valueThat'
        };

        // Request modified... finish sending! 
        interceptedRequest.continue(data);
    });

    // Navigate, trigger the intercept, and resolve the response
    const response = await page.goto('https://www.example.com/search');     
    const responseBody = await response.text();
    console.log(responseBody);

    // Close the browser - done! 
    await browser.close();

这里是 Puppeteer 2.0.0 的完整示例:

    const puppeteer = require("puppeteer");
    const devices = require("puppeteer/DeviceDescriptors");

    async function main() {
      const browser = await puppeteer.launch({
        args: ["--enable-features=NetworkService", "--no-sandbox"],
        ignoreHTTPSErrors: true
      });
      const page = await browser.newPage();

      await page.setRequestInterception(true);

      page.once("request", interceptedRequest => {
        interceptedRequest.continue({
          method: "POST",
          postData: "foo=FOO&bar=BAR",
          headers: {
            ...interceptedRequest.headers(),
            "Content-Type": "application/x-www-form-urlencoded"
          }
        });
      });

      const response = await page.goto("https://postman-echo.com/post");

      console.log({
        url: response.url(),
        statusCode: response.status(),
        body: await response.text()
      });

      await browser.close();
    }

    main();

请注意,如果您选中 response.request().method(),它将不会更新(仍然是 GET)

setRequestInterception'request' 事件的运作方式有一个怪癖。激活后,Puppeteer 会将 POST 数据发送到页面上的每个资源,而不仅仅是原始请求的页面。我遇到的问题是,一旦我在 Puppeteer 中添加 POST 数据,我的所有页面资源(脚本,CSS)都无法加载。

因为我只想将 POST 数据应用于第一个请求,所以这段代码对我有用:

// Used for serializing POST parameters from an object
const querystring = require('querystring');

// ...

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

let postData = {a: 1, b: 2};

await page.setRequestInterception(true);

page.once('request', request => {
    var data = {
        'method': 'POST',
        'postData': querystring.stringify(postData),
        'headers': {
            ...request.headers(),
            'Content-Type': 'application/x-www-form-urlencoded'
        },
    };

    request.continue(data);

    // Immediately disable setRequestInterception, or all other requests will hang
    page.setRequestInterception(false);
});

const response = await page.goto('https://www.example.com/');