使用 JavaScript 和 Node.Js 进行网络抓取

罗伯特-斯菲奇(Robert Sfichi),2023 年 1 月 16 日

实话实说吧。从现在开始,互联网的数据量只会越来越大。对此,我们真的无能为力。这就是网络抓取器的作用所在。

在下面的文章中,我们将向你展示如何使用 JavaScript 作为主要编程语言来创建自己的 Web Scraper。

了解使用 JavaScript 进行网络抓取

网络搜刮工具是一种软件,可以帮助你自动完成从第三方网站收集有用数据的繁琐过程。通常,这一过程包括向特定网页发出请求、读取 HTML 代码并分解代码以收集数据。

为什么要搜索数据?

假设您想创建一个价格比较平台。您需要从几家网上商店获得几种商品的价格。网络搜刮工具可以帮助您在几分钟内完成这项工作。

也许您正试图为自己的公司获得一些新线索,甚至是获得最优惠的机票或酒店价格。当我们在网上搜索这篇文章时,偶然发现了 Brisk Voyage。

Brisk Voyage 是一款网络应用程序,可帮助用户在最后一分钟找到便宜的周末旅行。他们利用某种网络搜刮技术,不断检查航班和酒店价格。当网络搜索器发现价格低廉的异常旅行时,用户就会收到一封包含预订说明的电子邮件。

网络清除器有什么用?

开发人员使用网络刮擦器来获取各种数据,但使用最多的情况如下:

  • 市场分析
  • 价格比较
  • 潜在客户生成
  • 学术研究
  • 收集机器学习的训练和测试数据集

使用 JavaScript 和 Node.Js 进行网络抓取有哪些挑战?

你知道那些让你承认自己不是机器人的小方框吗?不过,它们也不是总能把机器人拒之门外。

但大多数情况下,他们会这样做,当搜索引擎发现你未经许可试图搜刮他们的网站时,就会限制你的访问。

网络刮擦程序面临的另一个障碍是网站结构的变化。网站结构的一个微小变化就会让我们浪费大量时间。网络搜刮工具需要经常更新才能适应并完成工作。

网络搜刮器面临的另一个挑战叫做地理阻断。根据你的物理位置,如果请求来自不可信的地区,网站可以完全禁止你访问。

为了应对这些挑战,帮助您专注于开发产品,我们创建了WebScrapingAPI。这是一个易于使用的企业级扩展 API,可帮助您收集和管理 HTML 数据。我们追求速度,我们使用全球旋转代理网络,已经有 10,000 多家客户在使用我们的服务。如果您觉得没有时间从头开始构建 Web scraper,您可以使用免费层试用 WebScrapingAPI。

应用程序接口:网络搜索的简便方法

大多数网络应用程序都提供一个应用程序接口,允许用户以预先确定的、有组织的方式访问其数据。用户向一个特定的端点发出请求,应用程序就会回应用户特别要求的所有数据。通常情况下,数据已经格式化为 JSON 对象。

使用应用程序编程接口时,通常不必担心前面提到的障碍。尽管如此,应用程序接口也会收到更新。在这种情况下,用户必须时刻关注他所使用的应用程序接口,并相应地更新代码,以免丢失其功能。

此外,应用程序接口的文档也非常重要。如果应用程序接口的功能没有清晰的文档说明,用户就会发现自己浪费了很多时间。

了解网络

要很好地理解互联网,需要很多知识。让我们简要介绍一下所有术语,以便您更好地理解网络搜索。

HTTP 或超文本传输协议是网络数据交换的基础。顾名思义,HTTP 是一种客户端-服务器协议。HTTP 客户端(如网络浏览器)会打开一个与 HTTP 服务器的连接,并发送一条信息,如"嘿!怎么了?能把这些图片传给我吗?"。服务器通常会以 HTML 代码的形式作出回应,然后关闭连接。

假设您需要访问谷歌。如果您在网络浏览器中输入地址并点击回车键,HTTP 客户端(浏览器)将向服务器发送以下信息:

