使用JavaScript开始网页抓取

网络爬虫是编程世界中最有趣的事情之一。

什么是网络爬虫?

它为什么存在?

让我们找到答案。

什么是网络爬虫?

网络爬虫是从网站中提取数据的自动化任务。

网络爬虫有许多应用。提取产品价格并与不同的e-Commerce platforms进行比较。从网络上获取每日行情。构建自己的搜索引擎,如Google、Yahoo等等,等等。

你可以用网络爬虫做更多你想做的事情。一旦你知道如何从网站中提取数据,你就可以对数据进行任何想要的操作。

从网站中提取数据的程序被称为网络爬虫。你将学习如何使用JavaScript编写网络爬虫。

网络爬虫主要分为两个部分。

  • 使用请求库和无头浏览器获取数据。
  • 解析数据,从中提取我们想要的确切信息。

话不多说,让我们开始吧。

项目设置

假设你已经安装了Node,如果没有,请查看NodeJS installation guide

我们将使用node-fetchcheerio包来进行JavaScript的网络爬虫。让我们通过npm来设置项目,以便使用第三方包。

让我们快速看一下完成设置的步骤。

  • 创建一个名为web_scraping的目录,并进入该目录。
  • 运行命令npm init来初始化项目。
  • 根据您的喜好回答所有问题。
  • 现在,使用以下命令安装包
npm install node-fetch cheerio

让我们来看一下已安装包的一瞥。

node-fetch

node-fetchwindow.fetch带到了Node.js环境中。它有助于进行HTTP请求并获取原始数据。

cheerio

cheerio用于解析和提取原始数据中必要的信息。

对于JavaScript的网络爬虫,node-fetchcheerio这两个包已经足够好了。我们不会看到包提供的每个方法。我们将看到网络爬虫的流程以及其中最有用的方法。

通过实践来学习网络爬虫。所以,让我们开始工作。

爬取板球世界杯列表

在这一部分,我们将进行实际的网络爬虫。

我们要提取什么?

通过本部分的标题,我想你很容易猜到。是的,你所想的一切都是正确的。让我们提取所有板球世界杯的获胜者和亚军。

  • 在项目中创建一个名为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

开心编程 🙂

类似文章