nodejs抓取动态网页(谷歌发布的一款Chromium无头的基本使用(s)模块)
优采云 发布时间: 2022-01-25 10:04nodejs抓取动态网页(谷歌发布的一款Chromium无头的基本使用(s)模块)
我们可以使用 nodejs 的 http(s) 模块来请求目标 URL,也可以使用 axios 之类的第三方库来请求网页。拿到html后,使用html解析库解析成方便的js对象,然后抓取目标内容。这里推荐解析库cheerio。Cheerio 提供了类似 jQuery 的操作方式,可以轻松抓取我们想要的内容。
// demo1
const cheerio = require('cheerio')
const axios = require('axios')
async function main() {
const resp = await axios.get('https://www.jianshu.com/')
console.log(resp.data)
}
main()
通过节点demo1执行demo1,我们可以得到短书首页的html。
图像.png
现在让我们改进demo1的代码,使用cheerio来解析html。
// demo1
const cheerio = require('cheerio')
const axios = require('axios')
async function main() {
const resp = await axios.get('https://www.jianshu.com/')
const $ = cheerio.load(resp.data)
const articleList = []
$('#list-container li').each((i, el) => {
articleList.push({
id: $(el).attr('id').replace('', ''),
title: unescape($(el).find('.title').html().replace(/&#x/g, '%u').replace(/;/g, '')),
href: $(el).find('.title').attr('href'),
})
})
console.log(articleList)
}
main()
图像.png
这样我们就得到了文章的id、title和link。
采用这种方式捕获数据的优点是效率高,占用的硬件资源极少。但是这种方法也有一些缺点。例如,延迟加载页面很难爬取。因为懒加载页面的内容是由浏览器js动态加载的,这样对于我们请求的页面,由于js还没有渲染页面上的内容,我们无法正确获取页面内容,而我们的请求也未能提供页面js所需的运行环境。这时候,我们将介绍另一种爬虫。
无头浏览器
无头浏览器是一种在后台运行的网络浏览器程序,没有操作界面。常用的无头浏览器有PhantomJS、Selenium、Puppeteer等(还有很多很多,有兴趣的可以去看看)。
无头浏览器常用于自动化测试、爬虫等技术。它提供了浏览器js所需的运行环境,我们可以利用它来处理延迟加载的页面。
Puppeteer 是谷歌发布的 Chromium 无头浏览器。这里我们以 Puppeteer 为例,编写一些小 Demo。
// demo2
const puppeteer = require('puppeteer');
async function main() {
const browser = await puppeteer.launch({
// 是否为无头,无头模式下没有用户操作界面
headless: false,
defaultViewport: null
})
const page = await browser.newPage();
await page.goto('https://www.jianshu.com/u/04d11dd2f924');
}
main()
让我们使用 node demo2 来执行:
图像.png
我们现在已经用代码打开了一个浏览器窗口。接下来我们会继续完善demo2来爬取这个页面的内容。
// demo2
const puppeteer = require('puppeteer');
async function main() {
const browser = await puppeteer.launch({
// 是否为无头,无头模式下没有用户操作界面
headless: false,
defaultViewport: null,
devtools: true,
})
const page = await browser.newPage();
await page.goto('https://www.jianshu.com/u/04d11dd2f924');
const articleList = await page.$$eval('#list-container li', els =>
els.map(el => {
const id = el.dataset.noteId
const title = el.querySelector('.title').innerText
const url = el.querySelector('.title').href
return {id, title, url}
})
)
console.log(articleList)
}
main()
执行这段代码,我们得到以下结果:
图像.png
这是无头浏览器的基本用法。它还提供了很多方便的API,比如page.waitFor(selector, pageFun)方法,它可以在执行pageFun方法之前等待一个元素出现在页面上。还有page.addScriptTag(options)方法,可以直接在页面上使用。注入你自己的js脚本。
在这里,再次请大家不要滥用爬虫采集的资源去攻击别人的服务器。
两种方式的比较