GET / HTTP/1.1
Host: google.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/web\p,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch, br
Connection: keep-aliveUser-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

信息的第一行包含请求方法(GET)、请求的路径(在我们的例子中只是"/",因为我们只访问了 www.google.com)、HTTP 协议的版本以及多个标头,如 Connection 或 User-Agent。

让我们来谈谈流程中最重要的标题字段:

  • 主机:在网络浏览器中输入地址并按回车键后访问的服务器域名。
  • User-Agent:这里我们可以看到发出请求的客户端的详细信息。从__(Macintosh; Intel Mac OS X 10_11_6)__部分可以看出,我使用的是 MacBook,网络浏览器是__(Chrome/56.0.2924.87)__。
  • 接受:通过使用该标头,客户端限制服务器只向其发送某种类型的响应,如 application/JSON 或 text/plain。
  • Referrer: 该标头字段包含发出请求的页面地址。网站使用该标头根据用户的来源更改内容。

服务器响应可以是这样的

HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu) Content-Type: text/html; charset=utf-8
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>The content of the document</body>
</html>

如您所见,第一行是 HTTP 响应代码:**200OK。这意味着扫描操作成功。

现在,如果我们使用网络浏览器发送请求,它就会解析 HTML 代码,获取 CSS、JavaScript 文件、图像等所有其他资产,并渲染网页的最终版本。在下面的步骤中,我们将尝试自动完成这一过程。

了解使用 Node.Js 进行网络抓取

创建 JavaScript 的初衷是帮助用户为网站添加动态内容。起初,它不能直接与计算机或其数据交互。当您访问网站时,浏览器会读取 JavaScript,并将其转换为计算机可以处理的几行代码。

介绍 Node.Js,它不仅能帮助 Javascript 在客户端运行,还能在服务器端运行。Node.Js 可定义为用于服务器端编程的免费开源 JavaScript。它可以帮助用户快速构建和运行网络应用程序。

const http = require('http');
const port = 8000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello world!');
});
server.listen(port, () => {
  console.log(`Server running on port 8000.`);
});

如果没有安装 Node.Js,请查看下一步的说明。否则,创建一个新的 index.js 文件,并在终端中键入 node index.js 运行它,打开浏览器并导航到 localhost:8000。你应该会看到以下字符串:"世界你好!"。

所需工具

Chrome 浏览器 - 请按照此处的安装指南进行操作。

  • VSCode - 您可以从本页面下载,并按照说明将其安装到您的设备上。
  • Node.Js - 在开始使用 Axios、Cheerio 或 Puppeteer 之前,我们需要安装 Node.Js 和 Node 包管理器。安装 Node.Js 和 NPM 的最简单方法是从 Node.Js 官方源中获取安装程序并运行。

安装完成后,您可以在终端窗口中运行node -vnpm -v 来验证 Node.Js 是否已安装。版本应高于 v14.15.5。如果在此过程中遇到问题,还有另一种安装 Node.Js 的方法。

现在,让我们创建一个新的 NPM 项目。为项目创建一个新文件夹,然后运行npm init -y。现在,让我们开始安装依赖项。

  • Axios - 用于从 Node.Js 发起 HTTP 请求的 JavaScript 库。在新创建的文件夹中运行npm install axios
  • Cheerio - an open-source library that helps us to extract useful information by parsing markup and providing an API for manipulating the resulting data. To use Cheerio you can select tags of an HTML document by making use of selectors. A selector looks like this:  $("div"). This specific selector helps us pick all <div> elements on a page.

要安装 Cheerio,请在项目文件夹中运行npm install cheerio

  • Puppeteer - 一个 Node.Js 库,用于通过提供高级 API 来控制 Chrome 或 Chromium。

要使用 Puppeteer,必须使用类似的命令进行安装:npm install puppeteer。请注意,安装此软件包时,它还会安装最新版本的 Chromium,保证与你的 Puppeteer 版本兼容。

数据源检查

