Skip to content

wait

以编程的方式控制浏览器最重要的就是判断页面是否加载完毕。有两种方式来实现,当然他们殊途同归。

  1. 通过事件来实现,为特定事件绑定特定的执行器即可
  2. 通过各种 wait 方法来实现,这些方法都是异步的。可以通过 then() 来绑定会掉来实现,它实际上可以看作是相对复杂的事件

Page/Frame.waitForSelector

等待 selector 指定的元素出现在页面中,该方法立即返回该元素(Promise<ElementHandle>):

JavaScript
import puppeteer from "puppeteer";
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  let currentURL;
  // 类似于 img 出现时触发事件
  page
    .waitForSelector("img")
    .then(() => console.log("First URL with image: " + currentURL));
  for (currentURL of [
    "https://example.com",
    "https://google.com",
    "https://bbc.com",
  ]) {
    await page.goto(currentURL);
  }
  await browser.close();
})();

Page/Frame.waitForNavigation

等待页面导航(goto/goforward/goback)到行的页面或重新加载(reload)时直接返回:

JavaScript
const [response] = await Promise.all([
  page.waitForNavigation().then(callable), // The promise resolves after navigation has finished
  page.click("a.my-link"), // Clicking the link will indirectly cause a navigation
]);

Page.waitForRequest

等待特定请求发出,其中能够接受 url: string 或者 AwaitablePredicate<HTTPRequest> 作为参数,返回特定的请求(Promise<HTTPRequest>):

JavaScript
// 接受 URL 即等待该 URL 发出
const firstRequest = await page.waitForRequest("https://example.com/resource");

// 接受一个函数,所有请求都会被传入
const finalRequest = await page.waitForRequest(
  (request) => request.url() === "https://example.com",
);
return finalRequest.response()?.ok();

Tips

有点类似 request 事件,并且能够监听网络

Page.waitForResponse

等待特定的请求发出并响应,他同样接受 url: string 或者 AwaitablePredicate<HTTPResponse> 作为参数,返回特定的请求(Promise<HTTPResponse>):

JavaScript
const firstResponse = await page.waitForResponse(
  "https://example.com/resource",
);
const finalResponse = await page.waitForResponse(
  (response) =>
    response.url() === "https://example.com" && response.status() === 200,
);
const finalResponse = await page.waitForResponse(async (response) => {
  return (await response.text()).includes("<html>");
});
return finalResponse.ok();

Tips

有点类似 response 事件,并且能够监听网络