㊙️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~持续更新中!
㊗️爬虫难度指数:⭐⭐⭐
🚫声明:本数据&代码仅供学习交流,严禁用于商业用途、倒卖数据或违反目标站点的服务条款等,一切后果皆由使用者本人承担。公开榜单数据一般允许访问,但请务必遵守“君子协议”,技术无罪,责任在人。

🌟 开篇语

哈喽,各位小伙伴们你们好呀~我是【喵手】。
运营社区: C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO
欢迎大家常来逛逛,一起学习,一起进步~🌟

  我长期专注 Python 爬虫工程化实战,主理专栏 《Python爬虫实战》:从采集策略反爬对抗,从数据清洗分布式调度,持续输出可复用的方法论与可落地案例。内容主打一个“能跑、能用、能扩展”,让数据价值真正做到——抓得到、洗得净、用得上

  📌 专栏食用指南(建议收藏)

  • ✅ 入门基础:环境搭建 / 请求与解析 / 数据落库
  • ✅ 进阶提升:登录鉴权 / 动态渲染 / 反爬对抗
  • ✅ 工程实战:异步并发 / 分布式调度 / 监控与容错
  • ✅ 项目落地:数据治理 / 可视化分析 / 场景化应用

📣 专栏推广时间:如果你想系统学爬虫,而不是碎片化东拼西凑,欢迎订阅/关注专栏👉《Python爬虫实战》👈
  
💕订阅后更新会优先推送,按目录学习更高效💯~

1️⃣ 摘要(Abstract)

🎯 目标:构建一个基于 Playwright 的自动化监测机器人,针对 Amazon/Shopee 等高防御电商平台,定时抓取指定商品的价格与库存状态,并生成价格走势报告。
🛠 工具Python 3 + Playwright (新一代自动化神器) + pandas (数据分析) + APScheduler (定时任务)。
💡 读完收获

  1. 降维打击:为什么 Selenium 已经是过去式,而 Playwright 才是现代爬虫的王者?
  2. 反检测技术:如何绕过 WebDriver 检测,伪装成正常用户浏览。
  3. 长期主义:如何设计一个“每天跑一次,跑一年不被封”的稳健系统。

2️⃣ 背景与需求(Why)

🤔 为什么要爬?
在跨境电商(Cross-border E-commerce)领域,价格战是常态。

  • 卖家视角:需要监控竞对(Competitor)是否降价,从而调整自己的广告出价。
  • 买家/套利视角:监控“历史低价”或库存回补,进行套利。

⚔️ 挑战等级:Hard
这些站点不是简单的 HTML。

  • 动态渲染:价格往往是 JS 加载的。
  • 风控:Amazon 会检测你的浏览器指纹(Canvas, WebGL),普通 requests 请求会直接返回 503 或验证码。

🎯 目标字段

  • Product Title (商品标题)
  • Current Price (当前价格)
  • Availability (库存/配送状态)
  • ASIN/ID (商品唯一码)
  • Timestamp (抓取时间)

3️⃣ 合规与注意事项(⚠️ 高危必读)

在操作此类商业平台时,红线非常密集:

  1. API 优先原则:如果平台提供官方 API(如 eBay Finding API),必须优先使用 API。只有在无 API 可用时,才考虑网页采集。

  2. 绝对低频(Low-Frequency)

    • 错误:每秒爬 10 次,试图把全站数据拉下来(这是攻击,必死)。
    • 正确:模拟人类行为,每小时或每天查一次特定商品。我们做的是“监控”,不是“抄家”。
  3. 不触碰敏感区:绝不尝试自动化登录(Login)、不抓取用户评论中的个人隐私、不自动下单。只采集公开的 listing 页面信息。

4️⃣ 技术选型与整体流程(What/How)

