跳至内容
免费开始
返回博客

市场调研中的网页爬取:开发者指南

Sergiu Inizian最后更新于 1 min read
市场调研中的网页爬取:开发者指南

开始提取

免费试用 WebScrapingAPI

领取 1,000 个免费 API 积分。无需信用卡。

开始使用
简而言之:网络爬取可将公开的产品页面转化为对价格、品类和库存状况的可重复观察结果。有效的市场调研需要明确的样本、可比产品、时间戳和质量检查;仅凭爬取的产品列表无法揭示销售额、需求或市场份额。

用于市场调研的网络爬虫,是指通过自动化收集网站数据来回答关于市场或其参与者的特定问题。对于开发人员而言,最终交付物应是一套具有可追溯观察结果和明确边界的数据集,而不仅仅是一大堆网页。

以某零售商将其价格与竞争对手的公开报价进行比较为例。仪表盘可能显示另一家零售商本周的平均价格有所下降。这可能反映了真正的降价、新上架的低价产品、高价产品缺失,或是解析器开始读取分期付款价格。每种解释都会导致不同的商业决策。

可靠的研究会在呈现趋势之前,先区分这些可能性。您需要了解样本涵盖的内容、每条记录代表什么,以及哪些差异属于可比范围。产品页面是特定条件下广告报价的证据,而非已完成交易的证明。

本指南重点探讨竞争对手的产品与定价研究,因为该领域能清晰地揭示测量问题。您将明确研究问题、设计观察框架、在不丢失上下文信息的前提下对价格进行标准化处理,并在报告结果前验证数据采集的有效性。同样的研究规范也适用于服务目录、职位列表及其他公开的市场信号。

以可解答的问题为起点开展市场调研的网络爬取工作

“监控竞争对手”这一表述过于宽泛,无法转化为数据提取规范。应将其替换为如下问题:“针对该目的地,各零售商所宣传的同类产品送货价格存在哪些差异?”这句话在您选择爬虫库之前,就已明确了实体、指标以及重要条件。

在需求中区分“观察结果”与“解读”。您可以观察到显示的价格、列出的产品或库存状态信息。虽然可以利用这些观察结果来分析竞争对手的变动,但更强有力的结论需要额外证据。仅凭产品从页面上消失,还不足以断定其已售罄或停产。

研究问题

有用的观察字段

这些字段无法证明的内容

可比商品的差异何在?

产品标识、价格、货币、配送条件

每位客户的实际交易价格

列出了哪些类别?

产品ID、类别、卖家、观察时间

销量或市场份额

库存情况如何变化?

库存状态说明及成功观察状态

已售数量或仓库库存

促销活动如何变化?

公开促销文案、参与资格、有效期

促销效果或客户参与度

商品组合如何演变?

首次和最后观察日期、产品属性

确切的上市或停产日期

这并非仅仅是措辞上的谨慎。英国国家统计局曾指出网络爬取价格研究的一个关键局限:标价无法提供用于支出加权所需的购买数量。该局2017年关于网络爬取价格数据的研究仅是方法论背景,并非对当今零售市场的陈述。

请在问题旁注明预期决策。负责商品组合分析的团队所需的数据集,与衡量比价变化的分析师所需的数据集不同。若无人能解释额外字段如何支持决策,则应避免收集这些字段,因为它们虽然容易抓取,却无实际价值。

设计能揭示自身盲点的样本

您的数据源列表界定了您实际能够观察到的市场范围。即使对三个网站进行全面爬取,也仅是更广泛市场的一个样本。它排除了其他零售商、线下交易,以及隐藏在您采集范围之外条件下的优惠信息。仅增加同一数据源的页面数量无法弥补这些遗漏。

在收集数据前建立数据源登记表。记录所选零售商或平台、地理区域、品类、访问方式、审核负责人以及纳入理由。明确区分有意排除的数据源与因技术原因无法获取的数据源。否则,数据管道的中断可能会悄无声息地改变所研究的市场范围。

将覆盖率与数据提取成功率区分开来

尽可能基于明确的框架衡量覆盖率:经批准的零售商列表、已知的品类 URL 或参考产品面板。成功的响应率衡量的是检索情况,而非覆盖率。爬虫可能检索到了所有请求的 URL,却因导航链接变更而未能发现整个品类。

