必须先检查robots.txt并分析xhr请求,因电商网站常禁止爬取关键路径且价格由js动态加载,直接requests+beautifulsoup易失败,需结合随机延迟、ua伪装、session复用及数据库去重存储。

抓取前先确认目标网站是否允许爬虫
绝大多数电商或价格比价网站会在 robots.txt 里明确禁止爬虫访问关键路径,比如 /price、/product 或 API 接口。直接硬爬不仅可能被封 IP,还可能触发法律风险。打开目标域名根目录下的 robots.txt(例如 https://example.com/robots.txt),重点看 Disallow: 后面是否包含你打算访问的路径。如果发现 Disallow: /api/ 或 Disallow: /prices,说明官方不希望你批量获取数据。
更隐蔽但常见的是:网站通过 JavaScript 渲染价格,且关键字段由前端 JS 动态请求后端接口填充。这时用 requests.get() 拿到的 HTML 里根本没价格,必须分析浏览器开发者工具的 Network 面板,找到真实返回价格的 XHR 请求 URL 和所需 headers(比如 X-Requested-With、Referer)。
用 requests + BeautifulSoup 处理静态页面时的关键陷阱
很多老系统仍用服务端渲染,价格写在 HTML 里,看似适合 requests + BeautifulSoup。但实际运行常遇到 403、429 或返回空 div —— 原因不是代码写错,而是缺了基础伪装:
-
headers必须包含User-Agent,否则多数 CDN(如 Cloudflare)直接拦截;推荐用主流浏览器 UA 字符串,别用默认的python-requests - 部分网站校验
Accept、Accept-Language,漏掉可能返回简化版 HTML 或重定向到提示页 - 价格元素 class 名常动态生成(如
price_abc123),不能硬写死 selector;优先用属性定位,比如[itemprop="price"]或[data-testid="current-price"] - 价格可能含货币符号、空格、换行,用
strip().replace('\n', '').replace(' ', '')再转 float 更稳妥
应对反爬最常用的三个低成本手段
不需要上 Selenium 或 Playwright,先试试这三招能否绕过基础防护:
第一,加随机延迟:time.sleep(random.uniform(1, 3)),避免秒级高频请求被识别为脚本;第二,换 User-Agent 并轮询代理 IP(免费代理质量差,建议用付费 residential proxy,如 BrightData 或 ScraperAPI);第三,复用 session 并保持 cookies —— 很多网站要求先访问首页触发 cookie 设置,再请求商品页才放行。
如果目标网站用了前端加密参数(比如 URL 中带 sign=xxx),那就得逆向 JS:用浏览器断点调试找出生成逻辑,再用 execjs 或 py_mini_racer 在 Python 里执行等效 JS 代码,而不是硬猜参数规则。
存储与对比变动的核心逻辑不能只靠“存新查旧”
很多人写完抓取就直接把新价格 dump 到 CSV,下次运行再读出来比对 —— 这在单机小规模测试可行,但实际中会出问题:网络超时导致某次抓取失败,CSV 就缺一行;时间戳没对齐,同一天多次抓取覆盖了历史记录;不同 SKU 的价格单位不一致(比如有的标“¥199”,有的标“199.00”)。真正可用的做法是:
- 用 SQLite 或轻量级数据库(如
dataset库),每条记录带sku_id、price、scraped_at(精确到秒)、source_url - 每次入库前,用
ON CONFLICT REPLACE或 upsert 逻辑确保同一 SKU 当日只留最新一条 - 查变动时,不是简单比“上次”和“这次”,而是查每个 SKU 最近两条记录的时间差是否 >24h,再比价格是否变化 —— 避免因抓取间隔不均造成误报
真正难的不是怎么拿到价格,是怎么定义“有效变动”:促销价临时下调 2 小时算不算?同一商品在不同地区仓库显示不同价要不要合并?这些业务逻辑必须在入库前就设计好字段结构,后期补救成本极高。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











