探索网页抓取的奥秘
网页抓取是编程世界中最引人入胜的领域之一。它究竟是什么?它为何如此重要?让我们深入探索,揭开其神秘面纱。
网页抓取的定义
网页抓取,又称网络数据提取,是一种自动化技术,用于从网站上收集数据。它就像一个数字侦探,高效地从网页中检索信息。
网页抓取的应用范围极其广泛:从比较不同电商平台上的产品价格,到获取每日更新的股市行情,甚至构建像谷歌、雅虎这样的搜索引擎,其可能性几乎是无限的。
一旦掌握了从网站提取数据的技巧,您就可以根据自己的需求对这些数据进行各种处理和分析。执行数据提取任务的程序被称为网络爬虫或抓取工具。本文将指导您使用 JavaScript 创建自己的网络爬虫。
网页抓取主要分为两个核心步骤:
- 首先,利用请求库和无头浏览器获取目标网页的原始数据。
- 然后,解析这些数据,从中提取出您所需的精确信息。
现在,让我们开始实际操作!
项目准备
假设您已经安装了 Node.js。如果没有,请先查阅相关的Node.js安装指南。
我们将使用 node-fetch
和 cheerio
这两个JavaScript库来实现网页抓取。我们需要使用 npm 来设置项目,以便使用这些第三方库。
以下是设置步骤的简要概述:
- 创建名为
web_scraping
的目录,并进入该目录。 - 运行
npm init
命令以初始化项目。 - 根据提示填写相关信息。
- 然后,使用命令
npm install node-fetch cheerio
安装所需的库。
让我们了解一下已安装的软件包:
node-fetch
node-fetch
库将 window.fetch
功能引入 Node.js 环境,使我们能够发送 HTTP 请求并获取网页的原始数据。
cheerio
cheerio
库则用于解析原始数据,并从中提取出我们需要的信息。
node-fetch
和 cheerio
这两个库足以满足我们使用 JavaScript 进行网页抓取的需求。我们不会深入探讨每个方法,而是重点关注网页抓取的流程以及最常用的方法。
通过实践操作,您将更好地掌握网页抓取。那么,让我们开始吧!
实战演练:抓取板球世界杯冠军名单
在本部分,我们将进行实际的网络数据抓取。
我们的目标是什么?
顾名思义,我们将抓取历届板球世界杯的冠军和亚军名单。
- 首先,在您的项目中创建一个名为
extract_cricket_world_cups_list.js
的文件。 - 我们将从
维基百科的板球世界杯页面
获取相关信息。 - 首先,使用
node-fetch
库获取页面的原始数据。 - 以下代码展示了如何获取维基百科页面的原始数据。
const fetch = require("node-fetch");
// 获取原始数据的函数
const getRawData = (URL) => {
return fetch(URL)
.then((response) => response.text())
.then((data) => {
return data;
});
};
// 数据来源的 URL
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";
// 程序入口
const getCricketWorldCupsList = async () => {
const cricketWorldCupRawData = await getRawData(URL);
console.log(cricketWorldCupRawData);
};
// 调用主函数
getCricketWorldCupsList();
现在,我们已经成功获取了原始数据。接下来,我们需要从中提取我们需要的信息,这时候就需要使用 cheerio
库。
利用 cheerio
处理 HTML 数据非常简单。在实际操作之前,我们先来看一些使用 cheerio
解析数据的例子:
- 使用
cheerio.load
方法解析 HTML 数据。
const parsedSampleData = cheerio.load(
`<div id="container"><p id="title">I'm title</p></div>`
);
- 我们已经解析了上述 HTML 代码,现在如何从中提取
p
标签的内容呢?这与 JavaScript DOM 操作中的选择器类似。
console.log(parsedSampleData("#title").text());
您可以根据需要选择标签。 更多信息,请参考 cheerio官方文档.
- 现在,让我们开始提取世界杯名单吧。我们需要知道目标信息位于页面中的哪个 HTML 标签。请访问
板球世界杯维基百科页面
并检查相关 HTML 标记。
以下是完整的代码:
const fetch = require("node-fetch");
const cheerio = require("cheerio");
// 获取原始数据的函数
const getRawData = (URL) => {
return fetch(URL)
.then((response) => response.text())
.then((data) => {
return data;
});
};
// 数据来源的 URL
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";
// 程序入口
const getCricketWorldCupsList = async () => {
const cricketWorldCupRawData = await getRawData(URL);
// 解析数据
const parsedCricketWorldCupData = cheerio.load(cricketWorldCupRawData);
// 提取表格数据
const worldCupsDataTable = parsedCricketWorldCupData("table.wikitable")[0]
.children[1].children;
console.log("Year --- Winner --- Runner");
worldCupsDataTable.forEach((row) => {
// 提取 `td` 标签
if (row.name === "tr") {
let year = null,
winner = null,
runner = null;
const columns = row.children.filter((column) => column.name === "td");
// 提取年份
const yearColumn = columns[0];
if (yearColumn) {
year = yearColumn.children[0];
if (year) {
year = year.children[0].data;
}
}
// 提取冠军
const winnerColumn = columns[3];
if (winnerColumn) {
winner = winnerColumn.children[1];
if (winner) {
winner = winner.children[0].data;
}
}
// 提取亚军
const runnerColumn = columns[5];
if (runnerColumn) {
runner = runnerColumn.children[1];
if (runner) {
runner = runner.children[0].data;
}
}
if (year && winner && runner) {
console.log(`${year} --- ${winner} --- ${runner}`);
}
}
});
};
// 调用主函数
getCricketWorldCupsList();
以下是抓取的数据:
Year --- Winner --- Runner
1975 --- West Indies --- Australia
1979 --- West Indies --- England
1983 --- India --- West Indies
1987 --- Australia --- England
1992 --- Pakistan --- England
1996 --- Sri Lanka --- Australia
1999 --- Australia --- Pakistan
2003 --- Australia --- India
2007 --- Australia --- Sri Lanka
2011 --- India --- Sri Lanka
2015 --- Australia --- New Zealand
2019 --- England --- New Zealand
是不是很酷? 😎
通用抓取模板
在每一个网页抓取项目中,从 URL 获取原始数据都是常见的步骤。唯一变化的是根据需要提取数据的部分。您可以尝试将以下代码作为模板:
const fetch = require("node-fetch");
const cheerio = require("cheerio");
const fs = require("fs");
// 获取原始数据的函数
const getRawData = (URL) => {
return fetch(URL)
.then((response) => response.text())
.then((data) => {
return data;
});
};
// 数据来源的 URL
const URL = "https://example.com/";
// 程序入口
const scrapeData = async () => {
const rawData = await getRawData(URL);
// 解析数据
const parsedData = cheerio.load(rawData);
console.log(parsedData);
// 在这里编写提取数据的代码
// ...
// ...
};
// 调用主函数
scrapeData();
总结
您已经学习了如何抓取网页,现在是时候动手实践了!
我还建议您探索一些流行的网页抓取框架,了解基于云端的网络抓取解决方案。
祝您编程愉快!🙂
喜欢这篇文章吗?请分享给更多人吧!