我一直在尝试使用 puppeteer 来抓取 Twitch。
这个程序的想法是获取第一页“Just Chatting”类别中每个流的图标、用户名和缩略图。 我认为我的主要代码正在工作,但是我试图返回的对象(属性)被返回为未定义。
我尝试在函数 log() 中的 console.log 后面添加等待,我还在这里搜索了它并读到从评估函数返回的值必须是 json 可序列化的,我相信它确实包含对象所包含的字符串将有。任何帮助将不胜感激,谢谢!
let properties = { icon: [], user: [], img: [], link: [] };
const puppeteer = require('puppeteer');
let elements = {
'https://www.twitch.tv/directory/game/Just%20Chatting': [
'img[class="InjectLayout-sc-588ddc-0.iyfkau.tw-image.tw-image-avatar"]',
'a[class="ScCoreLink-udwpw5-0.cxXSPs.tw-link"]',
'img[class="tw-image"]',
],
};
async function scrapeStreams() {
console.log('scrape started');
try {
console.log('try started');
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.setDefaultNavigationTimeout(0);
await page.goto(Object.keys(elements)[0], { waitUntil: 'networkidle2' });
await page.evaluate(
(properties, elements) => {
for ([key, value] of Object.entries(elements)) {
if ((key = Object.keys(elements)[0])) {
value.forEach((element) => {
if ((element = Object.values(elements)[0])) {
el = document.querySelector(element);
for (let val in el) {
datatype = val.src;
Object.values(properties)[0].push(datatype);
}
} else if ((element = Object.values(elements)[1])) {
el = document.querySelector(element);
for (let val in el) {
datatype = val.innerHTML;
Object.values(properties)[1].push(datatype);
}
} else if ((element = Object.values(elements)[2])) {
el = document.querySelector(element);
for (let val in el) {
datatype = val.src;
Object.values(properties)[2].push(datatype);
}
}
});
}
}
return properties;
},
properties,
elements
);
} catch (error) {
console.log('THIS IS THE ERROR: ' + error);
}
}
async function log() {
let properties = await scrapeStreams();
console.log(properties);
}
log();
page.evaluate()
的函数参数内部和外部的变量是不一样的:它们在Node.js和浏览器上下文之间传输时被复制。因此,当您更改 properties
内部的 page.evaluate()
时,外部 properties
保持不变。当您在 return properties;
中使用 page.evaluate()
时,您不会保存返回值。
你忘记在
scrapeStreams()
中返回值。
但是,您的代码中似乎还存在一些其他问题(返回了许多
null
),但您可以使用另一个问题来解决它们。
// ...
// FIXED:
properties = await page.evaluate(
// ...
// FIXED:
return properties;
} catch (error) {
console.log('THIS IS THE ERROR: ' + error);
}
}
// ...