网络抓取是以编程方式从网站提取数据的过程。虽然许多流行的网页抓取工具都利用 Python 和 Node.js 等服务器端技术,但也可以仅使用客户端 JavaScript 来抓取网页。在这篇文章中,我们将探讨如何利用您现有的 Vanilla JS 知识开始抓取,而无需学习任何新框架。
为什么使用 Vanilla JavaScript 进行抓取?
以下是使用 Vanilla JS 进行抓取的一些主要好处:
进入门槛低 – 如果您已经了解 JavaScript,则无需学习新语言即可快速开始网络抓取。 Vanilla JS 抓取的学习曲线比较温和。
前端聚焦 – 对于主要从事前端项目的开发人员来说,Vanilla JS 抓取允许您重用现有的技能。
轻量化设计,方便挪动 – 客户端抓取避免了设置和维护服务器来运行抓取程序的开销。
便携性 – Vanilla JS 抓取工具可以直接在浏览器中运行,从而可以轻松共享和部署您的抓取工具。
Stealth – 与服务器端抓取相比,客户端抓取可能更难被网站检测和阻止。
因此,如果您想要一种简单的方法来开始使用 JavaScript 从网络中提取数据,Vanilla JS 抓取是一个不错的选择!接下来让我们看看它的幕后工作原理。
客户端网页抓取的工作原理
使用 Vanilla JS 进行网页抓取的基本步骤是:
使用
fetch()
下载页面的 HTML。使用 DOM API 解析 HTML 以提取所需的数据。
转换并存储提取的数据。
对其他页面重复步骤 1-3。
关键是一切都直接发生在浏览器而不是服务器上。这 fetch()
方法允许我们发出下载 HTML 的请求,DOM API 提供了类似的方法 document.querySelector()
分析 HTML 并提取我们想要的数据。
我们可以随时通过运行 JavaScript 抓取代码来启动抓取过程。抓取逻辑将在客户端运行,并与网页的其余部分隔离以确保安全。
现在让我们看一下运行中的 Vanilla JS 抓取工具的简单示例!
一个简单的例子
假设我们想从电子商务网站上抓取一些产品数据。下面是我们如何使用简单的 JavaScript 来做到这一点:
// Fetch the HTML of the product page
fetch(‘https://example.com/products/1‘)
.then(response => response.text())
.then(html => {
// Parse the HTML with the DOM
const doc = new DOMParser().parseFromString(html, ‘text/html‘);
// Extract the product title
const title = doc.querySelector(‘h1.product-title‘).textContent;
// Extract the product description
const description = doc.querySelector(‘div.product-description‘).textContent;
// Extract the product price
const price = doc.querySelector(‘span.price‘).textContent;
// Store the data somewhere, e.g. log to console
const product = {
title,
description,
price
};
console.log(product);
});
这就是它的全部内容!只需几行 Vanilla JS,我们就可以从产品页面中抓取关键数据。
这种方法的优点在于它直接利用前端开发人员已经熟悉的标准 Web 平台 API。不需要特殊的抓取库!
让我们进一步深入了解关键步骤。
获取页面
第一步是下载我们想要抓取的页面的 HTML。从 JavaScript 发出 HTTP 请求的现代方法是使用 获取API.
我们可以使用 fetch()
下载任何公共 URL 的 HTML:
fetch(‘https://example.com‘)
.then(response => response.text())
.then(html => {
// now we have the HTML of the page in the html variable
});
fetch()
方法返回一个承诺,该承诺解析为包含响应数据的 Response 对象。呼唤 .text()
响应返回一个以文本形式解析内容的承诺。
我们提供回调 .then()
只要 HTML 准备好就运行我们的抓取逻辑。
解析 HTML
一旦我们有了 HTML,下一步就是解析它以提取我们想要的数据。在浏览器中以编程方式分析 HTML 文档的最佳 API 是 DOM API.
我们可以使用以下方法将 HTML 字符串解析为文档 DOMParser
类:
const parser = new DOMParser();
const doc = parser.parseFromString(html, ‘text/html‘);
本篇 doc
变量现在包含一个表示解析后的 HTML 的文档对象。
我们可以使用 DOM 方法,例如 querySelector()
从文档中分析和提取数据:
// Select elements
const headers = doc.querySelectorAll(‘h2‘);
// Get text content
const headerText = headers[0].textContent;
// Get attribute values
const linkUrl = doc.querySelector(‘a.link‘).getAttribute(‘href‘);
DOM API 非常广泛,允许您以编程方式模拟人类如何在浏览器中分析网页。
我们 本指南 有关使用 DOM API 解析和遍历 HTML 文档的更多信息。
存储抓取的数据
一旦我们从页面中提取了我们想要的数据,下一步就是将其存储在某个地方。简单的选项包括:
- 记录到控制台——有利于调试
- 保存到 JavaScript 变量或数据结构
- 储存于 本地存储 – 跨会话持续存在
- 通过 AJAX 发送到服务器 – 例如将抓取的数据保存在数据库中
例如:
// Log to console
console.log(extractedData);
// Store in memory
let scrapedData = [];
scrapedData.push(extractedData);
// Save to localStorage
localStorage.setItem(‘data‘, JSON.stringify(extractedData));
// Send to server
fetch(‘/api/data‘, {
method: ‘POST‘,
body: JSON.stringify(extractedData)
});
这些是在客户端持久保存抓取数据的一些常见模式。
抓取多个页面
为了抓取多个页面,我们将抓取逻辑包装在一个可以迭代调用的函数中:
async function scrapePage(url) {
// Fetch HTML
// Parse HTML
// Extract data
// Store data
}
const urls = [
‘https://example.com/page1‘,
‘https://example.com/page2‘,
// ...
];
// Sequentially scrape each page
for (const url of urls) {
await scrapePage(url);
}
// Or scrape multiple pages concurrently
await Promise.all(urls.map(scrapePage));
我们可以按顺序循环并抓取每个页面,或者使用 Promise.all()
同时抓取多个页面。
这使我们能够以编程方式抓取整个网站!
为扩大规模而采用无头技术
到目前为止的示例直接在浏览器中运行抓取逻辑。为了获得更多的规模和运行时控制,我们可以使用类似的工具在无头浏览器环境中运行 JavaScript 抓取工具 木偶戏.
Puppeteer 提供了一个 Node.js API,用于通过 DevTools 协议以编程方式控制 Chrome(或 Chromium)。这使我们能够在服务器上执行抓取脚本,同时利用最新的浏览器渲染引擎。
下面是一个 Puppeteer 脚本示例:
const puppeteer = require(‘puppeteer‘);
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(‘https://example.com‘);
// Extract data from page with page.$eval()
await browser.close();
})();
因此,通过 Puppeteer 管理浏览器环境,我们可以扩展客户端抓取工具并在云中的服务器上运行它们。
还有类似的服务 阿皮菲 和 剧作家云 提供针对运行大规模抓取作业而优化的托管环境。
常见问题
以下是使用 Vanilla JS 抓取页面时需要注意的一些常见挑战:
同源策略 – 无法访问不同域上页面的响应数据。代理或 Apify 等服务可以提供帮助。
异步执行 – JavaScript 执行是异步的,因此您需要正确排序抓取步骤。
动态页面内容 – 通过 JavaScript 加载的内容可能不会出现在初始页面加载中。可能需要等待类似的事件
DOMContentLoaded
.浏览器差异 – 脚本在不同浏览器中的执行方式可能不同。建议测试多个浏览器。
检测刮刀 – 网站可能会尝试使用浏览器指纹识别等方法来检测和阻止抓取工具。轮换代理/用户代理可以提供帮助。
机器人排除标准 – 抓取工具应遵守 robots.txt 等标准。像 RobotJS 这样的浏览器扩展可以提供帮助。
所以这些是需要注意的事情。总的来说,Vanilla JavaScript 提供了一种非常有用且易于访问的方式来开始抓取网络!
刮擦道德
值得注意的是,虽然网络抓取本身通常是合法的,但您对抓取的数据所做的操作可能不合法。
确保以符合道德和负责任的方式进行刮擦。避免造成网站负载过大,尊重 robots.txt 和任何 UI 限制,并且不要违反网站的服务条款。
仅收集可公开访问的数据,切勿共享来自抓取网站的私人数据。仅将抓取的数据用于个人或研究目的,不得用于商业利益。
遵守这些道德原则有助于确保网络抓取作为一种有用技术的长久存在。
结论
以下是我们介绍的有关使用客户端 JavaScript 进行网页抓取的一些要点:
网络抓取涉及以编程方式从网站中提取数据。
Vanilla JavaScript 提供了一种使用标准浏览器 API 开始抓取的可访问方法。
Fetch API 可以检索页面 HTML,DOM API 解析并提取数据。
存储、转换和迭代允许大规模抓取网站。
像 Puppeteer 这样的无头浏览器提供了更多的功能和控制。
网络抓取时遵循道德原则很重要。
因此,利用现有的 Vanilla JS 技能是开始从网页中提取有用数据的快速方法。一旦掌握了基本技术,天空就是极限!
快乐(道德)刮擦!