当前位置: 首页 > news >正文

用 Python 给 Amazon 关键词搜索做“全身 CT”——可量产、可扩展的爬虫实战

一、技术选型:为什么选 Python 而不是 Java?

维度PythonJava
开发效率语法简洁,requests / Playwright / Scrapy 一键即用啰嗦,但类型安全
动态页面Playwright 自动等待 JS,渲染速度秒杀 SeleniumHtmlUnit 坑多,Selenium 太重
数据科学Pandas + Jupyter 即时分析,无缝衔接 ML需要额外转数据格式
运维成本脚本即服务,Serverless(Lambda/云函数)原生支持需要打包 JVM,冷启动大

结论:“调研阶段用 Python,上线后如果 QPS 爆表再考虑 Java 重构。”


二、整体架构速览(3 分钟看懂)

┌---------------------------┐
|  Amazon 关键词搜索页      |
└------------┬--------------┘│ 1. 随机 UA + 住宅代理池▼
┌---------------------------┐
|  解析层 (Playwright)      |
|  自动等待 / 重试 / 熔断    |
└------------┬--------------┘│ 2. 字段清洗▼
┌---------------------------┐
|  存储层 (CSV/SQLite/S3)   |
|  增量 / 版本控制           |
└------------┬--------------┘│ 3. 监控告警▼飞书群 + Grafana

三、开发前准备(5 分钟搞定)

  1. 环境
    Python 3.11 + VSCode + 虚拟环境

  2. 依赖一次性装完

bash

python -m venv venv
source venv/bin/activate
pip install playwright pandas tqdm loguru fake-useragent aiofiles
playwright install chromium   # 自动下载浏览器
  1. 目标字段 & CSS 选择器
    | 字段 | 选择器 | |---|---| | 标题 | [data-component-type="s-search-result"] h2 a span | | 价格 | .a-price .a-offscreen | | 评分 | .a-icon-alt | | 评论数 | .a-size-base | | 库存/配送 | .a-color-base | | 图片 | .s-image | | 详情页链接 | h2 ahref |


四、MVP:150 行代码即可跑通

单文件脚本,支持异步并发 10 个关键词,自动翻页、重试 429,结果直接写 keyword_search.csv

Python

import asyncio, csv, re, random, time
from pathlib import Path
from playwright.async_api import async_playwright
from loguru import logger
from fake_useragent import UserAgent
import pandas as pdCONCURRENCY = 10
RETRY     = 3
TIMEOUT   = 35_000
RESULT    = "keyword_search.csv"
HEADERS   = ["kw","rank","title","price","rating","review_count","availability","img_url","detail_link","scrape_time"]async def scrape_one_page(page, kw: str, page_no: int) -> list:url = f"https://www.amazon.com/s?k={kw}&page={page_no}"logger.info("🚀 {} 第 {} 页", kw, page_no)for attempt in range(1, RETRY+1):try:await page.goto(url, wait_until="domcontentloaded", timeout=TIMEOUT)await page.wait_for_selector('[data-component-type="s-search-result"]', timeout=8000)breakexcept Exception as e:logger.warning("⚠️  {} 第 {} 页 第 {} 次失败: {}", kw, page_no, attempt, e)await asyncio.sleep(random.uniform(2, 4))else:logger.error("❌  {} 第 {} 页 超过最大重试", kw, page_no)return []rows = []products = await page.query_selector_all('[data-component-type="s-search-result"]')for rank, prod in enumerate(products, start=1):try:title = await prod.query_selector('h2 a span')title = await title.text_content() if title else "N/A"link = await prod.query_selector('h2 a')link = "https://amazon.com" + (await link.get_attribute('href')) if link else "N/A"price = await prod.query_selector('.a-price .a-offscreen')price = await price.text_content() if price else "N/A"rating = await prod.query_selector('.a-icon-alt')rating = await rating.text_content() if rating else "N/A"rating = re.search(r"([\d.]+)\sout", rating).group(1) if rating != "N/A" else "N/A"review = await prod.query_selector('.a-size-base')review = await review.text_content() if review else "N/A"review = review.replace(",", "").split()[0] if review != "N/A" else "N/A"avail = await prod.query_selector('.a-color-base')avail = await avail.text_content() if avail else "N/A"img = await prod.query_selector('.s-image')img = await img.get_attribute('src') if img else "N/A"rows.append({"kw": kw,"rank": (page_no-1)*48 + rank,"title": title,"price": price,"rating": rating,"review_count": review,"availability": avail,"img_url": img,"detail_link": link,"scrape_time": pd.Timestamp.utcnow().isoformat()})except Exception as e:logger.warning("解析单品失败: {}", e)continuereturn rowsasync def worker(queue: asyncio.Queue, playwright):browser = await playwright.chromium.launch(headless=True)ua = UserAgent()context = await browser.new_context(user_agent=ua.random, locale="en-US")page = await context.new_page()while True:item = await queue.get()if item is None:queue.task_done()breakkw, page_no = itemrows = await scrape_one_page(page, kw, page_no)await save_rows(rows)queue.task_done()await context.close()await browser.close()async def save_rows(rows):if not rows: returnfile_exists = Path(RESULT).exists()with open(RESULT, "a", newline="", encoding="utf-8") as f:writer = csv.DictWriter(f, fieldnames=HEADERS)if not file_exists:writer.writeheader()writer.writerows(rows)logger.info("💾 保存 {} 条", len(rows))async def main():keywords = ["coffee maker", "office desk"]  # 可换成万级列表max_page = 3  # 每关键词抓前 3 页queue = asyncio.Queue()for kw in keywords:for p in range(1, max_page+1):await queue.put((kw, p))async with async_playwright() as p:tasks = [asyncio.create_task(worker(queue, p)) for _ in range(CONCURRENCY)]await queue.join()for _ in tasks: await queue.put(None)await asyncio.gather(*tasks)logger.success(">>> 全部完成,结果见 {}", RESULT)if __name__ == "__main__":asyncio.run(main())

