Axios 分页:如何抓取多个页面
在本指南中,我将向您介绍如何使用 Axios(一种在 Node.js 中进行 HTTP 请求的流行工具)来刮擦分页网站。但是,仅靠 Axios 本身无法处理分页问题。我们需要编写一些额外的代码,以便从一个页面移动到下一个页面,直到收集到所有数据。
在学习过程中,我们还将介绍如何处理基于 JavaScript 的分页,以及如何避免刮擦时被拦截。让我们开始吧!
什么是分页?
分页是网站将大量数据分成多个页面的一种技术。网站不是一次性加载所有数据,而是每页显示数量有限的项目,用户可以使用按钮或链接浏览页面。
有三种常见的分页方式:
- 编号分页 - 页面按数字标注,如 1、2、3、4...
- "下一步 "和 "上一步 "按钮 - 用户点击 "下一步 "前进或点击 "上一步 "后退。
- 无限滚动 - 当用户向下滚动时,新数据会自动加载。
每种类型都需要不同的刮擦方法。让我们从最简单的开始:编号分页。
为网络抓取设置 Axios
要抓取分页数据,我们需要两个 npm 软件包:
安装 Axios 和 Cheerio
首先,创建一个新的 Node.js 项目并安装所需的软件包:
mkdir axios-pagination-scraper
CD axios-pagination-scraper
npm init -y
npm install axios cheerio
现在,我们可以开始编写刮板了。
使用编号分页搜索网站
步骤 1:单个页面的基本扫描器
我们将从一个使用编号分页的虚构电子商务网站上抓取产品详细信息(名称、价格和图片 URL)。
const axios = require('axios');
const cheerio = require(cheerio);
const url = 'https://www.scrapingcourse.com/ecommerce/?page=1';
async function scrapePage(pageUrl) {
try {
const response = await axios.get(pageUrl);
if (回应。status !== 200) {
console.error(`错误: ${response.status}`);
return [];
}
const $ = cheerio。load(回应。data);
const 产品 = [];
$('.product').each((指数、产品) => {
const name = $(产品)。find('.product-name').text().内饰();
const 价格 = $(产品)。find('.product-price').text().内饰();
const imageUrl = $(产品)。find(产品图片).attr(src);
产品push({ 名称: name、 价格价格、 图片: imageUrl });
});
return 产品;
} catch error) {
console.error(`错误: ${error.message}`);
return [];
}
}
(async () => {
const products = await scrapePage(url);
console.log(产品);
})();
该脚本只从第一页提取产品。现在,让我们对它进行修改,以便抓取多个页面。
步骤 2:抓取多个页面
我们需要循环浏览每个页面并提取数据,以抓取所有页面。我们假设网站有 12 个页面。
async function scrapeAllPages(基础 URL、总页数) {
let allProducts = [];
for (let i = 1i <= TotalPages; i++) {
const pageUrl = `${baseURL}?page=${i}`;
console.log(刮削: ${pageUrl}`);
const products = await scrapePage(pageUrl);
allProducts = [...allProducts, ... products];
}
return 所有产品;
}
(async () => {
const 所有产品 = await scrapeAllPages('https://www.scrapingcourse.com/ecommerce/', 12);
console.log(allProducts);
})();
该版本会扫描所有 12 个页面,并将数据合并到一个数组中。
使用 "下一页 "和 "上一页 "按钮搜索网站
有些网站不使用页码,而是提供 "下一页 "和 "上一页 "按钮。
为了解决这个问题,我们需要
- 提取 "下一页" URL.
- 递归访问下一页,直到没有 Next 按钮。
步骤 1:修改扫描器以检测下一页链接
async function scrapePages(url) {
let 产品 = [];
try {
const response = await axios.get(url);
if (回应。status !== 200) {
console.error(`错误: ${response.status}`);
return 产品;
}
const $ = cheerio。load(回应。data);
$('.product').each((指数、产品) => {
const name = $(产品)。find('.product-name').text().内饰();
const 价格 = $(产品)。find('.product-price').text().内饰();
const imageUrl = $(产品)。find(产品图片).attr(src);
产品push({ 名称: name、 价格价格、 图片: imageUrl });
});
const nextPage = $('.下一个).attr(href);
if (nextPage) {
console.log(扫描下一页: ${下一页}`);
const nextProducts = await scrapePages(nextPage);
产品 = [...products, ...nextProducts];
}
} catch error) {
console.error(`错误: ${error.message}`);
}
return 产品;
}
(async () => {
const 所有产品 = await scrapePages('https://www.scrapingcourse.com/ecommerce/');
console.log(allProducts);
})();
现在,刮板会自动跟随 "下一页 "按钮,直到没有剩余页面为止。
处理基于 JavaScript 的分页
使用 JavaScript 动态加载数据的网站无法仅使用 Axios 进行搜刮。您需要一个无头浏览器,如 Puppeteer 或 Playwright.
使用 Puppeteer 实现无限滚动
安装 Puppeteer:
npm install puppeteer
修改刮刀:
const puppeteer = require(product_titles:);
async function scrapeInfiniteScroll(url) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, { waitUntil: networkidle2 });
let 产品 = [];
while (true) {
const 新产品 = await page.evaluate(() => {
return Array.from(document.querySelectorAll('.product')).map(product => ({
名称产品。querySelector('.product-name').innerText,
价格产品。querySelector('.product-price').innerText,
图片产品。querySelector(产品图片).来源
}));
});
产品 = [...products, ...newProducts];
const 加载更多 = await page.$('.加载更多);
if (loadMore) {
await 装载更多click();
await page.等待超时(2000);
} else {
break;
}
}
await browser.close();
return 产品;
}
(async () => {
const 所有产品 = await scrapeInfiniteScroll('https://www.scrapingcourse.com/infinite-scroll');
console.log(allProducts);
})();
该刮板会滚动页面并点击 "加载更多 "按钮,直到没有内容出现为止。
避免反机器人检测
网站通常会使用验证码、IP 禁止和 JavaScript 挑战来阻止刮擦程序。为了避免这种情况
- 使用 旋转代理
- 随机化请求头和用户代理
- 增加请求之间的延迟
- 使用可靠的解决方案,如 Bright Data 或 Oxylabs可自动绕过反僵尸程序。简单代码示例
const axios = require('axios');
const url = 'https://www.scrapingcourse.com/antibot-challenge';
const apiKey = YOUR_Bright Data_API_KEY;
公理。get(`https://api.brightdata.com/v1/?url=${url}&apikey=${apiKey}&js_render=true`.)
.then(response => console.log(回应。data))
.catch(error => console.log(错误));
结论
扫描多个页面时,了解网站通常使用的反僵尸措施非常重要。虽然 Axios 和 Cheerio 等工具可以很好地处理基本的分页,但这些反僵尸系统仍会妨碍工作。因此,我推荐使用 Bright Data 或 Oxylabs。它是一个全面的网络搜刮解决方案,可以帮助你搜刮网站而不用担心被屏蔽。
使用 Bright Data 或 Oxylabs,您可以访问旋转代理、验证码解码和其他创新功能,从而使搜刮更轻松、更可靠。因此,如果您想让您的搜刮工作保持顺畅和不间断,Bright Data 和 Oxylabs 绝对值得考虑。它将为您节省时间,减少麻烦,让您可以专注于收集所需的数据!