爬取网站能给你带来成行的结构化网页数据,但原始行数据并不等于洞察。当你想跨数据提问时,哪些商品降价了、哪些品类的评论最多、各品牌的中位评分是多少,你需要 SQL。GoogleSQL 是 Google Cloud SQL 和 BigQuery 背后的 SQL 方言,它与 Crawlbase 的爬取配合得天衣无缝:一次采集数据,加载到托管表中,然后用纯 SQL 进行查询,而不是每次都编写一次性的解析脚本。

本指南是一个可运行的完整流程演练。你通过 Crawling API 获取结构化的产品数据,将其保存为 CSV,加载到 Google Cloud SQL 表中,然后对其编写 GoogleSQL 查询:过滤、聚合、排名,以及一些可在自有数据源上复用的查询模式。爬取示例使用 Amazon 公开搜索结果,但 SQL 部分适用于你采集的任何结构化数据集。

你将构建什么

一个以可查询 SQL 表结尾的小型数据流水线。运行示例拉取某个商品的 Amazon 搜索结果,但爬取之后的所有步骤都与数据源无关。你将生成:

  • 一个爬取记录的 CSV,每行代表一个商品,包含名称、价格、货币、评分和评论数。
  • 一个 Cloud SQL 表,一个承载导入行数据的带类型的 PostgreSQL 表。
  • 一组查询,用于过滤、聚合、排名和汇总数据的可复用 GoogleSQL 查询。
  • 一个可复用的循环,只需更换爬虫和表结构,即可将整个流水线指向任何其他爬取数据源。

用通俗语言解释 GoogleSQL

GoogleSQL 是 Google Cloud 各托管数据库服务所使用的 SQL 语言风格的统一名称。在 Cloud SQL 中,它是你针对 Google 托管的 MySQL、PostgreSQL 或 SQL Server 实例编写的标准 SQL,Google 负责运行硬件和大部分运维工作。在 BigQuery 中,它是用于处理超大型分析查询的方言。无论哪种情况,核心理念相同:你不需要管理自己的服务器,连接到托管引擎,编写查询,让 Google 处理后端。

本教程使用带有 PostgreSQL 的 Cloud SQL,因为这是从爬取数据 CSV 到可查询表格的最直接路径。你在这里编写的 GoogleSQL 是普通的 SQL:SELECTWHEREGROUP BYORDER BY 和窗口函数。其价值不在于奇特的语法,而在于将你爬取的网页数据存储在一个托管表中,让这些查询在毫秒内返回结果。

前提条件

在编写任何代码之前,需要先准备好几样东西,每项都不需要太长时间。

一个 Crawlbase 账户和 token。注册后,打开控制台,从账户文档页面复制你的普通请求 token。Crawlbase 提供最多 20,000 次免费请求,完成本指南绰绰有余。将 token 视为密码,不要将其纳入版本控制。

Python 3 和 requests 库。python --version 确认你的版本,然后安装爬虫所需的唯一依赖。jsoncsv 均随标准库一同提供。

一个 Google Cloud 账户。创建 Cloud SQL 实例需要启用计费功能的项目。Google 为新账户提供免费额度,因此你可以在不承诺付费计划的情况下跟随本指南操作。对 SQL 有基本了解会有帮助,但并非必需,这里的查询都会逐行解释。

配置项目

创建工作目录并安装爬虫使用的唯一库。

bash
python --version

mkdir googlesql-crawlbase && cd googlesql-crawlbase

pip install requests

这就是全部的本地配置。爬取步骤在 Python 中运行,之后的所有操作都在 Google Cloud SQL 内完成,你直接在控制台或任何你偏好的 SQL 客户端中编写 GoogleSQL。

第一步:将结构化数据爬取到 CSV

第一项工作是采集值得查询的数据。下面的脚本使用 amazon-serp 爬虫调用 Crawlbase Crawling API,该爬虫会返回 Amazon 搜索结果页面的解析 JSON,然后将商品数据展平为 CSV。将其保存为 crawl_data.py,并将 token 占位符替换为你自己的。