请分别追踪已发现的产品、请求的页面、成功的观测结果以及有效记录。保留每项数据缺失的原因。不可用产品、缺失价格、请求失败和标识符不匹配等情况不应全都归为空行。在解释最终样本的变化时,这些区分至关重要。

如果无法估算全面覆盖率,请说明已知信息。“从选定的公开类别页面观察到的商品信息”是一个可辩护的描述,而“整个市场”则不然。请记录发现规则,以便其他开发人员能够复现数据集的边界。

使用稳定的面板和数据发现流

一种实用的设计方案是:在运行独立的发现任务以收集新上架商品的同时,保留一个固定的商品面板用于比较。面板有助于随时间推移比较相似商品;而发现任务则能揭示面板原本可能遗漏的商品组合变化。应分别公布两者的计数结果,因为它们回答的是不同的问题。

应定期审查样本集,而非悄无声息地替换缺失的产品。即使单个价格采集正确,产品更替也会改变价格序列。ONS 在针对网络爬取服装数据的研究中探讨了这一问题。对工程实践的启示是:在记录观测值的同时,应保留产品入组、退组及匹配决策。

将报价存储为带时间戳的观测值

对产品、报价和观测值采用不同的概念。产品是指被销售的商品。报价则包含卖家及商业条件。观测值记录了数据采集器在特定时间、特定情境下所观察到的内容。

Schema.org 产品(Product)和 Schema.org 促销(Offer)为这种区分提供了有用的词汇,包括产品标识符以及价格、货币和可用性等促销属性。网站结构化数据可以作为便捷的提取来源,但不要假设它与可见内容一致,或能正确识别所选变体。在依赖这些数据之前,请先验证具有代表性的页面。

字段组

建议字段

为何重要

来源

来源 URL、观察时间、运行 ID、解析器版本

重现并审核观测结果

产品标识

源产品ID、提供的GTIN(如有)、品牌、型号、变体

同类匹配

商品信息

卖家、地区、货币、商品状况、购买资格

避免比较不兼容的商品

价格依据

标价、运费金额或状态、税费基准

说明价格包含哪些内容

采集结果

获取状态、提取状态、字段缺失原因

区分未知值与实际变更

在经批准的数据保留政策允许的情况下,在保留标准化值的同时保留原始字段文本。 “19.99起”、“每月19.99”和“19.99”在描述不同优惠时,标准化后可能显示为相同的数值。保留原始证据有助于调查此类错误,而无需假设页面在后续仍保持原样。

使用支持时区识别的观察时间戳,并定义报告日期的分配规则。在某个地区午夜前采集的价格,若在另一地区属于午夜后,可能会被归入不同的日汇总中。即使仪表盘显示的是本地日期,也应保留实际采集的瞬间时间。

将更正视为可追溯的变更。如果解析器将运费映射到了价格字段中,则更正后的数据集应记录受影响的运行和转换版本。默默覆盖历史观测数据会使解释上周发布的图表为何发生变化变得困难。

在比较价格前先匹配产品

仅凭标题的相似性不足以确定产品等同。在将两项报价视为替代选项之前,应比较型号、变体、包装数量、商品状态和卖家背景。翻新机、新机和多件装可能在可见文字上高度相似,但代表的是不同的购买选择。

如有可用,请使用可信的标识符。GS1 在其关于 GTIN 和条形码的说明中,将 GTIN 描述为产品身份键。请将标识符作为字符串保留(包括前导零),并检查网站是否将该标识符与相关变体关联起来。标识符的存在并不意味着无需验证提取的关联关系。

当标识符缺失时,请采用分阶段匹配流程。规范化明显的格式差异,按品牌和类别缩小候选范围,然后比较型号和变体属性。存储匹配状态,例如“已确认”、“暂定”或“已拒绝”。将不确定的匹配结果提交审核,而非默认将模糊的相似度评分视为事实等同。

规范单位和商业条件

单位定价可使包装规格具有可比性,但前提是必须先确认该单位具有相同含义。对于等效的包装商品,比较每公斤价格可能很有用。但如果浓度、质量或随附配件存在差异,这并不能使产品完全相同。请保留原始包装信息,以便分析师选择适当的比较方式。

请勿将多种货币合并为单一数值列并计算平均值。应保留原始货币单位;若需进行货币转换,请记录汇率来源、时间戳及转换规则。转换后的金额属于衍生指标,而非原始观测值。