🛠 为什么选 Playwright?

  • Requests/Scrapy:面对 Amazon 的强反爬和动态渲染,不仅要破解 JS 加密,还得维护复杂的 Cookie 池,成本太高。
  • Selenium:老旧、慢、特征明显(容易被识别出是机器人)。
  • Playwright:微软出品,原生支持异步(Async),速度比 Selenium 快数倍,且自带浏览器指纹管理,配合 playwright-stealth 插件,几乎可以完美模拟真人。

🔄 整体流程

任务调度 (Scheduler) ➡️ 启动无头浏览器 (Headless Browser) ➡️ 注入隐身脚本 (Stealth) ➡️ 渲染页面 ➡️ 提取数据 ➡️ 存入追加型 CSV

5️⃣ 环境准备与依赖安装(可复现)

除了安装 Python 库,Playwright 还需要下载浏览器内核。

# 1. 安装库
pip install playwright pandas apscheduler

# 2. 安装浏览器内核 (Chromium, Firefox, Webkit)
# 这一步非常重要!
playwright install

📂 项目结构

monitor_system/
├── data/
│   └── price_history.csv   # 历史价格数据库
├── app.py                  # 主程序
└── targets.txt             # 监控目标列表 (ASIN 或 URL)

6️⃣ 核心实现:隐身请求层(Stealth Fetcher)

普通的浏览器自动化会被 Amazon 一眼识破(navigator.webdriver 属性为 true)。我们需要“整容”。

(注:由于 playwright-stealth 库更新较慢,这里演示一种通过修改启动参数来手动隐身的方法,这是专家级的技巧)

import asyncio
import random
from playwright.async_api import async_playwright

async def fetch_product(url):
    """
    使用 Playwright 隐身访问页面
    """
    async with async_playwright() as p:
        # 1. 启动浏览器
        # headless=True 表示无界面模式(服务器运行用)
        # args 里的参数是为了禁用一些自动化特征
        browser = await p.chromium.launch(
            headless=True, 
            args=['--disable-blink-features=AutomationControlled'] 
        )
        
        # 2. 创建上下文 (Context)
        # 这一步至关重要!我们要模拟真实的 User-Agent 和视口大小
        context = await browser.new_context(
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
            viewport={'width': 1920, 'height': 1080},
            locale='en-US'
        )
        
        # 3. 注入反检测脚本 (Stealth Mode)
        # 这是一个核心 Hack,移除 navigator.webdriver 标记
        await context.add_init_script("""
            Object.defineProperty(navigator, 'webdriver', {
                get: () => undefined
            });
        """)
        
        page = await context.new_page()
        
        try:
            print(f"🕵️ 正在潜入: {url[:60]}...")
            # goto 里的 timeout 设长一点,电商页面加载慢
            await page.goto(url, timeout=60000, wait_until='domcontentloaded')
            
            # 4. 随机等待 (Human-like behavior)
            # 假装在看图片,停留 2-5 秒
            await asyncio.sleep(random.uniform(2, 5))
            
            # 5. 截图留证 (Debug 神器)
            # 遇到 403 或 验证码时,截图能让你知道发生了什么
            await page.screenshot(path='debug_snapshot.png')
            
            content = await page.content()
            return content, page # 返回 page 对象以便后续可能的交互
            
        except Exception as e:
            print(f"❌ 访问出错: {e}")
            return None, None
        finally:
            await browser.close()

7️⃣ 核心实现:鲁棒解析层(Robust Parser)

电商页面的 CSS 经常变,而且不同品类(书、电子产品、衣服)的布局可能不同。我们的解析器必须具备容错性

from bs4 import BeautifulSoup

