
如果你已经知道住宅代理为什么能改善多地区价格观察,下一步真正困难的不是“买哪一种代理”,而是把商品任务、地区环境、代理会话、页面请求、异常处理和价格数据连接成一套可以长期运行的系统。
这篇文章专门回答“怎么做”。内容面向开发者、数据团队、电商卖家和价格情报人员,重点介绍如何配置住宅代理、发送请求、管理网络地址与会话、处理地区价格差异、记录失败任务,以及把价格结果保存为可以比较的数据。
如果你还需要先了解地区环境、动态与静态住宅地址的分工以及数据质量判断,可以先阅读文章 1:亚马逊价格监控住宅代理完整指南:从地区环境到数据质量。本文不再重复基础选型,而是直接进入实施流程。
一个可执行的亚马逊价格监控流程,可以概括为八个步骤:
建立商品、站点、地区和更新频率任务表。
为每组任务配置对应地区的住宅代理。
使用脚本请求库、任务框架或合规的浏览器环境发送请求。
在同一商品任务中保持会话稳定,在相互独立的任务之间进行有限轮换。
同步记录站点、网络地区、配送区域、语言、货币和访问时间。
对超时、限流、验证码和字段缺失进行分类,不把失败页面当成价格结果。
将价格、卖家、库存、优惠和环境字段一起保存。
只让通过质量检查的数据进入趋势比较和告警系统。
住宅代理只负责网络出口和地区环境的一部分。它不能保证页面一定完整,也不能替代亚马逊官方接口、网站规则、访问授权、字段校验或人工复核。对于能够通过官方数据接口、联盟接口、授权数据源或商业数据服务获得的数据,应优先使用这些方式。
不要先写爬虫,再补业务规则。价格监控最容易返工的原因,是开发已经能拿到页面,团队却没有定义“什么结果才算有效”。
开始前至少准备以下六类信息。
每个任务至少包含:
商品唯一标识,例如商品编号。
商品页面地址。
亚马逊站点,例如美国站、英国站或德国站。
目标国家、州或城市。
目标配送区域或邮政编码。
需要记录的价格类型。
更新频率与业务优先级。
不一定。能够通过官方数据接口、联盟接口、授权数据源或商业数据服务获得的信息,应优先使用这些方式。只有在获得授权且目标内容允许访问时,才考虑自建公开页面监控流程。
轻量级请求库更适合小规模验证和代理连接排查;任务框架更适合任务队列、并发控制、数据管道和长期调度。两者都需要单独建立地区、会话和数据质量规则。
不应该机械地每次轮换。同一商品的一组连续步骤通常更适合保持会话,相互独立的商品或地区任务可以使用不同会话。轮换粒度应与业务任务一致。
只比较国家市场时,国家级通常已经足够。只有当库存、配送承诺、税费或业务决策依赖更细地区时,才需要州级或城市级定位,并通过配送信息和货币进行交叉验证。
不要把不同站点、不同货币和不同配送地区的商品混在同一个无差别队列中。站点和地区应成为任务的正式字段,而不是写在备注里。
同一商品页可能同时出现标准售价、折扣价、优惠券、会员权益价格、订阅价格、运费、税费或第三方卖家报价。系统必须提前规定本次监控要比较哪一种价格。
建议至少拆分以下字段:
字段 | 说明 |
|---|---|
标价 | 页面显示的标价或参考价 |
当前售价 | 当前主要销售价格 |
优惠说明 | 优惠券或额外优惠说明 |
配送费用 | 可识别的配送费用 |
货币 | 页面货币 |
卖家 | 当前卖家或销售主体 |
库存状态 | 有货、无货或预计送达状态 |
报价类型 | 标准、促销、会员、订阅或第三方报价 |
代理服务通常会提供网关地址、端口、用户名、密码、地区参数和会话参数。为了避免凭据进入代码仓库,应把完整代理地址保存在环境变量中。
示例格式如下,具体参数名称应以服务商文档为准:
http://USERNAME:PASSWORD@PROXY_GATEWAY:PORT
如果服务商通过用户名表达国家和会话,可能会形成类似下面的结构:
http://username-country-us-session-price_monitor_01:password@gateway.example:10000
示例中的国家参数和会话参数只用于说明配置思路。不要直接复制到生产环境,也不要假设所有服务商使用相同格式。
基础任务可以使用:
轻量级脚本请求库,适合低并发验证和简单页面请求。
任务调度框架,适合任务队列、并发控制、管道入库和长期调度。
另一种脚本请求库,适合已有的数据服务。
浏览器自动化,适合获得授权且必须等待页面渲染的场景。
需要注意,请求库能返回页面源码,不代表页面中的目标数据一定完整。页面如果依赖脚本渲染、地区设置或交互状态,应先确认网站允许的访问方式,再选择官方接口、授权浏览器流程或其他合规数据来源。
至少准备两类存储:
价格结果表,保存通过质量检查的商品数据。
请求日志表,保存状态码、耗时、代理地区、会话、失败原因和重试次数。
不要只保存成功价格。没有失败日志,就无法判断价格空缺究竟来自商品无货、页面变化、地区错误、代理异常还是解析规则失效。
开始前明确:
只处理获得授权或允许访问的公开信息。
遵守目标网站当前规则、适用法律和组织内部数据政策。
不访问个人账户、订单、支付或其他非公开数据。
不把住宅代理用于规避登录验证、访问控制或平台限制。
出现验证码、持续拒绝或明确禁止信号时暂停任务并进入人工复核。
一套稳定系统通常由六个模块组成:任务表、调度器、代理管理器、请求与解析器、质量检查器、数据存储与告警。
调度器根据商品价值、站点、地区和更新频率生成本轮任务。例如,高价值商品每小时检查一次,普通商品每天检查两次,长尾商品每天或每周检查一次。
频率应来自业务需要,而不是为了增加请求量。价格变化较慢的商品没有必要高频访问。
代理管理器根据任务中的目标国家、州或城市选择对应住宅网络出口,并为任务生成会话标识。
同一个商品任务如果需要依次打开商品页、卖家报价页和相关配送信息,应尽量保持同一会话。相互独立的商品或地区任务,可以使用不同会话,但不需要在页面资源或每一个网络请求之间无意义地频繁换地址。
请求器发送请求,同时记录:
商品与任务编号。
目标站点和目标地区。
代理会话编号。
请求开始与结束时间。
网页状态码与响应耗时。
重试次数与最终状态。
解析器只负责把页面中可识别的商品信息拆成结构化字段。由于页面结构会变化,选择器必须可配置,并配套字段完整性检查。
质量检查不应只判断价格字段是否非空,还要检查:
站点是否正确。
货币是否符合预期。
配送地区是否与任务一致。
商品标识是否匹配。
页面是否为正常商品页。
价格类型是否可解释。
结果是否超出合理历史范围。
只有通过质量检查的结果才能进入正式价格表。异常数据进入复查队列,不直接覆盖上一条可信价格。
微软系统命令行可以为当前终端设置环境变量:
$env:PROXY_URL="http://USERNAME:PASSWORD@PROXY_GATEWAY:PORT"
苹果电脑或服务器终端可以使用:
export PROXY_URL="http://USERNAME:PASSWORD@PROXY_GATEWAY:PORT"
生产环境应通过密钥管理服务、部署平台的密钥功能或受控配置中心保存凭据,不要把用户名和密码写入代码、日志或公开仓库。
正式访问商品页面前,可以使用经过批准的网络出口信息服务验证当前网络环境,并记录返回的国家、州、城市和网络提供商。验证结果应与任务地区一起保存。
地区标签不是最终证据。还要通过亚马逊站点、页面货币、语言和配送区域交叉判断环境是否一致。
住宅网络链路通常比本地直连多一个代理节点,因此必须同时设置连接超时和读取超时。例如:
TIMEOUT = (5, 20) # 连接超时5秒,读取超时20秒
没有超时的任务可能长期占用工作线程,最终让整个队列看起来“没有报错但一直不完成”。
下面的代码用于演示代理配置、有限重试、超时、错误分类和基础日志。页面选择器仅为示例,实际使用前必须根据当前页面结构、访问授权和业务字段重新验证。
先安装依赖:
pip install requests beautifulsoup4
import logging import os import re import time from dataclasses import dataclass from decimal import Decimal, InvalidOperation from typing import Optionalimport requests from bs4 import BeautifulSoup from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry
logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s", )
class ManualReviewRequired(Exception): """任务需要停止自动处理并进入人工复核。"""
@dataclass class PriceResult: title: Optional[str] price: Optional[Decimal] currency: Optional[str] availability: Optional[str] http_status: int elapsed_ms: int quality_status: str
def build_session(proxy_url: str) -> requests.Session: session = requests.Session() session.proxies.update({ "http": proxy_url, "https": proxy_url, })
retry = Retry( total=2, connect=2, read=2, status=1, backoff_factor=2, status_forcelist=[429, 500, 502, 503, 504], allowed_methods=["GET"], respect_retry_after_header=True, raise_on_status=False, ) session.mount("https://", HTTPAdapter(max_retries=retry)) session.mount("http://", HTTPAdapter(max_retries=retry)) return sessiondef clean_text(node) -> Optional[str]: if node is None: return None return " ".join(node.get_text(" ", strip=True).split())
def parse_decimal(whole: Optional[str], fraction: Optional[str]) -> Optional[Decimal]: if not whole: return None whole_digits = re.sub(r"[^0-9]", "", whole) fraction_digits = re.sub(r"[^0-9]", "", fraction or "") if not whole_digits: return None normalized = whole_digits if fraction_digits: normalized = f"{whole_digits}.{fraction_digits[:2]}" try: return Decimal(normalized) except InvalidOperation: return None
def parse_product_page(html: str, status_code: int, elapsed_ms: int) -> PriceResult: soup = BeautifulSoup(html, "html.parser")
title = clean_text(soup.select_one("#productTitle")) whole = clean_text(soup.select_one(".a-price .a-price-whole")) fraction = clean_text(soup.select_one(".a-price .a-price-fraction")) currency = clean_text(soup.select_one(".a-price .a-price-symbol")) availability = clean_text(soup.select_one("#availability span")) price = parse_decimal(whole, fraction) quality_status = "valid" if title and price and currency else "needs_review" return PriceResult( title=title, price=price, currency=currency, availability=availability, http_status=status_code, elapsed_ms=elapsed_ms, quality_status=quality_status, )
第二个示例只负责网络请求和状态分类。页面源码解析可以使用对应的解析组件,但解析规则同样要接受字段完整性检查,不能只找到一个数字就认定采价成功。
代理轮换最容易被误解为“每次请求都换一个网络地址”。对于价格监控,正确策略取决于任务是否需要连续环境。

