news 2026/8/27 6:14:04

Python爬虫实战:双十一商品数据自动化采集与分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python爬虫实战:双十一商品数据自动化采集与分析

1. 项目概述:为什么用Python抓取双十一商品数据?

又到一年双十一,作为技术人,看着满屏的促销信息,你是不是也想过:这些商品数据背后到底藏着什么规律?哪些品类折扣最狠?历史价格曲线是怎样的?与其手动一个个商品去比价、记录,不如写个脚本,让程序自动帮你把感兴趣的商品信息“一网打尽”,保存到Excel里慢慢分析。这就是我们这次要做的——用Python构建一个双十一商品数据采集器。

这个项目的核心价值在于“自动化”和“可分析”。手动收集信息效率低、易出错,而一个几十行的Python脚本,可以在几分钟内抓取成百上千个商品的关键信息,包括标题、价格、销量、店铺、促销标签等,并规整地存入Excel表格。有了这份结构化的数据,无论是做个人消费决策分析(比如对比同款商品在不同平台的价格),还是进行简单的市场调研(观察某个类目下的价格分布和竞争态势),都有了扎实的数据基础。它特别适合有一定Python基础,想通过一个有趣、实用的项目来巩固爬虫和数据处理技能的朋友,也适合那些对数据敏感、希望用技术提升生活效率的“极客”们。

接下来,我将带你从零开始,拆解这个项目的完整实现路径。我们会用到requests库来模拟浏览器请求,用BeautifulSoupparsel来解析网页内容,最后用pandas将数据优雅地写入Excel。过程中,我会重点分享如何应对反爬策略、如何高效解析复杂页面结构,以及如何将数据清洗得干净利落。这些技巧,都是我在多次电商数据抓取项目中踩过坑后总结出来的实战经验。

2. 核心思路与工具选型:为什么是这套组合拳?

在动手写代码之前,理清思路和选对工具至关重要。一个高效的爬虫项目,绝不是把几个库堆砌起来就行,而是要根据目标网站的特点,选择最合适、最稳定的技术方案。

2.1 整体架构设计

我们的目标是获取双十一商品数据并保存为Excel。流程可以抽象为四个核心步骤:

  1. 目标确定与URL构造:明确要抓取哪个电商平台、哪个类目下的商品。双十一期间,各大平台的商品列表页通常会有专门的促销标识和筛选条件。
  2. 网页内容抓取:模拟浏览器访问这些商品列表页和详情页,获取原始的HTML数据。
  3. 数据解析与提取:从复杂的HTML代码中,精准地定位并提取出我们需要的商品信息字段。
  4. 数据存储与导出:将提取出的结构化数据(列表或字典)保存到Excel文件中,便于后续使用。

这个流程看似简单,但每个环节都有“坑”。比如,网站可能有访问频率限制、页面内容是动态加载的、HTML结构经常变动等。我们的方案必须足够健壮以应对这些挑战。

2.2 工具库选型与理由

为什么选择requests+BeautifulSoup/parsel+pandas这套组合?这是经过大量实践验证的“黄金搭档”。

  • 网络请求:Requests库Requests是Python中最简单易用的HTTP库。相比Python自带的urllib,它的API设计极其人性化,几行代码就能完成GET/POST请求、添加请求头、处理Cookie等操作。对于大多数静态页面或接口数据抓取,它都是首选。在双十一这种高并发场景下,目标网站对爬虫的容忍度可能更低,因此我们需要用Requests精细地控制请求头(特别是User-Agent),模拟得更像真实浏览器。

  • HTML解析:BeautifulSoup 或 Parsel这是从HTML“大海”中捞出数据“针”的关键工具。

    • BeautifulSoup:老牌、强大、文档丰富。它支持多种解析器(如lxml,html.parser),能很好地处理“破碎”的HTML,查找语法直观(find,find_all,select)。对于Python新手来说,学习曲线平缓。
    • Parsel:你可能更熟悉它在Scrapy框架中的身影。它继承了Scrapy选择器的强大功能,支持XPath和CSS选择器,解析速度通常比BeautifulSoup更快,尤其是在处理大量页面时。XPath的路径表达方式在定位复杂嵌套元素时非常精准。我的选择建议:如果你对CSS选择器熟悉,或者项目后期可能升级到Scrapy,用Parsel。如果你追求极简和快速上手,用BeautifulSoup。本文示例将主要使用BeautifulSoup,因为其受众更广,但原理是相通的。
  • 数据处理与导出:Pandas抓取到的数据往往是零散的字典或列表。PandasDataFrame对象是处理这类表格数据的“神器”。我们可以轻松地将数据列表转换为DataFrame,进行数据清洗(去重、填充空值、格式转换),然后通过一行代码df.to_excel(‘filename.xlsx’, index=False)导出为Excel。它比直接用openpyxlxlwt库手动写入单元格要高效、优雅得多。