def parse_amazon_html(html):
    """
    解析 HTML 提取关键信息
    """
    soup = BeautifulSoup(html, 'html.parser')
    data = {}
    
    # 1. 提取标题 (尝试多个常见的选择器)
    title_selectors = ['#productTitle', '#title', 'h1']
    for sel in title_selectors:
        node = soup.select_one(sel)
        if node:
            data['title'] = node.text.strip()
            break
    data.setdefault('title', 'Unknown Product')
    
    # 2. 提取价格 (这是最难的,因为格式极多)
    # 常见的有 .a-price-whole, #priceblock_ourprice, .apexPriceToPay
    price_node = soup.select_one('.a-price .a-offscreen')
    if not price_node:
        price_node = soup.select_one('#price_inside_buybox')
        
    if price_node:
        data['price'] = price_node.text.strip()
    else:
        data['price'] = 'N/A' # 可能缺货或需要登录见价格
        
    # 3. 提取库存状态
    availability = soup.select_one('#availability')
    data['status'] = availability.text.strip() if availability else 'Unknown'
    
    return data

# 🔍 代码详细解析:
# - 为什么要用 BeautifulSoup 而不是 Playwright 自带的选择器?
#   虽然 Playwright 可以 await page.locator('.price').text_content(),
#   但把 HTML 拿下来在本地用 BS4 解析更快,且不会因为页面元素遮挡而报错。
# - setdefault: 这是一个防御性编程。如果没找到标题,给个默认值,别让程序崩了。

8️⃣ 数据存储与定时任务(Persistence & Scheduler)

我们不做一次性买卖。我们需要记录时间序列数据,这样才能画出价格走势图。

import pandas as pd
import os
from datetime import datetime

def save_record(data, asin):
    """
    追加写入 CSV
    """
    filename = 'data/price_history.csv'
    os.makedirs('data', exist_ok=True)
    
    record = {
        'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        'asin': asin,
        'title': data['title'],
        'price': data['price'],
        'status': data['status']
    }
    
    df = pd.DataFrame([record])
    
    # header 处理:文件不存在时写入表头,存在时追加且不写表头
    if not os.path.isfile(filename):
        df.to_csv(filename, index=False, encoding='utf-8-sig')
    else:
        df.to_csv(filename, mode='a', header=False, index=False, encoding='utf-8-sig')
        
    print(f"💾 已记录: {data['price']} | {data['title'][:20]}...")

# 定时任务包装器
async def job(url_list):
    print(f"\n⏰ 定时任务启动: {datetime.now()}")
    for url in url_list:
        # 简单的从 URL 提取 ASIN 逻辑 (假设 url 是 amazon.com/dp/ASIN/...)
        try:
            asin = url.split('/dp/')[1].split('/')[0]
        except:
            asin = "Unknown_ID"
            
        html, _ = await fetch_product(url)
        if html:
            data = parse_amazon_html(html)
            save_record(data, asin)
            
        # ⚠️ 关键:每个商品之间休息 10-30 秒,模拟人类阅读
        wait = random.uniform(10, 30)
        print(f"☕ 喝口咖啡,休息 {wait:.1f} 秒...")
        await asyncio.sleep(wait)

9️⃣ 运行方式与监控面板(必写)

这里我们引入 APScheduler,让这个脚本变成一个由 Python 托管的后台服务。

# app.py
from apscheduler.schedulers.asyncio import AsyncIOScheduler
import asyncio

# 监控目标 (实际项目中应该从数据库读取)
TARGETS = [
    "https://www.amazon.com/dp/B08N5WRWNW", # 示例:PS5 或某款热门耳机
    # 添加更多...
]

if __name__ == "__main__":
    print("🚀 跨境电商监控系统初始化...")
    
    scheduler = AsyncIOScheduler()
    
    # 每天早上 9 点和晚上 9 点各跑一次
    # 这种低频操作是官方通常能容忍的底线
    scheduler.add_job(job, 'cron', hour='9,21', args=[TARGETS])
    
    print("⏳ 系统已启动,等待任务触发 (按 Ctrl+C 退出)...")
    
    try:
        scheduler.start()
        # 保持主线程存活
        asyncio.get_event_loop().run_forever()
    except (KeyboardInterrupt, SystemExit):
        pass

🔟 常见问题与排错(💡 专家经验)

