1. 项目背景与工具选型
最近在做一个家居电商价格监控项目,需要采集宜家官网的商品数据。传统爬虫遇到的最大痛点就是动态加载内容——宜家的商品目录通过JavaScript异步加载,普通requests库根本无法获取完整数据。经过多轮技术选型,最终选择了微软开源的Playwright作为核心工具。
为什么是Playwright而不是Selenium或Puppeteer?这里有几个关键考量点:
- 跨浏览器支持:一套代码可运行在Chromium、Firefox和WebKit上
- 自动等待机制:内置智能等待,不需要手动写sleep
- 无头模式性能:比Selenium快3-5倍的内存占用
- 录制功能:playwright codegen可以录制操作生成代码
重要提示:Playwright安装时建议指定国内镜像源,否则chromium下载可能失败。使用命令:
pip install playwright -i https://pypi.tuna.tsinghua.edu.cn/simple
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与基础配置
2.1 安装必备组件
首先需要安装Python 3.7+环境,然后执行:
bash复制# 安装playwright库
pip install playwright
# 安装浏览器二进制文件(建议全部安装)
playwright install chromium
playwright install firefox
playwright install webkit
2.2 初始化浏览器实例
创建一个基础爬虫类,封装浏览器初始化逻辑:
python复制from playwright.sync_api import sync_playwright
class IKEASpider:
def __init__(self, headless=True):
self.playwright = sync_playwright().start()
self.browser = self.playwright.chromium.launch(
headless=headless,
args=["--disable-blink-features=AutomationControlled"]
)
self.context = self.browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
)
self.page = self.context.new_page()
关键参数说明:
headless=False调试时可看到浏览器界面args参数用于禁用自动化检测user_agent需要模拟真实浏览器
3. 宜家网站结构分析与爬取策略
3.1 商品目录加载机制
通过开发者工具分析发现:
- 首页加载完成后发起AJAX请求获取分类数据
- 每个分类页采用无限滚动加载
- 商品详情页有独立API接口
3.2 核心爬取流程设计
mermaid复制graph TD
A[启动浏览器] --> B[访问宜家首页]
B --> C[获取一级分类]
C --> D[遍历二级分类]
D --> E[滚动加载商品列表]
E --> F[提取商品基础信息]
F --> G[进入详情页获取完整数据]
实际代码实现的关键函数:
python复制def crawl_category(self, url):
self.page.goto(url)
# 等待分类元素加载
self.page.wait_for_selector(".nav-item")
# 自动滚动到底部触发加载
last_height = 0
while True:
self.page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
self.page.wait_for_timeout(2000) # 适当等待
new_height = self.page.evaluate("document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
# 提取商品卡片
items = self.page.query_selector_all(".product-card")
return [self.parse_item(item) for item in items]
4. 反爬对抗与优化策略
4.1 常见反爬措施破解
宜家采用了多种反爬手段:
- 用户行为检测(鼠标移动轨迹)
- 请求频率限制
- WebSocket验证
应对方案:
python复制# 模拟人类操作
async def human_like_actions(page):
await page.mouse.move(100, 100)
await page.wait_for_timeout(random.randint(200, 800))
await page.mouse.move(200, 150)
# 使用代理IP池
context = browser.new_context(
proxy={"server": "http://proxy.example.com:8080"}
)
# 随机延迟
await page.wait_for_timeout(random.randint(1000, 3000))
4.2 数据存储优化
采用增量爬取策略:
python复制def is_new_item(item_id):
redis_client = Redis()
if redis_client.sismember("crawled_items", item_id):
return False
redis_client.sadd("crawled_items", item_id)
return True
存储方案对比:
| 方案 | 优点 | 缺点 |
|---|---|---|
| MySQL | 结构化查询方便 | 写入性能一般 |
| MongoDB | 灵活Schema | 占用内存大 |
| CSV文件 | 简单易用 | 不适合大数据量 |
5. 完整代码实现与调试技巧
5.1 核心爬虫类实现
python复制class IKEACrawler:
def __init__(self):
self.playwright = sync_playwright().start()
self.browser = self.playwright.chromium.launch(headless=False)
self.context = self.browser.new_context()
self.page = self.context.new_page()
def crawl(self, start_url):
self.page.goto(start_url)
self.handle_cookies_popup()
categories = self.get_categories()
for cat in categories:
products = self.crawl_category(cat['url'])
self.save_products(products)
def handle_cookies_popup(self):
try:
self.page.click("#cookie-consent-accept-btn", timeout=5000)
except:
pass
def get_categories(self):
# 实现分类提取逻辑
pass
def crawl_category(self, url):
# 实现分类页爬取
pass
def save_products(self, products):
# 实现存储逻辑
pass
5.2 实用调试技巧
- 使用Playwright Recorder生成基础代码:
bash复制playwright codegen https://www.ikea.com
- 截屏调试:
python复制# 页面异常时截图
page.screenshot(path="debug.png")
- 控制台日志:
python复制# 打印网络请求
page.on("request", lambda request: print(">>", request.method, request.url))
page.on("response", lambda response: print("<<", response.status, response.url))
6. 项目扩展与进阶方向
6.1 分布式爬虫架构
当需要大规模爬取时,可以考虑:
- 使用Scrapy+Playwright组合
- 基于Redis的任务队列
- Docker容器化部署
6.2 数据应用场景
采集到的数据可以用于:
- 价格监控与历史趋势分析
- 竞品对比分析
- 商品推荐系统
- 库存预警系统
6.3 性能优化指标
测试对比结果(1000个商品):
| 配置 | 耗时 | 内存占用 |
|---|---|---|
| 单线程 | 12分 | 800MB |
| 多线程(4) | 3分 | 1.2GB |
| 分布式(3节点) | 1分 | 600MB/节点 |
7. 常见问题解决方案
在实际项目中遇到的典型问题:
问题1:页面检测到自动化工具
- 解决方案:添加
--disable-blink-features=AutomationControlled启动参数 - 额外措施:修改navigator.webdriver属性
问题2:无限滚动不触发加载
- 解决方案:调整滚动速度和等待时间
- 替代方案:直接调用页面内部加载函数
问题3:验证码突然出现
- 解决方案:使用2Captcha等验证码服务
- 预防措施:控制访问频率,模拟人类行为
8. 法律合规与道德考量
在开发商业爬虫时需要注意:
- 遵守robots.txt协议
- 控制请求频率(建议<1req/s)
- 不爬取用户隐私数据
- 设置合理的User-Agent
- 考虑使用官方API优先
个人学习使用建议:
- 仅用于技术研究
- 不进行商业牟利
- 不造成服务器负担
我在实际项目中发现,宜家对技术友好的爬取行为容忍度较高,但明显恶意的DDOS攻击会很快被封IP。建议在非高峰时段运行爬虫,并做好错误重试机制。