注意:在进行任何网络爬取前,务必遵守目标网站的robots.txt协议,尊重网站的服务条款。避免过高频率的请求,以防对对方服务器造成压力,导致自己的IP被封锁。本教程仅用于技术学习和个人数据分析,请勿用于商业爬取或恶意攻击。

3. 实战环境搭建与核心代码拆解

理论说得再多,不如一行代码。让我们一步步搭建环境,并深入每个环节的代码实现。

3.1 环境准备与依赖安装

首先,确保你的电脑上安装了Python(3.6及以上版本)。然后,通过pip安装我们所需的库。建议使用虚拟环境来管理项目依赖,避免污染全局环境。

# 安装核心库 pip install requests beautifulsoup4 pandas openpyxl # 可选:如果你打算用lxml作为BeautifulSoup的解析后端(速度更快) pip install lxml
  • requests: 用于发送HTTP请求。
  • beautifulsoup4: 用于解析HTML。
  • pandas: 用于数据处理和导出Excel。
  • openpyxl: 这是pandas写入Excel文件(.xlsx格式)所需的引擎,新版pandas通常会依赖它。

安装完成后,可以在Python交互环境中导入测试一下,确保没有报错。

3.2 步骤一:分析页面与构造请求

这是爬虫成功的第一步,也是最需要耐心的一步。你不能对着空气抓取,必须知道数据在哪、怎么获取。

1. 确定目标与分析页面结构:假设我们以某个大型电商平台为例。打开其网站,进入“双十一”或“11.11”专题页。按F12打开开发者工具,切换到“Network”(网络)选项卡,然后刷新页面或滚动加载商品。你会看到浏览器发出的所有请求。寻找那些返回商品列表数据的请求,通常是XHR(Ajax)请求,其响应体是JSON格式,里面包含了整齐的商品信息。这是最理想的情况,因为JSON数据结构化程度高,极易解析。

如果找不到这样的接口,或者接口参数过于复杂,我们只能退而求其次,去解析商品列表页的HTML源码。在“Elements”(元素)选项卡中,使用检查工具(箭头图标)点击一个商品,查看它的HTML结构。你需要找到包裹商品信息的那个HTML标签以及其CSS类名或ID。例如,你可能发现所有商品都包裹在一个<div class=”J_item item”>里面。

2. 构造请求头与参数:为了让我们用requests发出的请求更像来自真实浏览器,必须设置请求头。最关键的是User-Agent

import requests from bs4 import BeautifulSoup import pandas as pd import time # 定义请求头,模拟浏览器 headers = { ‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36’, ‘Accept’: ‘text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8’, ‘Accept-Language’: ‘zh-CN,zh;q=0.9,en;q=0.8’, } # 双十一商品列表页URL示例(此处为示例,请替换为真实URL) base_url = ‘https://example.com/search?keyword=双十一’

实操心得User-Agent可以从你浏览器开发者工具的请求头里直接复制。有时网站还会检查Referer(来源页)或Cookie,对于更复杂的网站,可能需要使用session对象来保持会话,甚至处理登录状态。

3.3 步骤二:抓取与解析页面内容

