我们使用联盟链接。它们让我们能够维持运营,而您无需承担任何费用。

使用 Node.js 进行 Web 抓取:初学者实用指南

您需要了解的有关使用 Node.js 和 JavaScript 进行网页抓取的所有内容都集中在一个地方。

使用 JavaScript NodeJS 进行 Web 抓取

JavaScript 是网页抓取中最流行的语言之一。Node.js 是一个 JavaScript 运行时,具有许多强大的库和框架,初学者和开发人员都可以使用。它已成为动态网页抓取的不可替代的工具。

在本分步指南中,您将了解 Node.js 近年来为何如此受欢迎、您应该为项目使用哪些工具以及如何在提取数据时获得更多成功请求。您还将找到有关处理静态和动态网页的进一步说明。提示:我们准备了真实示例。

什么是 Node.js Web 抓取?

Node.js 是一个运行时环境,允许您在服务器端运行 JavaScript。它的主要重点是构建 Web 应用程序,但 Node.js 在抓取网站方面也广受欢迎,因为现在很多 Web 都依赖于 JavaScript。 

使用 Node.js 进行网页抓取可以分为从 1) 静态网页和 2) 动态网页收集数据。两者的主要区别在于静态网页不需要 JavaScript 渲染来显示内容,而动态网页在加载信息之前会执行 JavaScript。

要使用 Node.js 抓取静态网站,您需要发出请求并使用 Axios 等 HTTP 客户端下载目标页面的 HTML 代码。下载数据后,您可以提取数据点并使用 Cheerio 等解析器对其进行结构化。

要抓取现代网站或单页应用程序,您首先需要渲染整个页面;传统脚本无法帮助您做到这一点。因此,您需要使用像 Puppeteer 这样的无头浏览器来处理无限滚动或延迟加载等元素。在这种情况下,Node.js 是少数几种使动态抓取变得轻而易举的语言之一。

为什么要选择 Node.js 进行网页抓取?

当涉及到网页抓取 JavaScript 呈现的网站(如社交媒体或新闻媒体)时,Node.js 可能是许多人的首选。以下是您应该选择 Web 抓取运行时而不是其他编程语言的主要原因: 

  • 处理动态网站。 Node.js 是抓取依赖 JavaScript 加载和呈现内容的网站的首选。 
  • 高度可扩展。 运行时使用非阻塞 I/O 模型,允许您同时处理多个连接和请求。它还可以处理大量数据而不会牺牲性能。这使得 Node.js 成为抓取多个页面的不错选择。 
  • 比较容易学。 Node.js 基于 JavaScript,因此如果您已经熟悉它,那么它就很容易理解。与其他可以处理动态网站的编程语言相比,Node.js 使用的代码行数更少。 
  • 很棒的图书馆和框架。 Node.js 有许多工具,您可以通过 npm(Node 包管理器)访问。例如,Axios 是一个用于处理 HTTP 请求的流行库,而 Puppeteer 和 Playwright 则控制无头浏览器并处理 JavaScript 渲染。这些库还包括用于欺骗浏览器指纹和处理反机器人系统的软件包。
  • 大型社区。 Node.js 拥有庞大的开发者和用户社区、丰富的文档和教程。您还可以在 StackOverflow 等论坛上找到有关特定问题的讨论。 

使用 JavaScript 进行网页抓取:动态网页

在处理依赖于 客户端 渲染和 JavaScript 执行来生成内容,传统脚本没有多大帮助。与所有内容都在源代码中的静态网页不同,动态网站从外部来源或 API 获取数据,然后使用 JavaScript 将它们整合在一起并显示给您。 那是一个 无头浏览器 库开始发挥作用。它提供了一种控制浏览器实例的方法,同时以编程方式模拟真实用户的行为。

木偶戏

Puppeteer是一款功能强大的无头浏览器,主要用于 Web 测试,但它也完全可以胜任网页抓取工作。该库可以控制 Chrome 和 Chromium 浏览器,并使用 Chromium 内置的 DevTools 协议,从而允许您直接控制浏览器。