运费、税费、会员费及最低购物金额要求均需同样明确地处理。未知运费不等于免运费。会员专享价格并非面向所有客户的公开价格。应比较相同的符合条件的情景,或将用户群体分开处理,以免仪表盘将性质不同的优惠误判为直接替代品并进行排名。

使用一个简单的 Python 函数验证可比总计

在聚合之前进行可比性检查。以下标准库示例接受已提取的字段,并仅当两项优惠共享相同的产品和商业基础时,才计算最终总金额。它会刻意拒绝未知运费,而不是将其视为零。

这是一个示例性的验证步骤,并非通用的商品匹配器或实时数据抓取工具。其输入假设您已确定商品标识、选定相关优惠,并规范化了数值文本。请根据您的数据源特定规则进行货币验证、税费处理和符合性判断。

from decimal import Decimal, InvalidOperation

def amount(value):
    if not isinstance(value, str):
        raise ValueError("Amounts must be normalized decimal strings")
    try:
        parsed = Decimal(value)
    except InvalidOperation as exc:
        raise ValueError("Invalid amount") from exc
    if not parsed.is_finite() or parsed < 0:
        raise ValueError("Amount must be finite and nonnegative")
    return parsed

def delivered_total(offer, expected_basis):
    for field, expected in expected_basis.items():
        if offer.get(field) != expected:
            raise ValueError(f"Incomparable field: {field}")
    if offer.get("shipping_status") != "known":
        raise ValueError("Shipping is unknown")
    return amount(offer.get("price")) + amount(offer.get("shipping"))

basis = {
    "matched_product_id": "widget-blue-small-single",
    "currency": "EUR",
    "condition": "new",
    "tax_basis": "included",
    "destination": "DE",
    "eligibility": "public",
}
offer = {
    **basis,
    "price": "24.90",
    "shipping": "3.50",
    "shipping_status": "known",
}
print(delivered_total(offer, basis))  # 28.40

Python 的 decimal 文档解释了小数运算,以及为何从字符串构建小数与从二进制浮点值构建小数有所不同。此处使用字符串输入是故意的。该函数还会拒绝非有限值,因为诸如 NaN 不应出现在定价报告中。

在将此步骤连接到生产数据之前,请扩展测试用例。应包含未知运费、货币不匹配、负数金额、不可用报价以及重复记录等情况。将遭拒绝的记录及其原因保存在审核流中。若默认直接丢弃这些记录,虽然会提高数据集的表面整洁度,但会掩盖覆盖率的损失。

对于提供这些字段的数据采集层,请从最简单的检索方法开始,该方法应能暴露所需内容。Python HTTP 客户端指南介绍了相关选择;eBay 价格情报教程提供了平台特定的示例,您可在审阅源需求后加以改编。

收集可重复的快照并检测管道变更

选择一个符合研究问题和允许的请求策略的采集计划。只有当新增的细节会改变分析结果时,频繁的观测才有意义。一份每日商品组合报告并不一定需要每分钟进行一次数据采集,特别是当这会增加成本并使质量检查变得复杂时。

请始终如一地记录采集上下文:地区、语言、目标页面、所选变体以及任何相关的公开报价条件。如果该上下文发生变化,请标记数据序列中的中断点。否则,位置变化可能会被误认为是竞争价格的变化。

构建一套经过审核的、涵盖常见页面和棘手情况的固定测试用例集。当选择器或依赖关系发生变化时,使用这些测试用例对解析器进行测试。随后通过实时检查确认页面结构和显示值是否仍符合您的假设。成功的HTTP响应绝不应是唯一的验收条件。

监控缺失字段率、记录数量的意外变化、ID 重复以及异常大的价格波动。这些检查应触发调查,而非自动删除异常值。真实的促销活动和数据提取错误在图表中可能表现相似。在确定哪种解释更合理之前,请对比保留的证据、最近的解析器变更以及相邻的观测结果。

将重试结果与原始尝试区分开来,并使用稳定的观察键,以确保交付重试不会产生第二个产品观察项。有关更广泛的实现讨论,请参阅《Scrapy 采集指南》中的爬取背景说明。

在运行任务前,请审查允许的访问权限、网站条款和数据采集范围。确保数据集聚焦于业务问题,并尽量减少不必要的个人数据。遵循有限请求政策,并将不确定的访问条件上报审核。托管检索服务仅改变了网络层的操作方,而非您研究项目有权收集的数据内容。

报告价格变动时切勿虚构市场份额