有了URL和请求头,我们就可以发起请求并获取页面内容了。

def fetch_page(url, params=None): “”” 发送HTTP请求,获取页面内容 “”” try: # 添加延时,避免请求过快 time.sleep(1) response = requests.get(url, headers=headers, params=params, timeout=10) response.raise_for_status() # 如果状态码不是200,抛出异常 # 检查编码,通常使用apparent_encoding或utf-8 response.encoding = response.apparent_encoding return response.text except requests.exceptions.RequestException as e: print(f”请求失败: {url}, 错误: {e}“) return None # 获取第一页内容 html_content = fetch_page(base_url) if not html_content: print(“获取页面内容失败,请检查网络或URL”) exit()

拿到HTML内容后,就是BeautifulSoup大显身手的时候了。我们需要根据之前分析的页面结构,编写选择器来定位元素。

def parse_product_list(html): “”” 解析商品列表页,提取每个商品的基本信息链接或关键字段 “”” soup = BeautifulSoup(html, ‘html.parser’) product_list = [] # 假设每个商品项都在 class=’item’ 的div中 # 这个选择器需要你根据实际页面调整,可能是 ‘.J_item’, ‘.product-item’ 等 items = soup.select(‘.item’) for item in items: product_info = {} # 提取商品标题 title_elem = item.select_one(‘.title a’) product_info[‘title’] = title_elem.get_text(strip=True) if title_elem else ‘N/A’ # 提取商品价格 - 注意双十一可能有多种价格(原价、券后价、预售定金等) price_elem = item.select_one(‘.price’) product_info[‘price’] = price_elem.get_text(strip=True) if price_elem else ‘N/A’ # 提取商品销量 sales_elem = item.select_one(‘.sales’) product_info[‘sales’] = sales_elem.get_text(strip=True) if sales_elem else ‘N/A’ # 提取商品详情页链接 link_elem = item.select_one(‘.title a’) product_info[‘link’] = link_elem[‘href’] if link_elem and link_elem.has_attr(‘href’) else ‘N/A’ # 注意:链接可能是相对路径,需要补全为绝对URL if product_info[‘link’] and product_info[‘link’].startswith(‘/’): product_info[‘link’] = ‘https://example.com’ + product_info[‘link’] # 提取店铺名称 shop_elem = item.select_one(‘.shop’) product_info[‘shop’] = shop_elem.get_text(strip=True) if shop_elem else ‘N/A’ # 提取促销标签(如“每满300减40”,“预售”) promo_elem = item.select_one(‘.promo-tag’) product_info[‘promotion’] = promo_elem.get_text(strip=True) if promo_elem else ‘’ if product_info[‘title’] != ‘N/A’: # 只添加有标题的商品 product_list.append(product_info) return product_list # 解析第一页的商品 products = parse_product_list(html_content) print(f”第一页解析到 {len(products)} 个商品”)

关键点解析

  • select_one(‘.title a’):使用CSS选择器语法,查找class为title的元素下的第一个<a>标签。select_one返回单个元素,select返回列表。
  • .get_text(strip=True):获取元素的文本内容,并去除首尾空白字符。
  • .has_attr(‘href’)[‘href’]:检查元素是否有href属性,并获取其值。
  • 链接补全:这是非常容易忽略的一点。网站上的链接常常是相对路径(如/item/12345.html),直接请求会失败。需要根据基础URL将其补全为绝对路径。

3.4 步骤三:处理分页与数据存储

商品列表通常不止一页。我们需要找到分页的规律,可能是URL中的page参数,也可能是通过“加载更多”按钮触发的Ajax请求。

def crawl_multiple_pages(base_url, max_pages=5): “”” 爬取多页商品数据 “”” all_products = [] for page in range(1, max_pages + 1): print(f”正在爬取第 {page} 页...”) # 构造分页参数,根据实际网站调整 params = {‘page’: page, ‘sort’: ‘sale’} # 示例参数 html = fetch_page(base_url, params=params) if html: products_on_page = parse_product_list(html) all_products.extend(products_on_page) else: print(f”第 {page} 页爬取失败,停止。”) break # 每爬一页后稍作休息,更友好 time.sleep(2) return all_products # 爬取前5页 all_products = crawl_multiple_pages(base_url, max_pages=5) print(f”总共爬取到 {len(all_products)} 个商品”)

