在当今的电商时代,获取淘宝商品数据对于市场分析、价格监控和竞品研究至关重要。本文将详细介绍如何使用Python的面向对象编程(OOP)来构建一个稳定、可扩展的淘宝商品爬虫,并分享2024年最新的反爬应对策略。
一、淘宝爬虫的挑战与设计思路
淘宝作为国内最大的电商平台,其反爬机制相当复杂,包括但不限于:动态加载内容、字体加密、请求频率限制、验证码验证等
。传统的过程式脚本难以应对这些挑战,而使用面向对象的方法可以将功能模块化,提高代码的可维护性和扩展性。
通过类封装,我们可以将爬虫的不同功能分离,使代码结构更清晰。下面是我们将构建的爬虫类的主要结构:
import requests
import time
import random
import json
import re
from abc import ABC, abstractmethod
from bs4 import BeautifulSoup
from typing import Dict, List, Optional

class BaseTaobaoSpider(ABC):
“”“淘宝爬虫基类(2025年12月测试有效)”“”

def __init__(self, keyword, delay=(1, 3), max_retry=3):
    self.keyword = keyword
    self.delay_range = delay  # 请求延迟范围
    self.max_retry = max_retry
    self.session = requests.Session()
    self._setup_session()
    
def _setup_session(self):
    """初始化会话配置"""
    self.session.headers.update({
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
        'Referer': 'https://www.taobao.com/',
        # 注意:实际使用中需要添加更多头部信息
    })

二、淘宝商品爬虫类的完整实现

  1. 核心类结构设计
    我们首先设计一个基类,包含爬虫的通用功能,然后通过继承实现特定平台的爬虫:
    class TaobaoItemSpider(BaseTaobaoSpider):
    “”“淘宝商品爬虫类(2025年反爬适配版)”“”

    def init(self, keyword, max_pages=5):
    super().init(keyword)
    self.max_pages = max_pages
    self.data = [] # 存储爬取结果
    self.retry_count = 0 # 重试计数器

    def _random_delay(self):
    “”“随机延迟控制(模拟人类行为)”“”
    delay = random.uniform(*self.delay_range)
    time.sleep(delay)

    def _get_search_url(self, page=1):
    “”“生成搜索URL(2025年淘宝搜索接口)”“”
    # 淘宝搜索页每页44个商品
    start = (page - 1) * 44
    return f"https://s.taobao.com/search?q={self.keyword}&s={start}"

  2. 请求处理与异常处理机制
    健壮的异常处理是爬虫稳定性的关键。我们需要处理网络异常、反爬检测等各种情况:
    def request_with_retry(self, url, **kwargs):
    “”“带重试机制的请求方法”“”
    for attempt in range(self.max_retry):
    try:
    self._random_delay() # 请求前延迟
    response = self.session.get(url, timeout=10, **kwargs)

             # 检查是否被反爬(状态码异常或包含验证页面)
             if response.status_code != 200:
                 print(f"请求异常,状态码:{response.status_code},第{attempt+1}次重试")
                 continue
                 
             if "验证" in response.text or "滑块" in response.text:
                 print("触发反爬验证,需要处理验证码")
                 self._handle_anti_spider()
                 continue
                 
             return response
             
         except requests.RequestException as e:
             print(f"网络请求异常:{e},第{attempt+1}次重试")
             if attempt == self.max_retry - 1:
                 print("重试次数已达上限,放弃请求")
                 return None
                 
     return None
    
  3. 页面解析与数据提取
    淘宝页面结构复杂,数据通常以多种方式嵌入,需要综合使用多种解析技术:
    def parse_search_page(self, html):
    “”“解析搜索页面,提取商品列表”“”
    if not html:
    return []

     soup = BeautifulSoup(html, 'lxml')
     items = []
     
     # 方法1:尝试从JSON数据中提取(淘宝数据主要存储方式)
     script_data = self._extract_json_data(html)
     if script_data:
         items.extend(self._parse_json_items(script_data))
     
     # 方法2:从HTML中提取备选数据
     html_items = self._parse_html_items(soup)
     items.extend(html_items)
     
     return items
    

    def _extract_json_data(self, html):
    “”“从页面脚本中提取JSON数据(淘宝主要数据存储方式)”“”
    try:
    # 匹配淘宝页面中的JSON数据
    pattern = r’g_page_config\s*=\s*({.?})\s;\s*g_srp_loadCss’
    match = re.search(pattern, html, re.DOTALL)
    if match:
    json_str = match.group(1)
    return json.loads(json_str)
    except (json.JSONDecodeError, AttributeError) as e:
    print(f"JSON数据提取失败:{e}")

     return None
    

    def _parse_json_items(self, data):
    “”“解析JSON格式的商品数据”“”
    items = []
    try:
    # 淘宝JSON数据结构(2025年版本)
    auctions = data.get(‘mods’, {}).get(‘itemlist’, {}).get(‘data’, {}).get(‘auctions’, [])

         for item in auctions:
             item_info = {
                 'item_id': item.get('nid'),
                 'title': item.get('title'),
                 'price': item.get('view_price'),
                 'sales': item.get('view_sales', '0人付款'),
                 'shop': item.get('nick'),
                 'location': item.get('item_loc'),
                 'image_url': item.get('pic_url'),
                 'detail_url': item.get('detail_url')
             }
             items.append(item_info)
             
     except Exception as e:
         print(f"解析JSON商品数据失败:{e}")
         
     return items
    