适合:
相互独立的公开页面样本。
不需要前后页面共享状态的任务。
多地区低频观察。
风险:
同一任务前后地区可能变化。
页面语言、货币和配送状态可能不一致。
异常结果难以复现。
适合:
同一商品的连续页面步骤。
需要稳定地区和配送环境的任务。
异常价格复查。
分页或同一卖家报价链路。
风险:
会话过期后需要明确重建。
如果一个会话承载过多任务,失败影响范围会扩大。
不要按“每个网络请求”决定是否轮换,而要按“业务任务”决定。
例如,一次任务需要检查一个商品编号对应的商品页、卖家、库存和配送信息,可以让这几个步骤共用一个会话。下一件相互独立的商品,或者下一个目标地区,再分配新的会话。
可以使用如下逻辑生成会话编号:
import hashlibdef build_session_id(marketplace: str, region: str, asin: str, run_id: str) -> str: raw = f"{marketplace}:{region}:{asin}:{run_id}" return hashlib.sha256(raw.encode("utf-8")).hexdigest()[:16]
这个会话编号用于内部日志和代理参数映射,不应包含密码、用户信息或其他敏感数据。
住宅代理提供的是网络地区,亚马逊最终展示结果还可能受到站点、配送地址、货币、语言、库存、卖家、时间和账号状态影响。
国家级定位适合比较不同亚马逊站点或不同国家市场。配置时至少保持以下信息一致:
站点域名。
代理出口国家。
请求语言设置。
目标货币。
配送国家或测试区域。
只有当商品库存、配送承诺、税费或业务分析确实依赖更细地区时,才需要州级或城市级定位。地区越细,可用地址、稳定性和成本约束通常越明显。
城市标签也不能单独证明页面环境正确。应重复检查网络出口信息、页面配送位置、货币和商品可用性。
配送区域有时需要通过页面交互或受控浏览器配置完成。对于获得授权的业务流程,应为不同地区建立独立测试配置,并记录:
测试站点。
配送国家和邮政编码。
页面语言和货币。
浏览器配置编号。
代理地区与会话编号。
是否登录以及使用何种授权账号类型。
公开价格观察应尽量不登录账号。确需账号状态的数据,应确认访问授权、账号用途和数据边界,不要采集与价格任务无关的个人信息。
任务编号 | 站点 | 代理地区 | 配送地区 | 语言 | 货币 | 会话策略 |
|---|---|---|---|---|---|---|
任务甲 | 亚马逊美国站 | 美国 | 美国指定区域 | 英语(美国) | 美元 | 同一商品固定会话 |
任务乙 | 亚马逊英国站 | 英国 | 英国指定区域 | 英语(英国) |
矩阵中的地区只是业务示例。团队应根据实际目标市场、授权范围和网站规则配置。
失败处理决定了系统最后保存的是价格数据,还是一堆无法解释的页面结果。