一份有用的报告应将其测量规则体现在输出结果中。在主图表旁显示数据源面板、观察窗口、有效记录数、未匹配产品以及缺失数据源。分析师不应需要检查数据处理日志才能发现某家零售商已从样本中消失。

进行价格比较时,应明确匹配的样本群体以及总和可比性的具体条件。若展示百分比变化,需说明是比较两个时段内的相同产品,还是不同周期的产品组合。即使图表外观相同,这些指标所回答的问题也截然不同。

将描述性摘要与正式的价格指数区分开来。观察到的价格中位数或匹配产品的价格变动对于内部研究可能很有用,但并不自动满足通胀指标的方法学要求。避免将简单平均值称为“市场通胀”,或将其作为消费者支出的代表性指标呈现。

同样,商品条目数量是观察到的商品组合指标,而非市场份额。拥有更多索引页面的零售商可能只是采用了不同的分页方式、拥有更多商品变体,或是存在重复的市场报价。收入份额需要超出本数据集范围的、合适的销售额和市场规模证据。报告的措辞应与数据实际揭示的内容保持一致。

每份报告结尾应提出数据引发的问题,而非缺乏依据的解释。促销商品列表份额的上升或许值得对相关营销活动进行调查,但这并不能证明竞争对手正面临财务压力。优质的网络爬虫市场调研既能使后续决策更为精准,又能保持证据与解读之间的界限。

关键要点

  • 定义一个可通过公开观察数据回答的研究问题,然后记录缺失的证据。
  • 在进行比较计算前,应保留产品标识、优惠条件、数据收集背景及时间戳。
  • 将样本覆盖范围与成功请求及有效的提取记录分开追踪。
  • 在对价格进行排名前,需验证匹配结果、货币、单位、税费及运费。
  • 准确标注商品组合和价格指标;抓取的商品列表并不能证明销售额或市场份额。

常见问题

是否可以将客户评论添加到研究数据集中?

可以,但应将其视为具有自身抽样限制的独立证据来源。 评论者未必能代表所有买家,且文本可能包含个人信息。请明确允许的收集范围,尽量减少不必要的标识符,并报告平台和观察时间段。情感分类属于衍生评估,因此应保留其评估方法和不确定性,而非将其作为直接的客户事实呈现。

应如何与其他团队共享研究结果?

请随数据记录一并提供数据字典、数据源范围、时间戳及已知限制。包含缺失值处理规则、产品匹配规则以及任何衍生字段的规则,以便其他分析师能够复现结果。与值会无预警变化的电子表格相比,带版本号的导出文件更便于审计。应明确负责人员,以便解答关于数据解读或更正的问题。

人工智能能否将产品分类到研究类别中?

可以,但在将其用于汇总分析前,请先对照经审核的样本评估其标签。应保留类别定义、模型或规则版本以及存在不确定性的分类结果,以便查阅。分类变更可能会导致产品在不同组别间转移,并改变报告中的趋势,即使源数据未发生变化。对于新类别或模糊类别,应采用单独的审核流程。

结论

市场研究中的网络爬取,在设计好测量方案后再构建采集器时效果最佳。明确研究问题,选择一个经得起推敲的来源样本,并保持产品、优惠和观察结果之间的区分。在计算价格差异前验证可比性,并公开覆盖缺失的信息,而不是将其隐藏在精美的图表中。

从一个类别和一个经过审核的小型样本开始。确认记录能够回答预期的问题,在多次观察中运行数据采集,并在扩展数据源列表之前调查失败原因。扩大模糊的架构只会产生更大的模糊数据集。

如果页面抓取占用了本应用于分析工作的精力,请考虑将 WebScrapingAPI 的 Scraper API 作为抓取组件,同时确保您的研究定义和验证规则保持明确。 已构建数据管道的价值不在于收集了多少数据,而在于其他开发人员或分析师能否审查结果、理解其局限性,并根据证据做出明智的决策。

关于作者

Sergiu Inizian, 技术内容撰稿人 @ WebScrapingAPI

Sergiu Inizian

技术内容撰稿人

Sergiu Inizian 是 WebScrapingAPI 的技术内容撰稿人,负责创作清晰、实用的内容,帮助开发者了解产品并有效使用它。

开始构建

准备好扩展您的数据收集规模了吗?

加入2,000多家企业,使用WebScrapingAPI在无需任何基础设施开销的情况下,以企业级规模提取网络数据。