数据抓取完成后,用pandas将其转换为DataFrame并保存为Excel。

def save_to_excel(product_list, filename=’double11_products.xlsx’): “”” 将商品列表保存为Excel文件 “”” if not product_list: print(“没有数据可保存”) return # 创建DataFrame df = pd.DataFrame(product_list) # 简单的数据清洗:去重(根据标题和链接) df.drop_duplicates(subset=[‘title’, ‘link’], keep=‘first’, inplace=True) # 调整列顺序(可选) column_order = [‘title’, ‘price’, ‘sales’, ‘promotion’, ‘shop’, ‘link’] df = df.reindex(columns=column_order) # 保存到Excel try: df.to_excel(filename, index=False, engine=‘openpyxl’) print(f”数据已成功保存到 {filename}, 共 {len(df)} 条记录。”) except Exception as e: print(f”保存Excel文件时出错: {e}“) # 保存数据 save_to_excel(all_products)

实操心得df.to_excelindex=False参数很重要,它避免将DataFrame的行索引也写入Excel,让表格更整洁。engine=’openpyxl’确保生成的是.xlsx格式的新版Excel文件。

4. 高级技巧与反爬策略应对

真实的电商网站不会让你这么轻松地抓取数据。下面分享几个进阶技巧,让你的爬虫更健壮。

4.1 应对动态加载内容

越来越多的网站使用JavaScript动态加载内容。用requests抓取到的HTML是初始页面,可能不包含滚动后才加载的商品数据。解决方法有:

  1. 寻找隐藏的API接口:在开发者工具的“Network”中筛选XHR/Fetch请求,找到直接返回数据的JSON接口。然后,用requests模拟这个接口的请求(复制它的URL、参数、请求头,有时甚至需要Cookie或Token)。这是最高效的方法。
  2. 使用Selenium或Playwright:这类工具可以控制一个真实的浏览器,能执行JavaScript,完全渲染页面后再获取HTML。虽然功能强大,但速度慢、资源消耗大,适合小规模或必须模拟交互的场景。
  3. 逆向分析JS:找到动态加载数据的JavaScript代码,分析其生成请求的逻辑,然后用Python复现。这需要较强的JS逆向能力。

4.2 设置合理的请求间隔与代理IP

