Skip to main content
Version: 3.6

获取一些真实的数据

嘿,伙计们,你知道吗,现在我们可以很酷的抓取网页<title>元素了,但这并不是非常的有用。最终我们能不能抓取一些真实数据,并将他们用可机器处理的格式进行保存?所以这正是本教程的原因!

来吧菜鸡!首先,你必须学会爬虫。只有这样你才能驾驭网络数据!

制作一个生产级爬虫

制作一个生产级的网络爬虫并不困难,但是在抓取数据时,你可能会遇到许多陷阱。因此,在这个真实项目中,你将学习如何抓取示例商店而不是Crawlee官网。它包含了各种分类下的产品列表,并且每个产品都有自己的详情页面。

该网站需要JavaScript渲染,这就使我们能够展示更多Crawlee的功能。我们还添加了一些有用的提示,为你解决在大规模进行爬取时,肯定会遇到的一些现实问题。

tip

如果你对爬虫理论不感兴趣,可以直接跳到下一节,直接开始编码。

制定计划

有时候爬取数据确实很直接,但大多数情况下,最好先做一些研究,尝试回答下面问题。

  • 网站的结构是怎样的?
  • 我能只用HTTP请求(用CheerioCrawler)来爬取它吗?
  • 我需要无头浏览器做些什么吗?
  • 是否有反爬保护措施?
  • 我需要解析HTML,还是可以通过其他方式获取数据,比如可以直接从网站的API获取吗?

为了达到本教程的学习目的,我们假设无法使用CheerioCrawler来爬取网站。实际上是可以的,但我想做的比入门指南更深入一些。现在我们先将事情简化,用PlaywrightCrawler来爬取,并且你会在这个过程中将学习关于无头浏览器的知识。

选择你需要的数据

首先要做的是确定你想要抓取哪些数据,以及在哪里找到它们。暂时让我们就从示例商店的集合页面中抓取所有分类下的所有产品,对于每个产品,我们想获取以下信息:

  • URL: 网址
  • Manufacturer: 制造商
  • SKU: 商品SKU
  • Title: 商品标题
  • Current price: 商品当前售价
  • Stock available: 可用库存

你会注意到一些信息可以直接在产品列上找到,但是对于像“SKU”这样的具体内容,我们还需要打开产品的详情页获取。

data to scrape

起始网址

这是你开始爬取数据的地方。为了方便,我们需要尽可能将靠近目标数据的页面作为开始页面。例如,我们已经知道我们想要提取的所有内容都可以在集合页面https://warehouse-theme-metal.myshopify.com/collections中找到,就没有必要把首页https://warehouse-theme-metal.myshopify.com/作为开始页面,然后再去爬取collections集合页面,这样操作就没有太多意义。

浏览页面

让我们仔细看一下集合页面https://warehouse-theme-metal.myshopify.com/collections。页面中有很多分类,进入每个分类都有一个产品列表页。在一些产品列表页底部,你还会注意到有一些进入下一页的链接,通常被称为分页

分类和排序

当你点击左边的分类时,它们会筛选加载该分类下产品。通过进一步的操作可以观察到,我们还可以选择按不同条件对商品进行排序(例如Best sellingPrice, low to high),但在本例中,我们将不涉及这些内容。

caution

需要注意的是,在一些网站上,比如amazon.com,添加筛选条件后的产品总数实际上要比分类下总产品的总数要少。在抓取有限制分页网站的课程中了解更多信息。

分页

示例商店的分页例子也非常简单。以“audio”这个集合为例,在切换分页链接时,你会看到URL更改为:

https://warehouse-theme-metal.myshopify.com/collections/audio?page=2

当你尝试点击第4页的链接时。你将看到分页链接被更新并显示更多的的页面。所以你如何才能相信这个分页会包含所有页面并且不会在某个时刻隐藏呢?

caution

这与上面的条件筛选问题类似,如果有分页的存在,并不能保证你可以简单地浏览到所有结果。所以始终要对分页进行反复观察测试。否则,你可能会错过一部分结果,甚至都不知道。

在撰写本文档时,“audio”集合显示了147个产品结果。 快速计算在一页上产品数量为24。6行乘以4个产品。 所以这意味着真实分页有7页。

