jd 的评论是 js 渲染的,几年前尝试爬过,现在用 puppeteer 一试,清爽多了。 puppeteer 是 Headless Chrome Node API,官方仓库:https://github.com/GoogleChrome/puppeteer
由于很简单,直接看代码注释
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);// 点开评论 tabawait 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 resolvereturn 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;
更多专业前端知识,请上 【猿2048】www.mk2048.com