住宅代理

跨国抓取 App Store 和 Google Play 数据

一个应用并非只有一个排名、一个价格或一套评论。它在每个应用商店中都有不同的数据,而你只能从该商店内部读取这些数据。

James Meadow

James Meadow

2026年8月22日 · 1 分钟阅读

移动应用数据看起来简单得让人误解。一个应用有排名、评分、价格、描述。但当你从另一个国家查看同一个应用时,这些数字全都不一样了,因为各大应用商店并不是一本目录,而是一组各自独立的国家级商店门户,各自有自己的排名、定价、上架情况,以及用自己语言写成的评论。你从自己所在办公室看到的,只是一百多个商店门户中的一个,把它当作全球图景来看待,是移动市场情报工作中最常见的错误。

这使得应用商店数据采集首先是一个地理问题,其次才是一个抓取问题。下面说明移动团队采集哪些数据、你落地到哪个商店门户是由请求看起来源自哪里决定的,以及住宅代理如何让你像本地用户一样阅读每个市场。

移动团队采集哪些数据

有用的数据可以分成几类。首先是排名:一个应用在分类榜和总榜中的位置,以及它在特定关键词的商店搜索结果中的位置,这两者都是按商店门户单独计算的,并且每天都在变动。其次是元数据,即标题、副标题、描述、截图和更新说明,这些都是按市场本地化的,是理解竞争对手在每个地区如何定位自己的原始材料。然后是定价,包括付费价格和应用内购买档位,这些按市场和货币变化,而不是按即时汇率换算出来的同一个数字。

上架情况比人们预期的更重要:一个应用可能在某个国家根本没有上架,无论是出于发行商的选择还是监管要求,而知道竞争对手在哪些地方有、哪些地方没有,本身就是一个战略信号。评分和评论则完善了这幅图景,因为分数和评论文本都是按商店门户区分的,一个市场里的抱怨往往和另一个市场里的抱怨完全不同。围绕这一切的还有发布节奏和编辑推荐位,即谁在持续发布更新、谁获得了推荐,这些同样是按国家区分的。

为什么你看到的商店门户由你的IP决定

两大应用商店都会把你导向某个国家的商店门户,这种路由主要由你的连接看起来源自哪里决定,并由设备语言区域设置以及网页端点上明确的国家参数加以强化,不过这些参数并不总能覆盖真实本地用户所能看到的一切。实际效果是,来自某个国家的请求会返回该国对你所有问题的答案:它的排名、价格、上架情况、评论。

因此,从单一地点采集只能得到一个商店门户的视角,无论你覆盖了多少个应用。你无法从德国的排名推断出日本的排名,也无法通过查看一个市场来看出某个应用在另一个市场是否下架。要阅读某个商店门户,请求必须来自其内部。

具备国家定向功能的住宅代理正是做到这一点,把每个请求放置在你想要阅读其商店门户的那个市场,这与用于访问任何随地区变化的公开数据所使用的合法地理定向是同一回事。值得注意的是,这与零售和旅游场景有所不同:应用商店门户是按国家划分的,所以国家级定向在这里就是恰当的粒度,城市级定向通常不会带来任何额外价值。让你呈现的语言和地区设置与你所使用的出口国家相匹配,这样商店门户才会返回本地用户实际会看到的本地化元数据。

规模问题:应用数乘以国家数乘以天数

这项工作的数据量来自乘法效应,而不是来自任何单一的重型查询。几百个被追踪的应用,分布在三四十个商店门户中,每天刷新一次,再加上关键词排名检查,累加起来的请求数量,如果来自太少的地址,会立即触及单个IP的速率限制。商店端点的限流非常激进,而一次被限流的响应不仅仅是延迟,它是每日时间序列中一个之后无法补上的空洞。

解决办法是分散:把检查分摊到整个IP池中,让每个地址都保持在限制之内,同时总体吞吐量得以扩大,这正是任何高流量采集器背后的负载均衡逻辑,也是无限并发连接存在的意义。如果你想知道实际上这种分散需要多大规模,相关推理见你到底需要多少个代理IP,简而言之,这取决于你在每个商店门户上的请求速率,而不是取决于一个笼统的IP池数字。

拿到真实的商店门户响应

商店的网页端点是受到防护的,数据中心地址段会被严厉处理,因为针对它们的自动化采集从未间断。从一个被标记的地址得到的响应,往往不是一次干净的封锁,而是对数据质量而言更糟糕的东西:一个被限流的响应、一个通用页面,或者一个看起来像数据但其实不是的部分结果。这才是需要设计应对的失败模式,因为它会悄无声息地破坏数据集。

