如何用JavaScript爬取一个网页?

爬取一个网页是一个网络爬虫的一个最基本的操作,那么如何用JavaScript来实现这个呢?

简单来说,爬取一个网页,需要以下三步:

1. 根据URL下载一个网页

我们使用axios库来下载我们的网页。Axios是一个非常简单易用、符合标准,又支持Promise的一个HTTP客户端的库,因此用它来开始我们的示例非常容易。

const axios = require('axios').default;

const downloadUrl = async (url) => {
    const response = await axios.get(url);
    if (response.status !== 200) {
        console.log(`Status code is not 200 when downloading ${url}`);
        return;
    }
    return response.data;
};

在上面的例子里,我们实现了一个downloadUrl()函数,这个函数会下载通过参数url传入的网址。

2. 解析网页的HTML

从第一步拿到html的文本内容之后,我们可以用cheerio这个库来解析网页的内容。

const html = await downloadUrl(url);
const $ = cheerio.load(html);

3. 抽取并存储网页的内容

这一步根据自己功能的需要,可以选择性地从解析后的HTML里面抽取自己需要保存的内容。在我们的例子里,我们主要是抽取了页面的标记,社交媒体图片,及描述。

完整的代码如下:

const axios = require('axios').default;
const cheerio = require('cheerio');

const downloadUrl = async (url) => {
    const response = await axios.get(url);
    if (response.status !== 200) {
        console.log(`Status code is not 200 when downloading ${url}`);
        return;
    }
    return response.data;
};

const extractContent = ($) => {
    const pageTitle = $('title').text();
    const image = $(`meta[property='og:image']`).attr('content');
    const description = $(`meta[name='description']`).attr('content');
    return { pageTitle, image, description };
};

const crawlPage = async (url) => {
    try {
        const html = await downloadUrl(url);
        const $ = cheerio.load(html);
        const data = extractContent($);
        console.log(data);
    } catch (error) {
        console.log(error);
    }
};

crawlPage('https://www.lema.fun/');

运行代码,会发现console.log()打印出以下的内容:

{
  pageTitle: '免费学编程 | 乐码范',
  image: undefined,
  description: '乐码范为您提供编程方面的教程、题库等多方面的信息,致力于帮助程序员更易入门,更快提高编程水平。'
}

至此,我们实现了extractContent()函数来专门抽取网页中的内容,如果需要修改或扩展,都可以改这个函数。最后,我们用crawlPage()函数来把三个步骤连起来,工作就基本上完成了。

需要注意的是,网络通信代码会遇到各种异常的问题,比如请求超时,网络异常等错误,所以需要用try/catch来捕获和处理异常。这也是我们在crawlPage()里加上异常处理的原因。