Puppeteer 由 Google 于 2018 年开发。它可以自动执行浏览器任务,例如填写表单、移动鼠标​​、等待页面加载等操作。它有详尽的文档,并且相对容易使用。 

与 Selenium 等框架相比,Puppeteer 库速度快、资源占用低。它支持用于伪造浏览器指纹和集成代理的插件。要开始使用 Puppeteer,您需要运行以下命令进行安装:`npm install puppeteer`

然后,您需要创建一个新文件并开始设置抓取工具。具体操作如下:

				
					// Importing Puppeteer library
import puppeteer from 'puppeteer';

// URL to scrape
const url = 'https://example.com';


async function scrapeData() {
	// Launching Puppeteer
	const browser = await puppeteer.launch();
	// Opening a new page
	const page = await browser.newPage();

	// Navigating to a sample webpage
	await page.goto(url);

	// Extracting sample data using page.evaluate
	const data = await page.evaluate(() => {
	// Sample data extraction logic
	const title = document.title;
	const body = document.querySelector('body').innerText;
	// Returning an object containing extracted data
	return { title, body };
	});

	// Logging the extracted sample data
	console.log(data);

	// Closing the Puppeteer browser
	await browser.close();
}

// Call the scrapeData() function
await scrapeData();
				
			

要了解有关网页抓取 Puppeteer 的更多信息,请参阅我们的分步教程。您将了解抓取者为何选择 Puppeteer 进行项目抓取,并通过一个真实示例教您如何抓取动态元素并处理延迟渲染。

这是使用 Node.js 库 Puppeteer 进行网页抓取的分步指南。

剧作家

Playwright 是最新的跨浏览器库之一,主要用于浏览器自动化。它由微软于 2018 年开发,多年来广受欢迎。

该框架用途广泛 - 它可以模拟三大浏览器组:Chromium、Firefox 和 WebKit。该工具具有内置驱动程序,因此您不需要其他依赖项即可运行。 

无头浏览器库易于使用,并提供大量文档,因此即使是初学者在网页抓取时也不会遇到困难。Playwright 性能出色 - 您可以发送多个请求,因为它使用在抓取期间保持打开状态的 WebSocket 连接。 

要开始使用 Playwright,您需要运行以下命令进行安装:npm install playwright

下面是一个如何使用 Playwright 进行抓取的示例:

				
					// Import Playwright library
import playwright from 'playwright';

// URL to scrape
const url = 'https://example.com';

// Function to scrape data
async function scrapeData() {
    // Launch a new browser instance
    const browser = await playwright.chromium.launch();

    // Create a new browser context
    const context = await browser.newContext();

    // Create a new page
    const page = await context.newPage();

    // Navigate to the URL
    await page.goto(url);

    // Scrape data from a specific element
    const data = await page.textContent('body');

    // Output the scraped data
    console.log(data);
	
	// Close the browser
	await browser.close();
}

// Call the scrapeData() function
await scrapeData();
				
			

如果您想了解有关使用 Playwright 进行网页抓取的更多信息,我们准备了一个分步教程。您将找到一个真实示例,从中您可以学习抓取单个和多个页面、加载动态内容、抓取表格等技能。

通过我们的分步教程练习基于 JavaScript 的网站网页抓取。

木偶戏演员与剧作家:该使用哪一个?

Puppeteer 和 Playwright 是实现浏览器自动化的绝佳工具。它们都能够渲染 JavaScript 并模拟用户交互。但是,在选择其中一个之前,您应该考虑它们在功能和性能方面的一些差异。

Puppeteer只能控制基于 Chromium 内核的浏览器(例如 Chrome)。它主要用于网页抓取,但在处理大量并发任务时速度可能会稍慢。Puppeteer 是一款较老的工具,这意味着它已经非常成熟,您在使用过程中不太可能遇到任何问题。此外,它还拥有完善的文档和庞大的社区支持。

