使用JavaScript开始网页抓取
网络爬虫是编程世界中最有趣的事情之一。
什么是网络爬虫?
它为什么存在?
让我们找到答案。
什么是网络爬虫?
网络爬虫是从网站中提取数据的自动化任务。
网络爬虫有许多应用。提取产品价格并与不同的e-Commerce platforms进行比较。从网络上获取每日行情。构建自己的搜索引擎,如Google、Yahoo等等,等等。
你可以用网络爬虫做更多你想做的事情。一旦你知道如何从网站中提取数据,你就可以对数据进行任何想要的操作。
从网站中提取数据的程序被称为网络爬虫。你将学习如何使用JavaScript编写网络爬虫。
网络爬虫主要分为两个部分。
- 使用请求库和无头浏览器获取数据。
- 解析数据,从中提取我们想要的确切信息。
话不多说,让我们开始吧。
项目设置
假设你已经安装了Node,如果没有,请查看NodeJS installation guide。
我们将使用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用于解析和提取原始数据中必要的信息。
对于JavaScript的网络爬虫,node-fetch
和cheerio
这两个包已经足够好了。我们不会看到包提供的每个方法。我们将看到网络爬虫的流程以及其中最有用的方法。
通过实践来学习网络爬虫。所以,让我们开始工作。
爬取板球世界杯列表
在这一部分,我们将进行实际的网络爬虫。
我们要提取什么?
通过本部分的标题,我想你很容易猜到。是的,你所想的一切都是正确的。让我们提取所有板球世界杯的获胜者和亚军。
- 在项目中创建一个名为
extract_cricket_world_cups_list.js
的文件。 - 我们将使用链接Wikipedia Cricket World Cup页面来获取所需的信息。
- 首先,使用
node-fetch
包获取原始数据。 - 下面的代码获取了上述维基百科页面的原始数据。
const fetch = require("node-fetch");
// function to get the raw data
const getRawData = (URL) => {
return fetch(URL)
.then((response) => response.text())
.then((data) => {
return data;
});
};
// URL for data
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";
// start of the program
const getCricketWorldCupsList = async () => {
const cricketWorldCupRawData = await getRawData(URL);
console.log(cricketWorldCupRawData);
};
// invoking the main function
getCricketWorldCupsList();
我们从URL获取了原始数据。现在,是时候从原始数据中提取我们需要的信息了。让我们使用cheerio包来提取数据。
使用cheerio提取涉及HTML标签的数据非常简单。在进入实际数据之前,让我们看一些使用cheerio进行示例数据解析的示例数据。
使用cheerio.load
方法解析HTML数据。
const parsedSampleData = cheerio.load(
`I'm title
`
);
我们已经解析了上面的HTML代码。如何从中提取p
标签内容?与JavaScript DOM操作中的选择器相同。
console.log(parsedSampleData("#title").text());
您可以根据需要选择标签。您可以从cheerio official website查看不同的方法。
现在,是时候提取世界杯列表了。要提取信息,我们需要知道信息所在页面上的HTML标签。转到cricket world cup Wikipedia page并检查页面以获取HTML标签信息。
这是完整的代码。
const fetch = require("node-fetch");
const cheerio = require("cheerio");
// function to get the raw data
const getRawData = (URL) => {
return fetch(URL)
.then((response) => response.text())
.then((data) => {
return data;
});
};
// URL for data
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";
// start of the program
const getCricketWorldCupsList = async () => {
const cricketWorldCupRawData = await getRawData(URL);
// parsing the data
const parsedCricketWorldCupData = cheerio.load(cricketWorldCupRawData);
// extracting the table data
const worldCupsDataTable = parsedCricketWorldCupData("table.wikitable")[0]
.children[1].children;
console.log("Year --- Winner --- Runner");
worldCupsDataTable.forEach((row) => {
// extracting `td` tags
if (row.name === "tr") {
let year = null,
winner = null,
runner = null;
const columns = row.children.filter((column) => column.name === "td");
// extracting year
const yearColumn = columns[0];
if (yearColumn) {
year = yearColumn.children[0];
if (year) {
year = year.children[0].data;
}
}
// extracting winner
const winnerColumn = columns[3];
if (winnerColumn) {
winner = winnerColumn.children[1];
if (winner) {
winner = winner.children[0].data;
}
}
// extracting runner
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}`);
}
}
});
};
// invoking the main function
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();
结论
你已经学会了如何抓取网页。现在轮到你 practice coding。
我还建议查看流行的 web scraping frameworks 来探索和 cloud-based web-scraping solutions。
开心编程 🙂