连续高速请求是触发反爬机制的最常见原因。

  • 请求间隔:在循环请求中,使用time.sleep(random.uniform(1, 3))来随机休眠,模拟人类操作。
  • 代理IP池:当单个IP被封锁后,可以使用代理IP服务。在requests.get()中通过proxies参数设置。
    proxies = { ‘http’: ‘http://your_proxy_ip:port’, ‘https’: ‘https://your_proxy_ip:port’, } response = requests.get(url, headers=headers, proxies=proxies)
  • 使用Sessionrequests.Session()可以自动管理Cookie,保持登录状态,在某些需要登录的页面非常有用。

4.3 解析更复杂的页面结构

有时商品信息分散在不同的标签里,或者被多层嵌套。

  • 多层选择soup.select(‘.product-info .price-wrapper .current-price’),可以精确定位。
  • 处理缺省值:不是每个商品都有促销标签或销量。代码中要用if … else …做好判断,避免因为某个元素缺失导致程序崩溃。
  • 正则表达式辅助:对于价格,字符串里可能包含“¥”、“¥”、“券后”等字符,可以用re模块提取纯数字。import re; price_num = re.search(r’\d+\.?\d*’, price_text).group()

5. 常见问题排查与优化建议

即使按照步骤操作,你也可能会遇到各种问题。这里汇总了一些常见坑点及解决方案。

5.1 请求被拒绝或返回异常内容

  • 现象requests返回403、404错误,或者返回的HTML内容很短,包含“访问受限”、“验证”等字样。
  • 排查
    1. 检查请求头:确保User-Agent是有效的,并且尽量模仿得跟你的浏览器一样。可以尝试添加Accept-Encoding,Referer等字段。
    2. 检查Cookie:某些页面需要登录后的Cookie才能访问。你可以从浏览器开发者工具中复制Cookie字符串,添加到请求头中:headers[‘Cookie’] = ‘your_cookie_string’
    3. 网站使用了反爬技术:如Cloudflare的5秒盾。对于这种情况,简单的requests难以绕过,可能需要使用cloudscraper这样的库,或者切换到Selenium。

5.2 解析不到数据或数据为空

  • 现象product_list为空,或者提取到的标题、价格都是N/A
  • 排查
    1. 确认选择器:页面结构可能已经更新。重新用开发者工具检查目标元素的CSS选择器是否还正确。有时类名会动态变化,可以尝试用其他属性如>
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/27 6:13:13

AI Skill 完全体环境搭建指南:从装而不生效到可复现、可验证

你很可能遇到过这种情况&#xff1a;安装了一个 AI Skill&#xff0c;目录也放进去了&#xff0c;配置也写了&#xff0c;结果和 Agent 对话时&#xff0c;它完全没有反应&#xff0c;甚至提示“未知命令”。这不是你的操作不够认真&#xff0c;而是 Skill 安装这件事本身就比想…

作者头像 李华
网站建设 2026/8/27 6:11:23

基于UDP实现可靠大文件传输:自定义协议设计与性能优化实践

简介&#xff1a;在计算机网络中&#xff0c;传输层协议是数据通信的基石。TCP协议通过连接管理、丢包重传和流量控制机制&#xff0c;为应用层提供了可靠的字节流服务&#xff0c;但其拥塞控制算法和队头阻塞问题&#xff0c;在高带宽、低延迟的局域网内传输大文件时可能成为性…

作者头像 李华
网站建设 2026/8/27 6:09:19

Python数学建模数据可视化:Matplotlib核心技巧与工程实践

1. 项目概述&#xff1a;为什么数学建模离不开Matplotlib&#xff1f;如果你正在用Python做数学建模&#xff0c;无论是参加竞赛还是完成科研项目&#xff0c;数据可视化这一关是绕不过去的。一堆冰冷的数字、复杂的矩阵&#xff0c;如果不转化成直观的图表&#xff0c;别说向评…

作者头像 李华
网站建设 2026/8/27 6:09:04

智能应用安全的经验沉淀

智能应用安全的经验沉淀 让维护成本参与决策 韩朔处理安全分析里的“智能应用安全的经验沉淀”时&#xff0c;通常不会先讨论工具多不多&#xff0c;而是先把任务压到一个具体场景&#xff1a;谁在什么条件下发起操作&#xff0c;系统需要留下什么结果&#xff0c;哪一步出错必…

作者头像 李华
网站建设 2026/8/27 6:07:10

Go语言 iota 详解:常量生成器原理、用法与工程实践

初学 Go 语言时&#xff0c;不少人会对常量声明里的iota感到困惑&#xff1a;它看起来像是一个“数字生成器”&#xff0c;但又不完全等同于传统的枚举&#xff1b;它写起来很简洁&#xff0c;但一旦遇到复杂表达式&#xff0c;结果又常常和直觉不符。本文会从iota的设计目的讲…

作者头像 李华
网站建设 2026/8/27 6:06:37

DNP3.0协议栈深度解析:从抓包工具到源代码重构的工业通信实践

简介&#xff1a;工业通信协议是工业自动化与物联网系统的核心技术基础&#xff0c;它定义了设备间数据交换的格式与规则&#xff0c;确保信息在分布式网络中的可靠传输。其工作原理通常遵循分层模型&#xff0c;从底层的物理链路到上层的应用数据表示&#xff0c;每一层都承担…

作者头像 李华