使用 Node.js 进行网页抓取的简介
很长一段时间以来,每当我想尝试创建网站进行练习时,我都会访问一个网站,打开控制台并尝试获取我需要的内容 - 所有这些都是为了避免使用我非常讨厌的 lorem ipsum。
几个月前,我听说了网页抓取,嘿,迟做总比不做好,对吧?它似乎能做到和我手动尝试的类似的事情。
今天我将解释如何使用 Node 进行网络抓取。
设置
我们将使用三个包来实现这一点。
- Axios是一个“基于承诺的浏览器和 node.js HTTP 客户端”,我们将使用它从任何选定的网站获取 html。
- Cheerio类似于 jQuery,但用于服务器。我们将使用它来从 Axios 结果中提取内容。
- fs是一个节点模块,我们将用它将获取的内容写入 JSON 文件。
让我们开始设置项目。首先创建一个文件夹,然后cd
在终端中打开它。
要初始化项目,只需运行npm init
并按照步骤操作即可(所有步骤均可直接按回车键)。初始设置完成后,您将创建一个package.json
文件。
现在我们需要安装上面列出的两个包
npm install --save axios cheerio
(请记住fs
它已经是节点的一部分,我们不需要为它安装任何东西)
您会看到上述软件包安装在node_modules
目录下,它们也在package.json
文件中列出。
从 dev.to 获取内容
您的 dev.to 个人资料位于https://dev.to/<username>
。我们的任务是获取我们撰写的帖子并将其存储在 JSON 文件中,如下所示:
在您的项目文件夹中创建一个 JavaScript 文件,devtoList.js
如果您愿意,可以调用它。
首先需要我们安装的软件包
let axios = require('axios');
let cheerio = require('cheerio');
let fs = require('fs');
现在让我们从dev.to
axios.get('https://dev.to/aurelkurtula')
.then((response) => {
if(response.status === 200) {
const html = response.data;
const $ = cheerio.load(html);
}
}, (error) => console.log(err) );
第一行我们从指定的 URL 获取内容。如前所述,axios
是基于 Promise 的,then
我们检查响应是否正确,并获取数据。
如果你在控制台日志中response.data
看到 URL 中的 HTML 标记,那么我们就可以加载这些 HTML 代码了cheerio
(jQuery 会在后台帮我们完成这项工作)。为了更清楚地说明这一点,我们将其替换response.data
为硬编码的 HTML
const html = '<h3 class="title">I have a bunch of questions on how to behave when contributing to open source</h3>'
const h3 = cheerio.load(html)
console.log(h3.text())
这将返回不带标签的字符串h3
。
选择内容
此时,您需要打开要抓取的网站的控制台,并找到所需的内容。如下所示:
从上面我们知道每篇文章都有一个类single-article
,标题是一个h3
标签,标签位于一个tags
类里面。
axios.get('https://dev.to/aurelkurtula')
.then((response) => {
if(response.status === 200) {
const html = response.data;
const $ = cheerio.load(html);
let devtoList = [];
$('.single-article').each(function(i, elem) {
devtoList[i] = {
title: $(this).find('h3').text().trim(),
url: $(this).children('.index-article-link').attr('href'),
tags: $(this).find('.tags').text().split('#')
.map(tag =>tag.trim())
.filter(function(n){ return n != "" })
}
});
}
}, (error) => console.log(err) );
上面的代码非常易读,尤其是参考上面的截图。我们循环遍历每个类为 的节点.single-article
。然后我们找到唯一的h3
,并从中获取文本以及trim()
多余的空格。然后 URL 也同样简单,我们从相关的锚标签中获取href
。
获取标签其实很简单。我们首先将它们全部获取为一个字符串(#tag1 #tag2
),然后将该字符串(无论#
出现在哪里)拆分成一个数组。最后,我们将数组中的每个值映射到trim()
空格处,最后过滤掉所有空值(主要是由于修剪造成的)。
let devtoList = []
在循环外声明一个空数组( )允许我们从内部填充它。
就这样吧。devtoList
数组对象包含我们从网站上抓取的数据。现在我们只想将这些数据存储到一个 JSON 文件中,以便可以在其他地方使用。
axios.get('https://dev.to/aurelkurtula')
.then((response) => {
if(response.status === 200) {
const html = response.data;
const $ = cheerio.load(html);
let devtoList = [];
$('.single-article').each(function(i, elem) {
devtoList[i] = {
title: $(this).find('h3').text().trim(),
url: $(this).children('.index-article-link').attr('href'),
tags: $(this).find('.tags').text().split('#')
.map(tag =>tag.trim())
.filter(function(n){ return n != "" })
}
});
const devtoListTrimmed = devtoList.filter(n => n != undefined )
fs.writeFile('devtoList.json',
JSON.stringify(devtoListTrimmed, null, 4),
(err)=> console.log('File successfully written!'))
}
}, (error) => console.log(err) );
原始devtoList
数组对象可能有空值,因此我们只需将它们修剪掉,然后使用该fs
模块将其写入文件(上面我将其命名为)devtoList.json
,其内容由数组对象转换为 JSON。
这就是全部了!
上面的代码可以在github找到。
除了使用上述代码抓取 dev.to 之外,我还从 goodreads 抓取书籍,从 IMDB 抓取电影,其代码位于存储库中。
文章来源:https://dev.to/aurelkurtula/introduction-to-web-scraping-with-nodejs-9h2