python
import csv
import json
import requests

API_TOKEN = "YOUR_CRAWLBASE_TOKEN"
API_ENDPOINT = "https://api.crawlbase.com/"

def crawl_data(search_url):
    params = {
        "token": API_TOKEN,
        "url": search_url,
        "scraper": "amazon-serp",
    }
    response = requests.get(API_ENDPOINT, params=params)
    response.raise_for_status()
    return response.text

FIELDNAMES = ["name", "price", "currency", "rating", "reviews"]

def save_to_csv(payload, filename="data.csv"):
    products = payload.get("body", {}).get("products", [])
    if not products:
        print("No products found")
        return
    with open(filename, "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
        writer.writeheader()
        for p in products:
            writer.writerow({
                "name": p.get("name", ""),
                "price": p.get("rawPrice", ""),
                "currency": p.get("currency", ""),
                "rating": p.get("customerReview", ""),
                "reviews": p.get("customerReviewCount", ""),
            })
    print(f"Saved {len(products)} products to {filename}")

if __name__ == "__main__":
    raw = crawl_data("https://www.amazon.com/s?k=wireless+headphones")
    save_to_csv(json.loads(raw), "data.csv")

python crawl_data.py 运行它。Crawling API 替你完成解析,因此你接收到的是一个干净的 products 数组,只需挑选你关心的字段,而无需编写选择器。脚本保留了五个字段:nameprice(取自数值型的 rawPrice 以便作为数字导入)、currencyratingreviews。结果是一个可以加载到 Cloud SQL 的 data.csv

Crawlbase Crawling API

上面的 amazon-serp 爬虫返回解析后的 JSON 而非原始 HTML,因此你完全跳过了编写和维护 CSS 选择器的工作。Scraper API 渲染页面、轮换住宅 IP、在服务端处理 CAPTCHA,并返回结构化字段,这正是 SQL 表所需的干净输入。在免费套餐上指向公开搜索页面,一次调用就能得到可供查询的数据。

第二步:创建 Cloud SQL 实例和数据库

在能够查询数据之前,需要给它找个存放的地方。在 Google Cloud 控制台中,配置一个托管的 PostgreSQL 实例和其中的一个数据库。

  • 打开 Google Cloud Console,创建或选择一个已启用计费的项目。
  • 在 APIs and Services 页面启用 Cloud SQL Admin API。
  • 进入 Cloud SQL Instances 页面,点击创建实例,然后选择 PostgreSQL
  • 设置实例 ID、区域和默认用户密码,然后创建实例。
  • 打开新实例,进入数据库选项卡,创建一个名为 analytics_example_db 的数据库。

Google 会替你配置和管理数据库引擎。实例运行起来、数据库创建好之后,你可以打开 Cloud SQL Studio(内置查询编辑器)并直接对其运行 GoogleSQL。

第三步:定义表结构

打开 Cloud SQL Studio,登录到 analytics_example_db,新建一个查询选项卡,创建一个与 CSV 列匹配的表。类型在这里至关重要:pricereviews 声明为数值类型,这样你之后才能对它们求和、取平均和比较,而文本字段保持为 TEXTVARCHAR

sql
CREATE TABLE "public"."amazon_products" (
  "name" TEXT,
  "price" DECIMAL(10, 2),
  "currency" VARCHAR(10),
  "rating" DECIMAL(3, 2),
  "reviews" INTEGER
);

这会创建一个包含五个带类型列的空 amazon_products 表。数值类型是整个练习的核心:存储为 DECIMAL 的价格可以被求平均和排名,而存储为文本的价格只能被展示。在这里把 schema 定义正确,才能让第五步的查询成为可能。

第四步:将 CSV 导入表中

表准备好后,加载爬取的行数据。Cloud SQL 从 Cloud Storage 存储桶中导入 CSV 文件。

  • 进入 Cloud SQL Instances 页面,打开你的实例。
  • 选择导入,将文件格式选为 CSV
  • data.csv 上传到 Cloud Storage 存储桶,并将其选为源文件。
  • analytics_example_db 设为目标数据库,amazon_products 设为目标表。
  • 点击导入
标题行

脚本会在 CSV 中写入标题行。导入时,告知 Cloud SQL 跳过第一行,以免将列名作为数据行加载。如果你的客户端没有这个选项,在上传前从文件中删除标题行。

导入完成后,行数据即可查询。从这里开始的一切都是 GoogleSQL。

第五步:使用 GoogleSQL 查询数据

这里是结构化数据发挥价值的地方。下面的每个查询都可以在 Cloud SQL Studio 或任何连接到实例的 PostgreSQL 客户端中运行。从基础开始,逐步深入。

读取全部数据。最简单的查询确认导入成功,并展示数据的形态。

sql
SELECT * FROM amazon_products LIMIT 10;

过滤并排序。在价格上限以内找出评论数量达标的商品,按价格从低到高排列。这种问题在电子表格中很繁琐,在 SQL 中则轻而易举。

sql
SELECT name, price, rating, reviews
FROM amazon_products
WHERE price < 100
  AND reviews > 500
ORDER BY price ASC;

聚合。用一行汇总整个结果集:商品数量、平均价格和价格区间。

sql
SELECT
  COUNT(*) AS total_products,
  ROUND(AVG(price), 2) AS avg_price,
  MIN(price) AS cheapest,
  MAX(price) AS most_expensive
FROM amazon_products;

分组与排名。当你的数据有分类列时,GROUP BY 能将平面表转化为横向比较。这里按货币分组,但同样的结构适用于品牌、类别或任何你爬取的列。

sql
SELECT
  currency,
  COUNT(*) AS listings,
  ROUND(AVG(rating), 2) AS avg_rating
FROM amazon_products
GROUP BY currency
ORDER BY listings DESC;

窗口函数。按评论数对商品排名,同时保留每一行,使你能在保留所有商品的同时看到每个商品在集合中的排名。RANK() 是标准 GoogleSQL,在 Cloud SQL 和 BigQuery 中都以同样的方式工作。

sql
SELECT
  name,
  reviews,
  RANK() OVER (ORDER BY reviews DESC) AS popularity_rank
FROM amazon_products
ORDER BY popularity_rank
LIMIT 10;

输出结果示例

排名查询会为每个商品返回一行,包含其在排名中的位置,评论最多的商品排在最前面,同时每个商品保留自己的独立行。

csv
name,reviews,popularity_rank
Wireless Over-Ear Headphones,12840,1
Noise Cancelling Earbuds,9325,2
Bluetooth Sport Headphones,7710,3
Studio Monitor Headphones,4188,4
Budget Wireless Earbuds,3902,5

聚合查询则折叠为单行汇总,包含整张表的商品数量、平均价格和价格区间。由于数据带有类型并存储在托管引擎中,这些查询会立即返回结果,即使表从几行增长到数十万行也同样快速。

将其适配到你自己的数据源

SQL 部分没有任何内容是 Amazon 专用的。要在不同的数据源上运行同一个流水线,只需更改三件事,其余不变。

  • 替换爬虫。将 Scraper API 指向另一个受支持的目标,或通过 Crawling API 获取原始 HTML 并自行解析。输出仍然是一个包含一致列的平面 CSV。
  • 匹配表结构。编辑 CREATE TABLE 语句,使列名和类型与新字段一致。任何你要聚合或比较的内容都保持为数值类型。
  • 复用查询。上面的过滤、聚合、分组和排名模式可以直接应用于任何表,只需更改列名即可适配新数据集。

对于较大规模的任务,使用异步 Crawler采集数据,它将请求排队并通过 webhook 交付结果,然后按计划将数据批量导入 Cloud SQL。如果你想深入了解加载和分析环节,在 SQL 中存储和分析爬取数据涵盖了 schema 设计和索引,构建可扩展的网页数据流水线介绍了如何周期性地运行这套流程。

负责任地爬取

SQL 部分你可以自由运行,但为其提供数据的爬取应当遵守几条规则。只采集公开数据,即任何访客无需登录即可看到的商品名称、价格、评分和评论数,并远离任何需要登录才能访问的内容。遵守每个数据源的服务条款及其 robots.txt,并将请求频率保持在合理水平,避免给网站造成压力。当数据源发布了官方 API 时,大批量或商业使用应优先考虑使用官方 API。如果你的数据集涉及个人数据,请按相关隐私规定(如 GDPR 或 CCPA)处理:对数据进行聚合,不要对个人进行画像,并只保留你需要的内容。

回顾

核心要点

  • GoogleSQL 就是托管引擎上的普通 SQL。它是 Cloud SQL 和 BigQuery 使用的方言,因此你已知的 SELECTGROUP BY 和窗口查询全都适用,由 Google 负责运行后端。
  • 先爬取到干净的 CSV。Crawling API 返回解析后的 JSON,你按名称挑选字段并写出平面 CSV,无需维护选择器。
  • 类型决定查询是否可用。CREATE TABLE 步骤中将 pricereviews 声明为数值类型,才能让你之后对它们求平均、比较和排名。
  • 查询模式可复用。过滤、聚合、分组和排名查询可以应用于任何表,只需更改列名即可适配新数据集。
  • 通过替换三件事进行适配。更换爬虫、匹配表结构、复用查询,将整个流水线指向新数据源。

常见问题

Cloud SQL 中的 GoogleSQL 与 BigQuery 中的有什么区别?

GoogleSQL 是共享的 SQL 方言,但底层引擎不同。Cloud SQL 运行 MySQL、PostgreSQL 或 SQL Server 的托管实例,适合事务性的中等规模数据集,如爬取的产品表。BigQuery 是专为超大型分析查询构建的无服务器数仓。本指南中的查询语法(包括 RANK() 窗口函数)在两者中都能工作。从这个规模的项目用 Cloud SQL 开始,只有当数据超过单个实例的承载能力时再迁移到 BigQuery。

使用 Google Cloud SQL 需要付费吗?

创建 Cloud SQL 实例需要在你的 Google Cloud 项目上启用计费,但新账户会获得免费额度,因此你可以在不自掏腰包的情况下完成本演练。完成后停止或删除实例以避免持续计费。Crawlbase 部分提供最多 20,000 次免费请求,对本教程的爬取步骤来说绰绰有余。

我可以将这种方法用于 Amazon 以外的数据源吗?

可以。爬取之后的流水线与数据源无关。将 Scraper API 指向另一个受支持的目标,或通过 Crawling API 获取并解析页面,然后生成列一致的 CSV。更新 CREATE TABLE schema 以匹配新字段,相同的导入和查询步骤即可原封不动地应用。

如果我的数据格式之后发生变化怎么办?

如果数据源新增了字段,或者你决定采集更多信息,不必从头开始。使用 ALTER TABLE 语句为现有表添加列,然后导入新行。现有数据完整保留,任何不涉及新列的查询也将继续正常工作。

为什么先爬取到 CSV 而不是直接插入行数据?

CSV 是最简单的交换格式,Cloud SQL 原生支持导入,这让爬取和加载保持解耦。你可以检查文件、重新导入或将其加载到其他系统,无需重新运行爬取。对于大批量或持续性的流水线,你会改为以编程方式插入行数据,但对于周期性的批处理,CSV 再导入的路径是最少移动部件的方案。

这些查询在标准 SQL 客户端中有效吗?

有效。Cloud SQL 实例启动后,你可以连接任何兼容 PostgreSQL 的客户端,无论是内置的 Cloud SQL Studio、psql 还是桌面工具,并运行相同的 GoogleSQL 查询。本指南中的查询使用标准 SQL 特性,因此可以跨 PostgreSQL 客户端移植,而非绑定于某个特定编辑器。

开始构建

大规模爬取任何站点,无需与基础设施对抗。

Crawlbase 负责处理代理、指纹和 CAPTCHA,让你的团队专注于交付数据流水线,而非维护爬取管道。1,000 次请求免费,无需信用卡。

自助开通 · 无需销售通话 · 提供企业级爬取量