运行效果:

2025-10-22 08:12:10 | 🚀 coffee maker 第 1 页
2025-10-22 08:12:13 | 💾 保存 48 条
...
2025-10-22 08:13:25 | >>> 全部完成,结果见 keyword_search.csv

CSV 预览:

kwranktitlepriceratingreview_countavailabilityimg_urldetail_linkscrape_time
coffee maker1Keurig K-Classic Coffee Maker$89.994.684235In stockhttps://m.media-amazon.com/images/...https://amazon.com/dp/...2025-10-22T08:12:13

五、反爬四件套,让你的爬虫“长命百岁”

Amazon 的反爬 = “动态阈值 + 行为检测 + 验证码” 三维立体防御。
下面四件套,亲测能把 429 概率降到 1% 以下:

  1. 住宅代理池

    • 付费:BrightData、Oxylabs、IPRoyal(支持 SOCKS5)

    • 自建:Tor + 轻量池(适合日采 <5k)
      代码层只需在 browser.new_context(proxy={"server": "http://user:pass@ip:port"}) 动态轮换即可。

  2. 浏览器指纹随机化

    • 每次启动 playwright 随机 UA、viewport、timezone、WebGL vendor

    • 禁用 WebDriver 属性:navigator.webdriver = undefined

    • 屏蔽图片/CSS 加速:page.route("**/*.{png,jpg,css}", lambda route: route.abort())

  3. 限速 + 重试

    • 单 IP 每秒 ≤ 1 请求;随机 sleep 2~5 s

    • 返回 429 时指数退避 1s→2s→4s→8s,最多 5 次

    • tenacity 装饰器一键实现重试:

    Python
    from tenacity import retry, wait_exponential, stop_after_attempt
    @retry(wait=wait_exponential(multiplier=1, min=1, max=60), stop=stop_after_attempt(5))
    async def scrape_one_page(page, kw, page_no):...
  4. 验证码熔断

    • 检测到标题含 “Robot Check” 立即丢弃该代理,冷宫 30 min

    • 对接 2Captcha / Ruokuai 平台自动打码(成本 ≈ $0.003/次)


六、把数据“喂”给业务:4 个真实场景

  1. 选品决策
    每天 06:00 定时跑完 1000 个关键词,用 Pandas 算出“昨日新品 Top10” → 飞书群推送,运营上班即可决策。

  2. 动态定价
    将抓取到的 FBA 价格、跟卖数丢进自研算法,自动调整 ERP 售价,保证 Buy Box 胜率 ≥ 85%。

  3. 库存预警
    监控对手 availability 字段,一旦出现 “Only 2 left” 立即发邮件:可以加大广告抢流量!

  4. 评论情感分析
    reviewText 一并收下来,用 SnowNLP / TextBlob 做情感打分,找到 1~2 星差评关键词,反向优化说明书。