在对抗激烈的电商领域,你一定会遇到这些:

  1. 验证码(Captcha)拦截

    • 现象:截图里显示一只狗,让你输入字符。
    • 策略:Playwright 无法自动解这种高级验证码。建议检测到验证码(检查页面是否有 “Enter the characters” 文本)时,立即停止任务并发送报警邮件,人工介入处理,或者等待几小时后重试。不要硬冲。
  2. 页面布局变异

    • 现象:昨天还能跑,今天 price 是 None。
    • 策略:电商平台经常做 A/B 测试。你的 CSS 选择器必须是列表形式 ['.price', '.offer-price', '#price'],挨个试。
  3. IP 被封(403/503)

    • 原因:请求太快,或者 IP 位于云服务器(AWS/阿里云的 IP 段通常被 Amazon 拉黑)。
    • 策略:如果你在云服务器上跑,必须买住宅代理(Residential Proxy)。如果在自家电脑跑(家庭宽带),通常不需要代理,只要频率够低。

1️⃣1️⃣ 进阶优化:企业级方向

如果你想把这个练手项目升级为生产力工具:

  1. 通知系统
    current_price < expected_price 时,通过 Server酱、Telegram Bot 或 钉钉机器人 推送消息。

    • 场景:“老板!竞对降价了,我们跟不跟?”
  2. 分布式部署
    单机 Playwright 跑 100 个任务内存就炸了。可以使用 Celery + Redis,把任务分发到多台机器上并行处理。

  3. API 混用策略
    通过 eBay API 获取市场均价(极速、合规),只用 Playwright 抓取 Amazon 独家竞品(精准、低频)。结合两者数据,生成更全面的报告。

1️⃣2️⃣ 总结与延伸阅读

🎉 复盘

这不仅是一个爬虫,更是一个**RPA(机器人流程自动化)**原型。我们用 Python 操作浏览器,像真人一样去巡查商品价格。
我们学会了:

  • Playwright 躲避检测。
  • AsyncIO 处理并发任务。
  • Cron 策略实现长期合规监控。

👣 下一步

  • 可视化:用 Streamlit 读取 price_history.csv,画出价格波动折线图,直接给老板看 Dashboard。
  • 深度学习:收集足够的验证码图片,训练一个 YOLO 模型来尝试识别(仅限研究用途!)。

请记住,技术无罪,但使用技术的人要有底线。保持低调,保持合规,你的爬虫之路才能越走越宽!

🌟 文末

好啦~以上就是本期 《Python爬虫实战》的全部内容啦!如果你在实践过程中遇到任何疑问,欢迎在评论区留言交流,我看到都会尽量回复~咱们下期见!

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦~
三连就是对我写作道路上最好的鼓励与支持! ❤️🔥

📌 专栏持续更新中|建议收藏 + 订阅

专栏 👉 《Python爬虫实战》,我会按照“入门 → 进阶 → 工程化 → 项目落地”的路线持续更新,争取让每一篇都做到:

✅ 讲得清楚(原理)|✅ 跑得起来(代码)|✅ 用得上(场景)|✅ 扛得住(工程化)

📣 想系统提升的小伙伴:强烈建议先订阅专栏,再按目录顺序学习,效率会高很多~

✅ 互动征集

想让我把【某站点/某反爬/某验证码/某分布式方案】写成专栏实战?

评论区留言告诉我你的需求,我会优先安排更新 ✅


⭐️ 若喜欢我,就请关注我叭~(更新不迷路)
⭐️ 若对你有用,就请点赞支持一下叭~(给我一点点动力)
⭐️ 若有疑问,就请评论留言告诉我叭~(我会补坑 & 更新迭代)


免责声明:本文仅用于学习与技术研究,请在合法合规、遵守站点规则与 Robots 协议的前提下使用相关技术。严禁将技术用于任何非法用途或侵害他人权益的行为。技术无罪,责任在人!!!

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