检测到验证码或机器人检查时:
立即停止当前自动任务。
保存任务编号、地区、会话、状态码和时间。
不把验证码页面送入价格解析器。
检查访问频率、授权范围和网站规则。
由人工决定是否调整流程或停止该数据来源。
验证码不是“换一个网络地址继续请求”的信号。持续轮换地址尝试绕过验证,会扩大合规风险,也会让日志失去解释价值。
超时可以分为:
代理连接超时。
加密连接或目标站点连接超时。
页面读取超时。
浏览器渲染超时。
不同超时应使用不同错误代码。连接超时可以进行一次或两次延迟重试;持续超时应把任务送入复查队列,不应无限重试。
收到 429 表示请求受到限流。系统应:
尊重服务器返回的建议等待时间。
降低该站点的并发与频率。
暂停相同任务组。
检查是否超过允许访问范围。
不通过快速更换住宅地址规避限流。
这些状态可能与认证、访问权限、请求规则或页面保护有关。默认处理应是停止自动重试、记录证据和人工检查,而不是把状态码当成代理质量问题直接更换地址。
状态码为 200 也可能失败。以下情况都应标记为待复核:
商品标题为空。
商品标识不匹配。
价格或货币为空。
页面显示了非目标地区。
返回的是搜索页、验证页或错误模板。
页面只有优惠说明,没有可比较的主价格。
{ "task_id": "US-01-ASIN-20260729T120000Z", "marketplace": "amazon.com", "target_region": "US", "session_id": "8f12c6d8a19e047b", "http_status": 429, "error_type": "rate_limited", "retry_count": 1, "elapsed_ms": 1832, "action": "paused_for_review", "observed_at": "2026-07-29T12:00:00Z" }
价格表的核心不是“保存最新价格”,而是保留每一次可信观察所对应的环境。
下面是一个简化的关系型数据库表结构:
CREATE TABLE price_observations ( id BIGSERIAL PRIMARY KEY, task_id TEXT NOT NULL, asin TEXT NOT NULL, marketplace TEXT NOT NULL, target_region TEXT NOT NULL, delivery_area TEXT, currency TEXT, sale_price NUMERIC(12, 2), list_price NUMERIC(12, 2), coupon_text TEXT, shipping_fee NUMERIC(12, 2), seller TEXT, availability TEXT, offer_type TEXT, session_id TEXT NOT NULL, http_status INTEGER NOT NULL, response_time_ms INTEGER, quality_status TEXT NOT NULL, observed_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() );CREATE INDEX idx_price_observations_lookup ON price_observations (asin, marketplace, target_region, observed_at DESC);
两条价格只有在以下条件基本一致时才适合直接比较:
商品编号相同。
亚马逊站点相同。
目标地区与配送区域相同。
货币相同。
价格类型相同。
质量状态为有效。
如果卖家、库存或促销类型发生变化,系统应把它标记为解释字段,而不是简单得出“市场价格上涨或下降”的结论。
异常阈值可以用于发现问题,但不应自动证明价格真实变化。例如:
与上一条有效价格相比变化超过设定比例。
价格低于近期合理区间。
货币突然变化。
商品从有货变成无货。
卖家发生变化。
同一时间不同会话得到冲突结果。
命中阈值后,将任务送入同地区、同配送条件的独立复查队列。复查通过后再触发业务告警。