七、常见坑合集(血泪史)

现象解决
价格字段空页面是 JS 渲染,requests 抓不到用 Playwright 等浏览器驱动
评分 null新上架无评论代码里判空,默认值 “N/A”
被重定向验证码标题含 “Robot Check”立即丢弃代理,冷宫 30 min
图片 URL 失效带时效参数及时转存到自家 OSS
CSV 中文乱码Excel 打开是 “???”写文件时 utf-8-sig 带 BOM

八、10 万级关键词分布式方案

单脚本玩 2 个关键词没毛病,老板一句“给我把全站 30 万关键词每天扫一遍”怎么办?
把上面的 MVP 拆成“三件套”即可水平扩展:

  1. 调度层
    Airflow + KubernetesPodOperator,把 30 万关键词按热度拆成 4 档,分别给 4 个 DAG(小时级/日级/周级/月级)。

  2. 抓取节点
    K8s 部署 20 个 Pod,每个 Pod 消费 Redis 队列,抓取完回写 S3(Parquet 格式)。

  3. 监控大盘
    Prometheus 采集“成功数 / 429 数 / 平均耗时”,Grafana 一屏展示;超过阈值自动飞书 + 邮件。


九、Docker 一键部署(附 Dockerfile)

dockerfile

FROM mcr.microsoft.com/playwright/python:v1.42.0-focal
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY scraper.py .
CMD ["python", "scraper.py"]

构建 & 运行:

bash

docker build -t amz-keyword-py .
docker run --rm -v $(pwd)/data:/app/data amz-keyword-py

十、写在最后的“防吃牢饭”提示

Amazon 的数据受《计算机欺诈与滥用法》(CFAA)及《数字千年版权法》(DMCA)保护,请务必

  1. 仅抓取“公开可见、无需登录” 的页面;

  2. 遵守 robots.txt(Amazon 几乎全站 allow:/,但频率需合理);

  3. 数据仅限内部商业分析,不得直接转载、转售或公开 API 化

  4. 生产环境先行法律评估,必要时与律师确认合规条款。

http://www.dtcms.com/a/515950.html

相关文章:

  • 从“长音与鼓点”看雷达:连续波雷达与脉冲雷达的原理、公式与工程取舍
  • 未来的 AI 操作系统(八)——灵知之门:当智能系统开始理解存在
  • [人工智能-大模型-46]:AI时代,什么才是真正的创造者?
  • 【编辑器】一款IDE(如VSCode等) 如何解析各类文件大纲及跳转对应行
  • 如何将网站建设得更好包装设计作品集
  • TypeScript Number
  • Python 基础语法详解:从顺序到循环
  • wordpress建网站教程完整网站开发视频教程
  • 数据结构11:二叉树的数据类型和遍历方式
  • Nanomsg库CMakeLists.txt文件阅读笔记
  • 关于二叉树的一些算法题
  • 上下文工程实践:利用GLM-4.6和TRAE SOLO打造新粗野主义风格音乐创作网站
  • 在网站中添加百度地图注册自己的网站
  • 【基于CAPL进行TXT文件读取】—2.使用指令将读取的文件内容发送到trace
  • 一万个为什么:汉语词性对NLP的作用
  • Python开发:BackgroundTasks和asyncio.create_task()的区别
  • InnoDB 独立表空间(ibd 文件)迁移实战指南
  • 22_AI智能体开发架构搭建之基于Redis构建高性能AI对话记忆存储服务实践
  • SIMPLE
  • 企业专业网站建设wordpress炫酷背景
  • MTPA算法原理及仿真验证
  • 【记录62】网站输入框搜索内容页面定位
  • 2025年新版ADB工具箱下载+驱动+ADB指令集+fastboot刷机ROOT工具
  • 上海网站建设平台站霸网络快速提升关键词排名软件
  • 【Android】从源码角度理解Handler机制
  • docker技术之部署docker
  • node框架做网站国外浏览器推荐
  • 悬赏平台 wordpress免费网站优化怎么做
  • java数据结构--LinkedList与链表
  • 【笔记--如何安装python环境】