如果你不相信这个结果,可以访问中间的某个页面,例如https://warehouse-theme-metal.myshopify.com/collections/audio?page=2 ,然后查看显示内容。

爬行策略

现在你知道从哪里开始以及如何找到所有的详细信息了,再让我们来看一下爬取过程。

  1. 访问包含所有分类的集合页面(开始页面)。
  2. 将所有分类的链接加入队列。
  3. 将分类下列表页的所有产品链接加入队列。
  4. 将分类下列表页的下一页链接加入队列。
  5. 依次打开队列中的下一个页面。
    • 当它是商品列表页时,转到至第2步。
    • 当它是产品链接页面时,抓取产品数据。
  6. 重复直到所有页面和所有产品都被处理完毕。

PlaywrightCrawler 会确保访问页面,如果你提供的请求是正确的,并且你已经知道如何将页面加入队列,这应该是相当容易的。尽管如此,我们还想给你展示一些更多的技巧。

合理性检查

让我们在编写抓取逻辑之前检查一切是否设置正确。你可能会意识到以前的分析中有些地方不太对,或者网站的行为可能并非完全符合你的预期。

下面的示例创建了一个新的爬虫,访问开始 URL 并打印该页面上所有类别的文本内容。当你运行代码时,你将看到个别分类卡片上 非常糟糕的格式 内容。

src/main.mjs
// Instead of CheerioCrawler let's use Playwright
// to be able to render JavaScript.
import { PlaywrightCrawler } from 'crawlee';

const crawler = new PlaywrightCrawler({
requestHandler: async ({ page }) => {
// Wait for the actor cards to render.
await page.waitForSelector('.collection-block-item');
// Execute a function in the browser which targets
// the actor card elements and allows their manipulation.
const categoryTexts = await page.$$eval('.collection-block-item', (els) => {
// Extract text content from the actor cards
return els.map((el) => el.textContent);
});
categoryTexts.forEach((text, i) => {
console.log(`CATEGORY_${i + 1}: ${text}\n`);
});
},
});

await crawler.run(['https://warehouse-theme-metal.myshopify.com/collections']);

如果你想知道如何获取.collection-block-item选择器,我们将在下一章中的DevTools中解释。

DevTools - 网页抓取工具箱

info

我们将在这里使用Chrome DevTools,因为它是最常见的浏览器,当然也可以随意使用其他任何浏览器,它们都非常相似。

让我们在Chrome中打开DevTools,方法是:当转到 https://warehouse-theme-metal.myshopify.com/collections 时,在页面的任何位置右键单击并选择检查,或者按下F12,或者是你系统偏好设置的其他快捷键。使用DevTools,你可以检查或操纵当前打开网页的任何方面。你可以在官方文档中了解更多关于DevTools的信息:official documentation

选择元素

在DevTools中,使用选择元素工具,然后尝试将鼠标悬停在页面上的任意一个分类卡片上。

select an element

你会发现可以在卡片内选择不同的元素。请选中整个卡片,而不仅仅是其中的一些内容,比如标题或描述。

selected element

在DevTools HTML检查器中选择一个元素将会突出显示它。仔细观察这些元素,你会发现不同的HTML元素上都附有一些class。这些被称为CSS class,我们可以在抓取数据时利用它们。

相反,通过在HTML检查器中悬停在元素上,你将看到它们在页面上突出显示。检查集合卡周围的页面结构。你会发现所有卡片数据都显示在一个带有class属性的<a>元素中,其中包括collection-block-item。现在应该清楚我们如何得到.collection-block-item选择器了。这只是一种找到所有带有collection-block-item标记的元素的方法。

始终要仔细检查,确保你在使用此class的时没有获取任何不需要的元素。为了做到这一点,请进入DevTools的控制台选项卡并运行:

document.querySelectorAll('.collection-block-item');

你会发现只有31个集合卡片元素将被返回,此外没有其他任何东西。

tip

CSS选择器和开发工具是一个相当大的话题。如果你想了解更多,请访问Apify学院中的面向初学者的网络抓取课程它是免费开源的 ❤️。

下一节

在下一课中,我们将爬取整个示例商店,包括所有的列表页面和所有的产品详情页。