住宅代理通过真实的家庭级连接路由每个请求,因此一次检查看起来就像是一个普通用户从自己所在国家打开商店页面,而一个具有良好信誉的干净地址会返回真实的商店门户,被标记的地址则会遇到验证或被敷衍打发。IP本身是必要但不充分的条件,所以要合理控制请求节奏,并处理好会触发封锁的信号,而不是因为端点碰巧有响应就一味猛打。

分页读取的粘性会话

大多数商店门户检查都是单次请求,应当轮换IP。例外是任何涉及分页的内容,而在这项工作中,这主要指评论。逐页浏览某个应用在某个国家的多页评论是一个连续的序列,如果出口地址在这个过程中发生变化,你可能会得到顺序不一致、重复条目,或者被重置回第一页。粘性会话会在这次浏览过程中固定使用一个地址,让分页保持连贯,然后下一个应用或国家再开始一个新的会话。在每日大范围扫描中轮换IP,在分页读取内部保持粘性。

保持序列数据的可靠性

排名是一个时间序列,而时间序列的质量取决于它有没有空缺。某个国家缺失一天的数据,就是你无法据以推理的一天,所以要把采集可靠性当作数据质量问题的一部分,而不仅仅是运维卫生问题。按商店门户监控采集管道,因为某个市场悄悄下降的成功率,首先意味着一条被扭曲的趋势线,而且值得验证返回的内容是否真的是商店门户,而不是通用页面或被限流的页面。这与持续进行的价格监控库存追踪所需要的纪律是一样的,采集到的结果也服务于同一类另类数据分析。

负责任地采集

这里有一些诚实的边界,值得重视。两大平台都为你自己的应用发布了官方报告API,那才是你自己表现数据的正确来源:它们结构化、准确,并且符合条款。公开商店门户采集是用于竞争和市场情报的,是任何API都不会给你的、关于别人应用的信息,应当只针对该国任何访问者都能看到的公开数据,并遵守各平台的服务条款和robots规则,以礼貌的请求速率进行。

有两点值得明确说明。评论数据属于用户生成内容,可能包含个人信息,因此应在适用的隐私规则下处理,不要构建针对个别评论者的画像。另外,这仅限于测量:采集排名数据属于市场调研,而试图影响排名、安装数或评论则属于操纵行为,违反每个平台的规则,代理不应被用于此目的。阅读商店门户是本职工作;触碰它则不是。

一个最小化的分国家读取示例

定向设置存在于网关的用户名中,因此固定某个商店门户只需要一个字段。让语言请求头与你正在读取的市场相匹配:

import requests

MARKETS = ["us", "gb", "de", "jp", "br"]

def storefront(country, lang):
    proxy = f"http://customer-USERNAME-country-{country}:PASSWORD@p.shifter.io:443"
    r = requests.get(
        "https://apps.example-store.com/app/id123456789",
        proxies={"http": proxy, "https": proxy},
        timeout=20,
        headers={"Accept-Language": lang},
    )
    r.raise_for_status()
    return r.text            # parse rank, price, availability, metadata

for country in MARKETS:
    html = storefront(country, "en-US" if country in ("us", "gb") else None)
    record(country, html)    # one row per storefront per day

在你追踪的每个市场上运行同样的读取操作,以构建按商店门户划分的图景,让分页的评论读取使用自己独立的粘性会话,并按固定的每日计划进行采样,使序列在各国之间具有可比性。通用的客户端模式可参考在Python中使用住宅代理这篇指南,而与评论相关的具体内容则在使用代理监控客户评论中有所介绍。

结论

一个应用并没有单一的排名、价格或评分。它在每个国家的商店门户中都有不同的数值,而每一个都只能从该国内部读取。这使得国家覆盖范围成为移动市场情报工作的核心要求,也使得从单一地点采集数据必然导致片面且具有误导性的图景。住宅代理正好解决了这个问题:通过国家定向像本地用户一样阅读每个商店门户,通过庞大的IP池在众多应用和市场上分摊每日扫描而不触发速率限制,通过干净的家庭级地址确保返回的是真实的商店门户而不是被限流的占位内容,并通过粘性会话支持分页读取。对自己的应用使用官方API,让竞争性采集停留在公开数据上并遵守各平台的条款,永远不要从测量排行榜越界到试图操纵它们。

这一采集层正是住宅代理所提供的:一个由真实家庭级IP组成的庞大IP池,具备国家定向功能,并在序列需要时提供粘性会话。按GB计费的定价非常适合这类工作,因为商店门户检查数据量小且频繁,成本会随你实际拉取的数据量变化,而不是随你监控的市场数量变化。

准备好开始了吗?

试用 Shifter 住宅代理,205M+ 个 IP,195+ 个国家,低至 $0.75/GB。

立即开始