puppeteer.js中:
const puppeteer = require("puppeteer");
const cookieObj = require('./cookie');
const path = require('path');
const fs = require('fs');
async function start() {
const browser = await puppeteer.launch({ headless: false, executablePath: path.resolve('F:/aaa/chrome-win/chrome.exe'), });
const page = await browser.newPage();
cookieObj.forEach((cookie) => {
page.setCookie(cookie);
});
await page.goto("https://juejin.cn/user/1873223546320967/pins");//打开页面
//计算列表内容的总高度,并设置视窗大小,确保所有的列表项都在可见区域内
const listHeight = await page.evaluate(() => document.querySelector('#juejin').scrollHeight);
console.log("listHeight=",listHeight)
await page.setViewport({ width: 1280, height: listHeight }); // 设置浏览器视窗大小
// 模拟滚动操作获取所有列表项
let pins = [];
let previousHeight;
while (true) {
const currentHeight = await page.evaluate(() => document.querySelector('#juejin').scrollHeight);
console.log("currentHeight=",currentHeight)
if (currentHeight === previousHeight) {
break;
}
previousHeight = currentHeight;
console.log("previousHeight=",previousHeight)
//`page.evaluate()`是一个 Puppeteer 中的页面方法,其作用是在当前页面上下文环境中执行指定的 JavaScript 代码。
//而本行代码 `window.scrollBy(0, ${currentHeight})` 的作用是控制页面进行垂直方向的滚动。该代码调用了DOM中定义的`window`对象的`scrollBy(x-coord, y-coord)`方法,其中:
//- x-coord:表示水平方向上滚动距离,此处为 0,表示不进行水平方向的滚动;
//- y-coord:表示垂直方向上滚动距离。该值通过 `${currentHeight}` 表示,是一个变量,具体值根据页面内容高度而定。
//也就是说,这行代码的作用是让页面往垂直方向上滚动一段特定的距离,以便加载新的数据。在获取有滚动条的列表//中的所有数据时,需要多次调用该代码,循环滚动页面,直到读取所有数据为止。
await page.evaluate(`window.scrollBy(0, ${currentHeight})`);
// 等待新列表项加载完成
await page.waitForTimeout(1000);
await page.waitForSelector(".list-block>.detail-list>.list-body>div>.like-list-box>ul.pin-list>li.item.shadow");
pins = await page.evaluate((pins) => {
const list = document.querySelectorAll(".list-block>.detail-list>.list-body>div>.like-list-box>ul.pin-list>li.item.shadow");
list.forEach(item => {
console.log(item)
pins.push({
time: item.querySelector('time').innerText,
content: item.querySelector('.content').innerText,
auth: item.querySelector('.username').innerText,
})
})
console.log("pins=", pins.length)
return pins
}, pins)
}
const uniqueArr = pins.reduce((prev, curr) => {//获取到的数据有重复的需要去重
if (prev.find(item => item.content === curr.content && item.time === curr.time)) {
return prev;
}
return prev.concat(curr);
}, []);
//将爬取到的数据写入本地json文件中
fs.writeFile('./data.json',JSON.stringify(uniqueArr),function(err){
if(err){
return console.log(err)
}else{
console.log('写入成功!')
}
})
return uniqueArr;
}
module.exports = start
index.js中:
const express = require('express')
const start = require('./puppeteer')
const app = express()
app.get('/pins', async function (req, res) {
const pins = await start()
res.send(pins)
})
app.listen(9999)