三、高级反爬策略与应对方案

  1. 动态请求头管理
    使用动态的请求头可以降低被识别为爬虫的概率:
    def _rotate_headers(self):
    “”“动态轮换请求头(降低检测概率)”“”
    user_agents = [
    ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36’,
    ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36’,
    ‘Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36’
    ]

     headers = {
         'User-Agent': random.choice(user_agents),
         'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
         'Accept-Encoding': 'gzip, deflate, br',
         'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
         'Cache-Control': 'no-cache',
         'Referer': 'https://www.taobao.com/'
     }
     
     self.session.headers.update(headers)
    
  2. 字体加密应对方案
    淘宝使用字体加密来保护价格等关键信息,我们需要特殊处理:
    def _handle_font_encryption(self, price_text):
    “”“处理字体加密(淘宝价格反爬关键)4,7"”"
    # 淘宝字体加密映射表(需要定期更新)
    font_mapping = {
    ‘’: ‘0’,
    ‘’: ‘1’,
    ‘’: ‘2’,
    ‘’: ‘3’,
    ‘’: ‘4’,
    ‘’: ‘5’,
    ‘’: ‘6’,
    ‘’: ‘7’,
    ‘’: ‘8’,
    ‘’: ‘9’
    }

     # 替换加密字符
     for encrypted_char, real_char in font_mapping.items():
         price_text = price_text.replace(encrypted_char, real_char)
         
     # 提取数字
     price_match = re.search(r'(\d+\.?\d*)', price_text)
     return float(price_match.group(1)) if price_match else 0.0
    

四、完整爬虫流程控制
将各个模块组合成完整的爬虫流程:
def run(self):
“”“运行爬虫主流程”“”
print(f"开始爬取关键词 ‘{self.keyword}’,最多{self.max_pages}页")

    for page in range(1, self.max_pages + 1):
        print(f"正在爬取第{page}页...")
        
        # 生成URL
        url = self._get_search_url(page)
        
        # 发送请求
        response = self.request_with_retry(url)
        if not response:
            print(f"第{page}页请求失败")
            continue
            
        # 解析页面
        page_items = self.parse_search_page(response.text)
        
        if not page_items:
            print(f"第{page}页未解析到商品数据")
            # 可能是反爬机制触发,增加延迟
            time.sleep(10)
            continue
            
        self.data.extend(page_items)
        print(f"第{page}页获取到{len(page_items)}条商品数据")
        
        # 随机延迟,避免请求过于频繁
        time.sleep(random.uniform(2, 5))
        
    print(f"爬取完成,共获取{len(self.data)}条商品数据")
    return self.data

def save_to_file(self, filename=None):
    """保存数据到文件"""
    if not filename:
        timestamp = time.strftime("%Y%m%d_%H%M%S")
        filename = f"taobao_{self.keyword}_{timestamp}.json"
        
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(self.data, f, ensure_ascii=False, indent=2)
        
    print(f"数据已保存至:{filename}")
    return filename

五、使用示例与最佳实践

  1. 基本使用方法
    if name == “main”:

    创建爬虫实例

    spider = TaobaoItemSpider(“手机”, max_pages=3)

    运行爬虫

    data = spider.run()

    保存结果

    spider.save_to_file()

    打印统计信息

    if data:
    prices = [float(item[‘price’]) for item in data if item[‘price’]]
    avg_price = sum(prices) / len(prices) if prices else 0
    print(f"平均价格:{avg_price:.2f}元")
    print(f"最高价格:{max(prices) if prices else 0:.2f}元")
    print(f"最低价格:{min(prices) if prices else 0:.2f}元")

  2. 高级功能扩展
    对于更复杂的需求,可以扩展基类实现更多功能:
    class AdvancedTaobaoSpider(TaobaoItemSpider):
    “”“高级淘宝爬虫(支持代理IP、分布式等)”“”

    def init(self, keyword, proxy_pool=None):
    super().init(keyword)
    self.proxy_pool = proxy_pool # 代理IP池

    def request_with_retry(self, url, **kwargs):
    “”“使用代理IP的请求方法”“”
    if self.proxy_pool:
    proxy = self.proxy_pool.get_random_proxy()
    kwargs[‘proxies’] = {‘http’: proxy, ‘https’: proxy}

     return super().request_with_retry(url, **kwargs)
    

六、法律合规与道德提醒
在使用淘宝爬虫时,请务必注意以下事项
:
遵守robots.txt:尊重网站的爬虫协议
控制请求频率:避免对目标网站造成过大压力
数据使用限制:仅将数据用于个人学习或研究目的
避免商业滥用:不得将数据用于商业竞争或非法用途
结语
本文介绍的面向对象淘宝爬虫具有以下优势:
模块化设计:功能分离,便于维护和扩展
异常处理:健壮的错误处理机制提高爬虫稳定性
反爬应对:综合多种策略应对淘宝的反爬机制
可扩展性:易于添加新功能如代理IP、分布式爬取等

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