首先,在阻止请求和禁用 JS 方面做得很好!这大大加快了脚本的速度,意味着我们可以完全依赖
view-source:
来简化问题。
一个问题是:
e.querySelector(".fc-item__media-wrapper .responsive-img src"),
这表示“在带有
<src>
的元素内返回带有 class="responsive-img"
的元素内的 class="fc-item__media-wrapper"
标签”。你可能是说:
e.querySelector(".fc-item__media-wrapper .responsive-img")
?.getAttribute("src")
至于“文本”,我不确定那指的是什么,因为
.fc-item__media-wrapper
类中的任何地方都没有文本。
如果您正在寻找踢球者的文字或标题,这是一种方法:
const fs = require("node:fs/promises");
const puppeteer = require("puppeteer"); // ^19.6.3
const url = "<Your URL>";
let browser;
(async () => {
browser = await puppeteer.launch();
const [page] = await browser.pages();
await page.setJavaScriptEnabled(false);
await page.setRequestInterception(true);
page.on("request", req => {
if (req.url() !== url) {
req.abort();
}
else {
req.continue();
}
});
await page.goto(url, {waitUntil: "domcontentloaded"});
const data = await page.$$eval(".fc-item__container", els =>
els.map(e => {
const $ = s => e.querySelector(s);
const text = s => $(s)?.textContent.trim();
return {
src: $(".fc-item__media-wrapper .responsive-img")
?.getAttribute("src"),
kicker: text(".fc-item__kicker"),
headline: text(".fc-item__headline"),
};
})
);
console.log(data);
await fs.writeFile("img_src.json", JSON.stringify(data, null, 2));
})()
.catch(err => console.error(err))
.finally(() => browser?.close());
顺便说一下,一旦您达到阻止所有请求并禁用 JS 的地步,您通常可以只需将 fetch(或 axios,如果您还没有在 Node 18 上)与 Cheerio 一起使用。这简化了事情并进一步加快了速度:
const cheerio = require("cheerio"); // 1.0.0-rc.12
const url = "<Your URL>";
fetch(url)
.then(res => {
if (!res.ok) {
throw Error(res.statusText);
}
return res.text();
})
.then(html => {
const $ = cheerio.load(html);
const data = [...$(".fc-item__container")].map(e => ({
src: $(e).find(".fc-item__media-wrapper .responsive-img").attr("src"),
kicker: $(e).find(".fc-item__kicker").text().trim(),
headline: $(e).find(".fc-item__headline").text().trim(),
}));
console.log(data);
})
.catch(err => console.error(err));