jd 的評論是 js 渲染的,幾年前嘗試爬過,現在用 puppeteer 一試,清爽多了。 puppeteer 是 Headless Chrome Node API,官方倉庫:github.com/GoogleChrom…
由於很簡單,直接看程式碼註釋
const puppeteer = require('puppeteer');
const autoScroll = require('./autoScroll');
const url = 'https://item.jd.com/4311178.html';
async function crawler() {
// 新開一個瀏覽器,headless false 方便視覺化程式碼的操作
let browser = await puppeteer.launch({
headless: false
});
// 開一個 tab 頁
let page = await browser.newPage();
// 載入 url 頁面
await page.goto(url, {
waitUntil: 'networkidle2'
});
// 等一等
await page.waitFor(500);
// 點開評論 tab
await page.click('li[data-anchor="#comment"]');
// 滾一滾,讓評論載入載入,這個方法內容繼續往下看
// 不滾也可以,單純想展示一下 page.evaluate()
await autoScroll(page);
// 獲取評論,多數情況直接操作 dom 就可以了
// $eval 對應 document.querySelector,$$eval 對應 document.querySelectorAll,夠用了
let comments = await page.$$eval('.comment-item .comment-con', els => {
return els.map(item => item.innerText);
});
// 輸出一下評論,宣告抓到了
comments.forEach((item, index) => {
console.log(`comment ${index} =======================`);
console.log(item);
});
// 關閉瀏覽器
await browser.close();
}
crawler();
複製程式碼
autoScroll 程式碼
async function autoScroll(page){
// page.evaluate 能獲取上下文,相當於在當前頁面執行 js,想幹啥就幹啥
await page.evaluate(() => {
// 返回 promise,evaluate 會等 promise resolve
return new Promise((resolve, reject) => {
let totalHeight = 0;
let distance = 200;
let timer = setInterval(() => {
let scrollHeight = document.body.scrollHeight;
window.scrollBy(0, distance);
totalHeight += distance;
if(totalHeight >= scrollHeight){
clearInterval(timer);
resolve();
}
}, 500);
});
});
}
module.exports = autoScroll;複製程式碼