首先,你需要使用 Chrome 浏览器或其他网络浏览器访问你要抓取的网站。要成功抓取所需数据,必须了解网站的结构。

有针对性的网站检查

一旦你成功访问了网站,就可以像普通用户一样使用它。如果你访问的是 /r/dundermifflin 子红人区,你可以点击主页面上的帖子,查看评论和高票,甚至根据特定时间段内的票数对帖子进行排序。

博客图片

如您所见,该网站包含一个帖子列表,每个帖子都有一些向上投票和一些评论。

只需查看 URL,就能了解网站的许多数据。在本例中,https://www.old.reddit.com/r/DunderMifflin 代表基本 URL,即进入 "The Office "Reddit 社区的路径。当你开始按照得票数对帖子进行排序时,你可以看到基本 URL 正在变为 https://www.old.reddit.com/r/DunderMifflin/top/?t=year。

查询参数是 URL 的扩展,用于根据传递的数据帮助定义特定内容或操作。在我们的例子中,"?t=year "代表我们希望看到最多人投票的帖子的时间范围。

只要你还在这个特定的 subreddit 上,基本 URL 就会保持不变。唯一会改变的是查询参数。我们可以把它们看作应用于数据库的过滤器,以检索我们想要的数据。只需更改 URL,你就可以切换时间范围,只查看上个月或上一周的最高票数帖子。

使用开发人员工具进行检查

在接下来的步骤中,您将进一步了解页面上的信息是如何组织的。您需要这样做,才能更好地了解我们究竟能从信息源中搜刮到什么。

开发者工具可以帮助你交互式地探索网站的文档对象模型(DOM)。我们将在 Chrome 浏览器中使用开发者工具,但你也可以使用任何你熟悉的网络浏览器。在 Chrome 浏览器中,右键单击页面任意位置并选择 "检查 "选项,即可打开该工具。

博客图片

在屏幕上出现的新菜单中,请选择 "元素 "选项卡。这将显示网站的交互式 HTML 结构。

博客图片

您可以通过编辑网站结构、扩展和折叠元素,甚至删除它们来与网站互动。请注意,只有您自己才能看到这些更改。

正则表达式及其作用

正则表达式(也称为 RegEx)可帮助您创建规则,以便查找和管理不同的字符串。如果你需要解析大量信息,掌握正则表达式可以为你节省大量时间。

When you first start using regex, it seems to be a little too complicated, but the truth is they're pretty easy to use. Let's take the following example: \d. By using this expression, you can easily grab any digit from 0 to 9. Of course, there are a lot more complex ones, like: ^(\(\d{3}\)|^\d{3}[.-]?)?\d{3}[.-]?\d{4}$. This matches a phone number, with or without parentheses around the area code, or with or without dots to separate the numbers.

正如你所看到的,正则表达式非常容易使用,如果你花足够多的时间掌握它,就会发现它非常强大。

了解 Cheerio.js

在成功安装了前面介绍的所有依赖项并使用开发工具检查了 DOM 之后,就可以开始实际的刮擦工作了。

需要注意的一点是,如果您要抓取的页面是 SPA(单页面应用程序),Cheerio 可能不是最佳解决方案。原因是 Cheerio 无法真正像网页浏览器那样思考。这就是为什么在下面的步骤中,我们要使用 Puppeteer。但在此之前,让我们来看看 Cheerio 有多强大。

为了测试 Cheerio 的功能,让我们试着收集之前介绍过的子论坛上的所有帖子标题:/r/dundermifflin。

让我们创建一个名为 index.js 的新文件,然后键入或直接复制以下几行:

const axios = require("axios");
const cheerio = require("cheerio");
const fetchTitles = async () => {
try {
const response = await axios.get('https://old.reddit.com/r/DunderMifflin/');
        const html = response.data;
const $ = cheerio.load(html);
const titles = [];
$('div > p.title > a').each((_idx, el) => {
const title = $(el).text()
titles.push(title)
});
return titles;
} catch (error) {
throw error;
}};
fetchTitles().then((titles) => console.log(titles));

