nodejs抓取动态网页(如何使用nodejs种的http(s)模块来请求目标网址)
优采云 发布时间: 2021-11-23 04:18nodejs抓取动态网页(如何使用nodejs种的http(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。
我们现在完成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('note-', ''),
title: unescape($(el).find('.title').html().replace(/&#x/g, '%u').replace(/;/g, '')),
href: $(el).find('.title').attr('href'),
})
})
console.log(articleList)
}
main()
这样我们就得到了文章的id、title和link。
这种方式捕获数据的优点是效率高,硬件资源少。但是这种方法也有一些缺点。例如,延迟加载页面很难抓取。因为延迟加载页面的内容是由浏览器js动态加载的,这样我们请求的页面,因为js还没有把内容渲染到页面,所以我们无法正确获取页面内容,而我们的请求也未能提供页面js所需的运行环境。这个时候我们将介绍我们的另一个爬虫。
无头浏览器
无头浏览器是指在后台运行的网页浏览器程序,没有操作界面。常用的无头浏览器有PhantomJS、Selenium、Puppeteer等(还有很多很多,有兴趣的可以去看看)。
Headless 浏览器常用于自动化测试、爬虫等技术。它提供了浏览器js所需的运行环境,我们可以用它来处理延迟加载页面。
Puppeteer 是 Google 发布的 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()
我们使用节点demo2来执行:
我们现在已经用代码打开了一个浏览器窗口。接下来我们会继续完善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()
执行这段代码,我们得到以下结果:
这是无头浏览器的基本用法。它还提供了很多方便的API,比如page.waitFor(selector, pageFun)`方法,可以在执行pageFun方法之前等待一个元素出现在页面上。还有一个`page.addScriptTag(options)方法,可以直接将自己的js脚本注入页面。
在此再次请大家不要滥用爬虫采集资源攻击他人服务器。
两种方法的比较