基于Scrapy的天猫商品数据爬取与分析实战(含API签名破解与可视化)

基于Scrapy的天猫商品数据爬取与分析实战(含API签名破解与可视化)

在这里插入图片描述


本文以华为Mate 60 Pro为例,详细介绍如何使用Scrapy框架爬取天猫商品数据,涵盖API签名破解、反爬应对、数据存储及可视化全流程,适合爬虫进阶学习者实践。

一、抓包分析:定位天猫商品API

1.1 目标与工具

  • 目标:获取华为Mate 60 Pro的价格、销量等数据
  • 工具:Chrome开发者工具(F12)、Mitmproxy(可选)

1.2 操作步骤

  1. 登录天猫并打开商品页
    访问 https://detail.tmall.com/item.htm?id=725643567890,右键点击页面 → 检查,切换到 Network 面板。

  2. 刷新页面抓包
    输入关键词 detail/get.json 过滤请求,找到目标API:

    https://api.tmall.com/rest/item/1.0/item/detail/get.json?itemId=725643567890&t=1685275400000&sign=abc123...
    
  3. 提取关键参数

    • itemId:商品ID(725643567890
    • t:13位时间戳(如 1685275400000
    • sign:MD5签名(需逆向生成)

二、环境搭建:Scrapy项目初始化

2.1 创建虚拟环境与依赖安装

# 创建虚拟环境
python -m venv venv
# 激活环境(Windows)
venv\Scripts\activate.bat
# 安装依赖
pip install scrapy requests cryptography matplotlib

2.2 初始化Scrapy项目

scrapy startproject tmall_huawei
cd tmall_huawei
scrapy genspider huawei_spider tmall.com

2.3 项目结构

tmall_huawei/
├── scrapy.cfg
└── tmall_huawei/
    ├── items.py         # 数据结构定义
    ├── middlewares.py   # 反爬中间件
    ├── pipelines.py     # 数据存储
    ├── settings.py      # 配置文件
    └── spiders/
        └── huawei_spider.py  # 爬虫逻辑
    └── utils/
        └── crypto.py    # 签名生成函数

三、核心开发:签名生成与爬虫逻辑

3.1 编写签名生成函数(utils/crypto.py

import hashlib
import time

def generate_tmall_sign(item_id, app_key="12574478", salt="0c8a5244c7d2b6e1b"):
    """生成天猫API签名"""
    t = str(int(time.time() * 1000))  # 13位时间戳
    sign_str = f"{t}{item_id}{app_key}{salt}"  # 拼接规则需与服务端一致
    sign = hashlib.md5(sign_str.encode()).hexdigest().lower()  # 转小写
    return {"t": t, "sign": sign, "appKey": app_key}

# 测试函数
if __name__ == "__main__":
    params = generate_tmall_sign("725643567890")
    print(f"生成的时间戳:{params['t']},签名:{params['sign']}")

3.2 定义数据结构(items.py

import scrapy

class TmallHuaweiItem(scrapy.Item):
    item_id = scrapy.Field()     # 商品ID
    title = scrapy.Field()       # 商品标题
    price = scrapy.Field()       # 价格
    sales = scrapy.Field()       # 月销量
    shop_name = scrapy.Field()   # 店铺名称
    timestamp = scrapy.Field()   # 采集时间

3.3 编写爬虫逻辑(spiders/huawei_spider.py

import scrapy
from urllib.parse import urlencode
from ..utils.crypto import generate_tmall_sign
from ..items import TmallHuaweiItem

class HuaweiSpiderSpider(scrapy.Spider):
    name = "huawei_spider"
    allowed_domains = ["tmall.com"]
    start_urls = ["https://detail.tmall.com/item.htm?id=725643567890"]

    def start_requests(self):
        item_id = "725643567890"
        sign_params = generate_tmall_sign(item_id)
        
        # 构造API参数
        params = {
            "itemId": item_id,
            "type": "json",
            "version": "1.0",
            "isLowPrice": "false",
            **sign_params
        }
        api_url = f"https://api.tmall.com/rest/item/1.0/item/detail/get.json?{urlencode(params)}"
        
        # 发送带请求头的API请求
        yield scrapy.Request(
            api_url,
            callback=self.parse_item,
            headers=self.get_headers(),
            meta={"item_id": item_id}
        )

    def parse_item(self, response):
        item = TmallHuaweiItem()
        data = response.json()
        item_info = data.get("data", {}).get("item", {})
        shop_info = item_info.get("shop", {})
        
        item["item_id"] = response.meta["item_id"]
        item["title"] = item_info.get("title", "")
        item["price"] = item_info.get("sellPrice", {}).get("price", "0.0")
        item["sales"] = item_info.get("sales", "0")
        item["shop_name"] = shop_info.get("name", "")
        item["timestamp"] = int(time.time())
        
        yield item

    def get_headers(self):
        """模拟浏览器请求头(含Referer和User-Agent)"""
        return {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/114.0.0.0 Safari/537.36",
            "Referer": "https://detail.tmall.com/item.htm?id=725643567890",
            "Accept": "application/json, text/plain, */*"
        }

四、数据存储与可视化

4.1 存储到CSV(pipelines.py

import csv
import time

class CSVPipeline:
    def __init__(self):
        self.filename = f"huawei_mate60_{time.strftime('%Y%m%d_%H%M')}.csv"
        self.file = open(self.filename, "w", newline="utf-8", encoding="utf-8-sig")  # 防止中文乱码
        self.writer = csv.DictWriter(self.file, fieldnames=["item_id", "title", "price", "sales", "shop_name", "timestamp"])
        self.writer.writeheader()

    def process_item(self, item, spider):
        self.writer.writerow(dict(item))
        return item

    def close_spider(self, spider):
        self.file.close()

4.2 启用管道(settings.py

ITEM_PIPELINES = {
    "tmall_huawei.pipelines.CSVPipeline": 300,
}

4.3 价格趋势可视化(visualize.py

import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

def plot_price_trend(csv_path):
    df = pd.read_csv(csv_path)
    df["price"] = df["price"].astype(float)
    df["time"] = df["timestamp"].apply(lambda x: datetime.fromtimestamp(x))
    
    plt.figure(figsize=(12, 6))
    plt.plot(df["time"], df["price"], marker="o", color="#FF6B6B", linestyle="-")
    plt.title("华为Mate 60 Pro价格趋势", fontsize=16)
    plt.xlabel("时间", fontsize=12)
    plt.ylabel("价格(元)", fontsize=12)
    plt.xticks(rotation=45)
    plt.grid(True, linestyle="--", alpha=0.7)
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    plot_price_trend("huawei_mate60_20250527_1530.csv")

五、调试技巧与反爬应对

5.1 常见错误与解决

错误类型原因分析解决方法
403 Forbidden签名错误或缺少请求头对比抓包签名,添加Cookie和Referer
JSONDecodeErrorAPI返回非JSON数据检查URL是否正确,确保登录态
KeyError: 'data'响应结构变化重新抓包分析JSON路径

5.2 反爬策略

  1. 请求间隔:在settings.py中设置 DOWNLOAD_DELAY = 2
  2. User-Agent轮换:使用fake_useragent库动态切换UA
  3. 代理IP池:集成scrapy-proxies中间件(需准备代理服务)

六、总结

本文通过实战演示了天猫商品数据爬取的完整流程,核心技术点包括:

  • 通过Chrome抓包定位API及参数逆向
  • 使用Scrapy框架实现分布式爬虫
  • MD5签名生成与反爬应对
  • 数据存储与可视化分析

实际应用中需根据网站反爬机制动态调整策略(如动态盐值、验证码处理),进一步可扩展为分布式集群或集成监控告警系统。

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灏瀚星空

你的鼓励是我前进和创作的源泉!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值