为了更好地理解上面编写的代码,我们将解释异步函数fetchTitles() 的作用:

首先,我们使用 Axios 库向旧 Reddit 网站发出 GET 请求。请求的结果会在第 10 行被 Cheerio 加载。通过使用开发者工具,我们发现包含所需信息的元素是几个锚标签。为了确保我们只选择包含帖子标题的锚标签,我们还将使用以下选择器选择它们的父标签:$('div > p.title > a')

为了单独获取每篇文章的标题,而不仅仅是一大堆毫无意义的字母,我们必须使用 each()函数循环查看每篇文章。最后,在每个项目上调用text()将返回该特定文章的标题。

要运行它,只需在终端中输入node index.js,然后点击回车。你会看到一个包含所有帖子标题的数组。

NodeJS 的 DOM

由于 Node.Js 无法直接获取网页的 DOM,因此我们可以使用 JSDOM。根据其文档JSDOM 是许多网络标准(尤其是 WHATWG DOM 和 HTML 标准)的纯 JavaScript 实现,可与 Node.Js 配合使用。

换句话说,使用 JSDOM,我们可以创建一个 DOM,并使用与操作网络浏览器 DOM 相同的方法对其进行操作。

JSDOM 使您可以与需要抓取的网站进行交互。如果您熟悉网络浏览器 DOM 的操作,那么理解 JSDOM 功能将不费吹灰之力。

为了更好地了解 JSDOM 的工作原理,让我们安装它,创建一个新的 index.js 文件,然后键入或复制以下代码:

const { JSDOM } = require('jsdom')
const { document } = new JSDOM(
  '<h1 class="string">Dunder mifflin, the people person\'s paper people!</h2>'
).window
const string = document.querySelector('.string')
console.log(string.innerHTML)
string.textContent = 'Hello world'
console.log(string.innerHTML)

正如您所看到的,JSDOM 创建了一个新的文档对象模型,我们可以使用与操作浏览器 DOM 相同的方法对其进行操作。在第 3 行,我们在 DOM 中创建了一个新的 h1 元素。我们使用归属于标题的类在第 7 行选择该元素,并在第 10 行更改其内容。您可以通过打印出更改前后的 DOM 元素来查看差异。

要运行它,请打开一个新终端,输入 node index.js,然后按回车键。

当然,您可以使用 JSDOM 执行更复杂的操作,如打开网页并与之交互、填写表格和点击按钮。

就其价值而言,JSDOM 是一个不错的选择,但 Puppeteer 在过去几年中获得了很大的发展。

了解 Puppeteer:如何解读 JavaScript 页面

使用 Puppeteer,你可以完成在网页浏览器中手动完成的大部分工作,如填写表格、生成网页截图或自动进行用户界面测试。

让我们通过 /r/dundermifflin Reddit 社区的截图来更好地了解它的功能。如果你已经安装了依赖项,请继续下一步。如果没有,请在项目文件夹中运行npm i puppeteer。现在,创建一个新的index.js文件并键入或复制以下代码:

const puppeteer = require('puppeteer')
async function takeScreenshot() {
try {
const URL = 'https://www.old.reddit.com/r/dundermifflin/'
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto(URL)
await page.pdf({ path: 'page.pdf' })
await page.screenshot({ path: 'screenshot.png' })
await browser.close()
} catch (error) {
console.error(error)
}
}
takeScreenshot()

我们创建了takeScreenshot()异步函数。

如你所见,首先使用puppeteer.launch()命令启动浏览器实例。然后,我们创建一个新页面,并使用 URL 作为参数调用goto() 函数,将之前创建的页面转到该特定 URL。pdf()screenshot( )方法可帮助我们创建一个新的 PDF 文件和一张包含网页可视化组件的图片。

最后,浏览器实例在第 13 行关闭。要运行它,请在终端输入node index.js,然后按回车键。你会在项目文件夹中看到两个新文件,分别名为page.pdfscreenshot.png