Playwright支持所有主流浏览器:Chromium、Firefox 和 WebKit(Safari),因此在同时处理多个浏览器时速度非常快。Playwright 还内置了移动端模拟功能,用于渲染网页。虽然它的历史不如 Puppeteer 悠久,但发展迅猛。

木偶戏演员与剧作家对比表
木偶戏演员与剧作家的比较

您可以阅读有关这两个无头浏览器有何不同的更深入的指南:

我们比较了两个 Node.js 无头浏览器库。

使用 JavaScript 进行网页抓取:静态网页

使用 JavaScript 抓取静态网页时,你可以从使用 服务器端渲染。与动态网页相比,静态网站更简单——您无需处理加载动态内容。在这种情况下,与启动浏览器实例相比,传统脚本是一种更快、更简单的数据收集方式。

使用 HTTP 客户端

无论您选择使用哪种语言进行抓取,您都需要自动化工具来检索网页,以便抓取它们。该规则也适用于 Node.js,因此您必须使用 HTTP 客户端以编程方式请求并返回 HTML 页面。Node.js 有多个可用的 HTTP 客户端,最受欢迎的是 Axios 和 Request。 

Axios使用 Promise——一种表示请求尚未完成但即将完成的占位符,无论其结果如何(成功或失败)。Promise 使异步操作变得简单,这意味着在操作等待期间,您的爬虫程序可以执行其他计划任务。

另一方面,Request使用回调函数来异步处理 HTTP 请求。你可以嵌套函数(将一个函数放在另一个函数内部)来创建任务链式逻辑,并保持代码的条理性。但是,嵌套会使代码难以阅读。

以下是 Axios 和 Request 的比较:

  爱可信 请求
使用方便 使用非常简单 使用简单,但功能不足
速度 速度很快,但由于基于承诺的性质,有时会变慢 由于设计更简单,通常速度更快
任务链 简单,无需嵌套 嵌套函数、链接任务会降低可读性
可读性 简便 简单,但嵌套函数会变得更加困难
维护 大型社区积极维护 不再维护

目前这两个HTTP客户端仍然有人在使用,但我强烈建议任何新项目都使用Axios 。它使用起来非常简单,而且仍在积极维护中,而Request已被弃用,不再更新。它未来可能会导致安全性和兼容性问题。

解析日期

如前所述,Axios 是一个检索网页的 HTTP 客户端。而 Cheerio 是一个 HTML 解析和操作库。Cheerio 和 Axios 库经常一起使用,因为您需要检索页面以及提取必要的数据。

Cheerio 是最常用的 Node.js 数据解析库 - 它从您下载的 HTML 代码中提取数据并将其转换为结构化格式。该工具在服务器端运行,不需要完整的浏览器环境。Cheerio 是一个具有 jQuery 功能的轻量级快速库。 

要开始使用 Cheerio 和 Axios,您需要通过运行以下命令来安装两个库:

  • npm 安装 axios
  • npm 安装 Cheerio

我们来看看使用 Axios 和 Cheerio 的示例代码:

				
					import axios from 'axios';
import cheerio from 'cheerio';

// URL of the webpage to scrape
const url = 'https://example.com';

// Using axios to fetch the HTML content
axios.get(url)
  .then(response => {
    // Loading HTML content into Cheerio
    const $ = cheerio.load(response.data);
    
    // Extracting data using Cheerio
    const data = {
      title: $('title').text(), // Extracting title
      heading: $('h1').text(), // Extracting heading
      paragraph: $('p').text() // Extracting paragraph
    };
    
    // Logging the extracted sample data
    console.log(data);
  })
  .catch(error => {
    console.log(error);
  });

				
			

要了解有关使用 Node.js 和 JavaScript 抓取静态页面的更多信息,请查看我们的 Axios 和 Cheerio 教程。您将学习如何:

  • 获取 HTML 数据,
  • 解析下载的数据, 
  • 处理分页和多个异步请求,
  • 清理数据。