[ ] 商品、站点、地区、配送区域和频率已经进入任务表。
[ ] 价格类型、货币、卖家、库存和优惠字段定义清楚。
[ ] 代理凭据通过环境变量或密钥功能管理。
[ ] 代理地区已经过独立验证。
[ ] 连接与读取超时已设置。
[ ] 单站点并发和请求频率有上限。
[ ] 401、403、429、验证码和字段缺失有停止规则。
[ ] 日志不包含代理密码、会话凭据或个人信息。
[ ] 异常价格不会直接覆盖上一条可信结果。
[ ] 团队已核对网站规则、授权范围和适用法律。
指标 | 说明 |
|---|---|
请求成功率 | 只反映网页请求情况,不能单独代表数据质量 |
有效价格率 | 通过地区、货币、字段和页面检查的结果比例 |
地区匹配率 | 网络地区、站点和配送环境一致的比例 |
字段完整率 | 标题、价格、货币、库存等必要字段完整的比例 |
异常复现率 | 异常结果在相同条件下能够再次出现的比例 |
单条有效数据成本 | 代理、计算、存储和复查成本除以有效记录数 |
平均恢复时间 | 从任务失败到恢复或完成复核所需时间 |
先选择 10 至 20 个代表性商品和一个目标地区进行小规模验证。
先证明地区和字段正确,再提高任务数量。
同一轮测试只调整一个变量,例如代理地区、会话策略或更新频率。
将公开页面观察、账号操作和异常复查拆成不同任务池。
定期抽查原始页面摘要与结构化结果,防止解析规则悄悄失效。
优先优化有效价格率,不要只追求请求数量或地址数量。
频繁轮换可能破坏同一任务的地区和会话一致性。是否轮换应由业务任务决定,而不是由请求数量决定。
页面可能返回验证模板、空商品页、错误地区或字段不完整的页面源码。必须进行第二层数据质量检查。
缺少站点、地区、配送、货币、卖家、库存和时间的价格无法可靠比较。
验证码应触发暂停、降频、规则检查和人工复核,不应被当成继续轮换地址的理由。
商品价值和价格变化速度不同。分级调度能降低成本,也能减少不必要访问。
不一定。能够通过官方数据接口、联盟接口、授权数据源或商业数据服务获得的信息,应优先使用这些方式。只有在业务获得授权、目标内容允许访问且其他方式不能满足需求时,才考虑自建公开页面监控流程。
轻量级请求库更适合小规模验证、单任务测试和排查代理连接;任务框架更适合任务队列、并发控制、自动重试、数据管道和长期调度。无论选择哪一种,都要单独建立地区、会话和数据质量规则。
不应该机械地每次轮换。同一商品的一组连续步骤通常更适合保持会话,相互独立的商品或地区任务可以使用不同会话。轮换粒度应与业务任务一致。
如果业务只比较国家市场,国家级通常已经足够。只有当库存、配送承诺、税费或业务决策依赖更细地区时,才需要州级或城市级定位,并通过页面配送信息和货币进行交叉验证。
停止当前自动任务,记录地区、会话、频率和响应状态,检查授权范围与网站规则,并进入人工复核。不要通过不断更换住宅地址尝试绕过验证码。
至少确认商品标识、站点、目标地区、配送条件、货币、价格类型和必要字段完整,并排除验证页、错误模板和异常跳转。超出历史范围的价格应先复查再入库。
不能。住宅代理主要改善网络地区和任务隔离。结果准确性仍取决于站点、配送地址、会话、货币、卖家、库存、页面解析、质量检查和异常复核。
使用住宅代理搭建亚马逊价格监控系统,真正需要管理的不是网络地址数量,而是任务与环境的一致性。
先定义商品、地区和价格字段,再为每个任务分配合适的住宅代理与会话。请求成功后继续检查地区、货币、页面类型和字段完整性;出现验证码、限流或访问拒绝时暂停自动任务;只有通过质量检查的数据才能进入价格比较和业务告警。
一套可以长期维护的流程,应当满足四个条件:任务可追踪、环境可复现、失败可解释、价格可比较。先用少量商品完成小规模验证,再根据有效价格率和单条有效数据成本逐步扩大,比一开始追求高并发和大量地址更稳妥。