替代木偶匠

如果觉得使用 Puppeteer 不方便可以使用 NightwatchJS、NightmareJS 或 CasperJS 等替代软件。

以 "噩梦 "为例。由于它使用的是 Electrons 而不是 Chromium,因此捆绑包的大小要小一些。运行npm I nightmare命令即可安装Nightmare。我们将尝试用 Nightmare 代替 Puppeteer 复制之前成功截取页面截图的过程。

让我们创建一个新的index.js文件,然后键入或复制以下代码:

const Nightmare = require('nightmare')
const nightmare = new Nightmare()
return nightmare.goto('https://www.old.reddit.com/r/dundermifflin')
.screenshot('./nightmare-screenshot.png')
.end()
.then(() => {
console.log('Done!')
})
.catch((err) => {
console.error(err)
})

如第 2 行所示,我们创建了一个新的 Nightmare 实例,将浏览器指向要截图的网页,在第 5 行截图并保存,然后在第 6 行结束 Nightmare 会话。

要运行它,请在终端中输入 node index.js,然后点击回车。你应该会在项目文件夹中看到两个新文件nightmare-screenshot.png

主要收获

如果你还在这里,恭喜你!你已经掌握了创建自己的网络刮刀所需的全部信息。让我们用一分钟来总结一下你目前所学到的知识:

  • 网络搜刮工具是一种软件,可以帮助你自动完成从第三方网站收集有用数据的繁琐过程。
  • 人们使用网络刮擦器来获取各种数据:市场分析、价格比较或线索生成。
  • HTTP 客户端(如网络浏览器)可帮助你向服务器发出请求并接受响应。
  • 创建 JavaScript 的初衷是帮助用户为网站添加动态内容。Node.Js是一种帮助 Javascript 不仅在客户端运行,而且在服务器端运行的工具。
  • Cheerio是一个开源库,它通过解析 HTML 并提供用于操作生成数据的应用程序接口,帮助我们提取有用信息。
  • Puppeteer是一个 Node.Js 库,通过提供高级 API 来控制 Chrome 或 Chromium。有了它,你可以在网络浏览器中手动完成大多数事情,如填写表格、生成页面截图或自动操作。
  • 只需查看 URL,就能了解网站的大量数据。
  • 开发人员工具 可帮助您以交互方式探索网站的文档对象模型。
  • 正则表达式可帮助您创建规则,从而查找和管理不同的字符串。
  • JSDOM是一种创建新文档对象模型的工具,可以使用与操作浏览器 DOM 相同的方法对其进行操作。

我们希望这些说明都很清楚,你也能为你的下一个项目获得所有需要的信息。如果你还是觉得不想自己动手,可以试试 WebScrapingAPI。

谢谢你坚持到最后!

新闻和更新

订阅我们的时事通讯,了解最新的网络搜索指南和新闻。

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

相关文章

缩图
使用案例在金融领域利用网络抓取另类数据:投资者综合指南

探索网络搜索在金融领域的变革力量。从产品数据到情感分析,本指南深入介绍了可用于投资决策的各类网络数据。

米赫内亚-奥克塔维安-马诺拉什
作者头像
米赫内亚-奥克塔维安-马诺拉什
13 分钟阅读
缩图
指南网络抓取 API 快速入门指南

开始使用 WebScrapingAPI - 终极网络搜索解决方案!收集实时数据,绕过反僵尸系统,享受专业支持。

米赫内亚-奥克塔维安-马诺拉什
作者头像
米赫内亚-奥克塔维安-马诺拉什
9 分钟阅读
缩图
指南了解如何使用最好的 Selenium 浏览器绕过 Cloudflare 检测

了解在使用 Selenium 进行网络刮擦时,绕过 Cloudflare 检测系统的最佳浏览器是什么。

米赫内亚-奥克塔维安-马诺拉什
作者头像
米赫内亚-奥克塔维安-马诺拉什
9 分钟阅读