这是使用 Node.js 库 Cheerio 和 Axios 的分步示例。

其他 Node.js Web 抓取库

Node.js 有许多出色的网页抓取库,选择取决于您的项目要求,包括您要抓取的网站的复杂性。但为您的网页抓取项目选择合适的工具可能很复杂。您需要考虑网站的复杂性、您要抓取的数据量、处理动态内容或 JavaScript 的需要以及其他方面。

了解 6 个最流行的 Node.js 网络抓取库并找到最合适的。

要查看这些库的并排比较情况,请查看以下教程以获取指导:

让我们看看哪个 Node.js 库更适合您的项目。

Node.js Web 抓取的技巧和窍门

制定网页抓取指南并练习你的技能

您可以从 eBay 等真实目标收集数据,或者在设计用于抓取的网站上练习您的技能。 

第一种方法适用于经验丰富的用户 - 您将在此过程中遇到更多网页抓取挑战,例如 CAPTCHA,但您可以获得大量有用的产品信息。对于网页抓取新手,请使用网页抓取沙盒;我们列出了练习网页抓取的最佳网站。

只要有可能,就寻找 API 端点。有些网站提供公开可用的 API。如果不是这种情况,您仍可能会发现一个“隐藏”的 API。Web 抓取 JavaScript 呈现的网站涉及加载 JavaScript 和解析 HTML 以提取数据。但是,如果您通过检查网络请求对 API 端点进行逆向工程,则可以获取结构化数据并使用更少的带宽。例如,GraphQL 是用于处理动态网站中大量数据的流行端点。

不要忘记尊重您正在抓取的网站。查看其 robots.txt 文件,了解哪些页面是抓取工具无法访问的。此外,尽量避免使用多个请求使服务器过载。

使用代理

如今的网络抓取与过去大不相同。恶意机器人活动等不良的网络抓取行为应承担很大一部分责任。网站开始实施反机器人系统(如 reCAPTCHA、DataDome、Cloudflare)和其他措施,以保护内容免受自动数据提取。 

这些保护机制也体现了合乎道德的网络爬虫实践。例如,您可能会遇到速率限制、验证码提示或 IP 地址封锁。这就是为什么您应该使用代理的原因。

代理服务器会隐藏您的真实位置,并通过路由您的流量为您提供不同的 IP 地址。如果您对您的项目非常重视,我们建议您轮换使用住宅代理服务器

这些 IP 地址来自 Wi-Fi 上的真实设备。住宅代理很难检测到,并且具有全球位置。 

如果网站对数据收集的限制不多,您可以选择更便宜的方案——轮换数据中心代理。这些代理由网络托管公司创建并存储在服务器上。它们比住宅代理速度快得多,但也很容易被检测到。

注意浏览器指纹

虽然 IP 地址会泄露您的真实位置,但当您发出 HTTP 请求时,它还会包含有关您的设备参数信息的标头。用户代理标头是网站所有者关心的主要字符串。HTTP 客户端(如 Axios)会发送自己的用户代理,因此您需要更改它,因为网站会识别您的抓取工具。

此外,不要使用相同的用户代理;您需要随机轮换字符串,因为网站会监控来自同一浏览器的请求。并且不要忘记检查您的用户代理字符串是否格式正确。

格式正确的用户代理的示例: 

				
					Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
				
			

要使用 Node.js 设置用户代理,您需要将其放入对象中:

				
					// Import the Axios library
import axios from 'axios';

// Define custom headers for the HTTP request
const headers = {
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36'
};
// Pass the custom headers object to the request
axios.get('https://www.example.com', { headers })
  .then(response => {
    // Handling successful response 
    console.log(response.data);
  })
  .catch(error => {
    // Handling errors 
    console.error('Error fetching data:', error);
  });

				
			
Adam Dubois 的图片
亚当·杜波依斯
代理极客和开发人员。