停止当前自动任务,记录地区、会话、频率和响应状态,检查授权范围与网站规则,并进入人工复核。不要通过不断更换住宅地址尝试绕过验证码。
至少确认商品标识、站点、目标地区、配送条件、货币、价格类型和必要字段完整,并排除验证页、错误模板和异常跳转。超出历史范围的价格应先复查再入库。
不能。住宅代理主要改善网络地区和任务隔离。结果准确性仍取决于站点、配送地址、会话、货币、卖家、库存、页面解析、质量检查和异常复核。
def fetch_product(session: requests.Session, url: str) -> PriceResult: headers = { "Accept-Language": "en-US,en;q=0.8", "User-Agent": "AuthorizedPriceMonitor/1.0 (+operations-contact@example.com)", }
started = time.perf_counter() response = session.get(url, headers=headers, timeout=(5, 20)) elapsed_ms = int((time.perf_counter() - started) * 1000) logging.info( "request_finished status=%s elapsed_ms=%s url=%s", response.status_code, elapsed_ms, url, ) if response.status_code in {401, 403}: raise ManualReviewRequired( f"访问被拒绝,状态码为 {response.status_code},停止自动重试并人工检查规则与授权。" ) if response.status_code == 429: raise ManualReviewRequired( "请求受到限流。应降低频率、检查服务器建议等待时间与网站规则,不应通过持续更换网络地址规避限制。" ) response.raise_for_status() lower_html = response.text.lower() if "captcha" in lower_html or "robot check" in lower_html: raise ManualReviewRequired( "页面出现验证码或机器人检查,任务应暂停并进入人工复核。" ) return parse_product_page(response.text, response.status_code, elapsed_ms)
if name == "main": proxy_url = os.environ["PROXY_URL"] product_url = "https://www.amazon.com/dp/EXAMPLE_ASIN"
http_session = build_session(proxy_url) result = fetch_product(http_session, product_url) print(result)</code></pre><p>这段代码故意把状态码为 <code>401</code>、<code>403</code>、<code>429</code> 的响应和验证码页面送入人工复核,而不是不断切换地址继续请求。这样做不仅更符合合规要求,也能避免把拒绝页面、验证页面或不完整页面源码误解析成商品数据。</p><h3>示例一的生产化改造重点</h3><p>正式系统还需要补充:</p><ul><li><p>从任务队列读取商品和地区,而不是把页面地址写死。</p></li><li><p>将代理会话编号、目标地区和任务编号加入结构化日志。</p></li><li><p>将选择器放进配置文件,页面变更时无需修改主程序。</p></li><li><p>把原始响应摘要或哈希保存到证据表,不长期保存不必要的页面内容。</p></li><li><p>对价格、货币、库存和卖家分别做质量检查。</p></li><li><p>设置全局并发和每个站点的访问节奏上限。</p></li></ul><h2>使用脚本发送请求示例二</h2><p>已有的脚本服务可以使用相应请求库和代理连接组件。先安装依赖:</p><pre><code class="language-bash">npm install axios https-proxy-agent</code></pre><pre><code class="language-javascript">import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";
const proxyUrl = process.env.PROXY_URL;
if (!proxyUrl) { throw new Error("缺少 PROXY_URL 环境变量"); }
const agent = new HttpsProxyAgent(proxyUrl);
async function fetchProduct(url) { const startedAt = Date.now();
const response = await axios.get(url, { httpsAgent: agent, proxy: false, timeout: 20000, maxRedirects: 3, headers: { "Accept-Language": "en-US,en;q=0.8", "User-Agent": "AuthorizedPriceMonitor/1.0 (+operations-contact@example.com)", }, validateStatus: () => true, });
const elapsedMs = Date.now() - startedAt;
console.log(JSON.stringify({ event: "request_finished", url, status: response.status, elapsedMs, }));
if ([401, 403, 429].includes(response.status)) { throw new Error(
任务暂停并进入人工复核,网页状态码:${response.status}if (response.status < 200 || response.status >= 300) { throw new Error(
请求失败,网页状态码:${response.status}const html = String(response.data); const lowerHtml = html.toLowerCase();
if (lowerHtml.includes("captcha") || lowerHtml.includes("robot check")) { throw new Error("检测到验证码或机器人检查,停止自动处理"); }
return { html, status: response.status, elapsedMs, }; }
const result = await fetchProduct( "https://www.amazon.com/dp/EXAMPLE_ASIN" );
console.log({
status: result.status,
elapsedMs: result.elapsedMs,
htmlLength: result.html.length,
});英镑
同一商品固定会话 |
任务丙 | 亚马逊德国站 | 德国 | 德国指定区域 | 德语 | 欧元 | 同一商品固定会话 |