我正在尝试加载一个页面来抓取,仅在加载多个递归异步脚本后才加载我需要的数据。但由于页面和项目的数量,无法使用 Puppeteer 或 Selenium 之类的东西。 我尝试了 jsdom,因为它看起来很完美,有 cookie jar、DOM 和脚本执行。但似乎遇到了嵌套 XHR as 的问题
dom = new JSDOM(``, {
url: "https://www.pnp.co.za/c/pnpbase?currentPage=" + p_ind.toString(),
contentType: "text/html",
referrer: "https://pnp.co.za/",
includeNodeLocations: true,
resources: "usable",
storageQuota: 10000000,
pretendToBeVisual: true,
});
导致
querySelectorAll('div[class~="product-action"]')
找不到任何结果。
有什么帮助吗?
正如其他人指出的那样,使用
jsdom
可能不是最好的方法,因为这个库没有实现完整的无头浏览器。
不过,如果您想使用
jsdom
加载页面,则应该使用 fromURL
方法。当您期望页面执行其脚本时,您还需要在提供给方法的选项中添加runScripts: "dangerously"
。
此外,由于
jsdom
不支持某些浏览器 API,例如 IntersectionObserver
(在您要废弃的 URL 中使用),我们可以通过创建 jsdom
来消除 virtualConsole
向控制台抛出的错误。这会消除错误。
将所有这些放在一起,您可以在页面上刮擦以下行中的内容:
// Define and setup virtual console to mute jsdom errors.
const virtualConsole = new jsdom.VirtualConsole();
virtualConsole.on('error', () => {});
const url = 'https://www.pnp.co.za/c/pnpbase?currentPage=' + p_ind.toString();
JSDOM.fromURL(url, {
referrer: 'https://pnp.co.za/',
includeNodeLocations: true,
resources: 'usable',
storageQuota: 10000000,
pretendToBeVisual: true,
// Tell jsdom to execute the page scripts (take into account
// that this can be dangerous)
runScripts: 'dangerously',
// Use the virtual console
virtualConsole
}).then(dom => {
const { window } = dom;
// Now the page is loaded, you should wait for the contents you
// expect to scrap to be loaded. For simplicity let's use a
// setTimeout that will wait 20 seconds
setTimeout(() => {
const actions = window.document.querySelectorAll('a[class~="product-action"]');
}, 20000);
});