在电商消费场景中,商品价格的波动规律是消费者决策、商家定价策略优化的重要依据。Temu 作为跨境电商平台的代表,其商品价格常因促销、供应链调整、节日活动等因素发生变化。本文将从技术角度出发,详细讲解如何构建 Temu 商品历史价格趋势爬虫,并对爬取的数据进行简单分析,帮助读者掌握爬虫开发与数据处理的核心思路。
需要注意的是,爬虫开发需严格遵守平台的 robots 协议与相关法律法规,本文仅作技术学习与研究使用,不得用于商业用途或对平台服务器造成压力。在实际操作中,应控制请求频率、使用合法的代理 IP,并在平台允许的范围内获取数据。
一、技术选型与核心思路
1. 技术栈选择
结合开发效率与生态完整性,本次爬虫采用 Python 作为核心语言,关键库选择如下:
- 请求层 :
<font style="color:rgb(0, 0, 0);">requests</font>(处理常规 HTTP 请求)+<font style="color:rgb(0, 0, 0);">fake-useragent</font>(生成随机 User-Agent,规避基础反爬);若遇到动态渲染页面,可替换为<font style="color:rgb(0, 0, 0);">Playwright</font>模拟浏览器行为。 - 解析层 :
<font style="color:rgb(0, 0, 0);">BeautifulSoup</font>(解析 HTML 页面,提取商品价格、名称等基础信息)、<font style="color:rgb(0, 0, 0);">jsonpath</font>(解析接口返回的 JSON 数据)。 - 数据存储与分析 :
<font style="color:rgb(0, 0, 0);">pandas</font>(数据清洗、整理与趋势分析)、<font style="color:rgb(0, 0, 0);">matplotlib</font>(可视化价格趋势)、<font style="color:rgb(0, 0, 0);">sqlite3</font>(轻量级本地数据库,存储历史价格数据)。
2. 核心思路
Temu 商品页面的价格数据主要有两种呈现形式:一是直接嵌入 HTML 的静态价格,二是通过 AJAX 请求从后端接口获取的动态价格。本次爬虫的核心步骤为:
- 构造 Temu 商品链接,发送 HTTP 请求获取页面内容或接口数据;
- 解析数据,提取商品名称、当前价格、商品 ID、采集时间等信息;
- 将数据存储到本地数据库,实现历史价格的持续采集;
- 利用 pandas 与 matplotlib 对历史数据进行清洗、分析与可视化,生成价格趋势图。
二、爬虫实现过程
1. 环境准备
首先安装所需依赖库,
2. 核心代码实现
(1)数据库初始化
创建 SQLite 数据库,用于存储商品历史价格数据,表结构包含商品 ID、商品名称、价格、采集时间等字段:
python
python
import sqlite3
import datetime
def init_db():
"""初始化数据库与表结构"""
conn = sqlite3.connect('temu_price.db')
cursor = conn.cursor()
# 创建商品价格表
cursor.execute('''
CREATE TABLE IF NOT EXISTS product_price (
id INTEGER PRIMARY KEY AUTOINCREMENT,
product_id TEXT NOT NULL,
product_name TEXT NOT NULL,
price FLOAT NOT NULL,
crawl_time DATETIME NOT NULL
)
''')
conn.commit()
conn.close()
# 初始化数据库
init_db()
(2)爬虫核心逻辑
构造请求,解析 Temu 商品页面数据(以静态页面为例,若为动态接口,可直接请求接口地址):
python
python
import requests
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
def get_temu_product_info(product_url):
"""
获取Temu商品信息
:param product_url: Temu商品链接
:return: 商品ID、名称、价格
"""
# 初始化UserAgent,生成随机请求头
ua = UserAgent()
headers = {
'User-Agent': ua.random,
'Referer': 'https://www.temu.com/',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Accept-Encoding': 'gzip, deflate, br'
}
try:
# 发送GET请求,设置超时时间
response = requests.get(product_url, headers=headers, timeout=10)
response.raise_for_status() # 抛出HTTP请求异常
response.encoding = response.apparent_encoding # 自动识别编码
# 解析页面
soup = BeautifulSoup(response.text, 'lxml')
# 提取商品信息(需根据Temu页面结构调整选择器,以下为示例)
# 商品名称:假设页面中商品名称的标签为h1,class为product-title
product_name = soup.find('h1', class_='product-title').get_text(strip=True) if soup.find('h1', class_='product-title') else '未知商品'
# 商品价格:假设价格标签为span,class为product-price
price_str = soup.find('span', class_='product-price').get_text(strip=True).replace('$', '').replace('¥', '') if soup.find('span', class_='product-price') else '0'
price = float(price_str) if price_str.replace('.', '').isdigit() else 0.0
# 商品ID:从URL中提取(假设URL格式为https://www.temu.com/product/123456.html)
product_id = product_url.split('/')[-1].replace('.html', '') if '/' in product_url else '0'
return product_id, product_name, price
except Exception as e:
print(f"爬取失败:{e}")
return None, None, None
(3)数据存储与定时采集
将爬取的数据存储到数据库,并实现定时采集功能(可结合<font style="color:rgba(0, 0, 0, 0.85) !important;">schedule</font>库实现定时任务):
python
python
import time
def save_to_db(product_id, product_name, price):
"""将商品信息保存到数据库"""
if not product_id or price == 0:
return
conn = sqlite3.connect('temu_price.db')
cursor = conn.cursor()
crawl_time = datetime.datetime.now()
# 插入数据
cursor.execute('''
INSERT INTO product_price (product_id, product_name, price, crawl_time)
VALUES (?, ?, ?, ?)
''', (product_id, product_name, price, crawl_time))
conn.commit()
conn.close()
print(f"数据保存成功:{product_name} | 价格:{price} | 时间:{crawl_time}")
# 示例:爬取单个商品并保存数据,可循环或定时执行
if __name__ == '__main__':
# 替换为实际的Temu商品链接
product_url = "https://www.temu.com/product/123456.html"
# 持续采集(可根据需求调整采集间隔,此处为每小时采集一次)
while True:
product_id, product_name, price = get_temu_product_info(product_url)
save_to_db(product_id, product_name, price)
# 休眠1小时(3600秒)
time.sleep(3600)
3. 注意事项:反爬策略应对
Temu 作为电商平台,存在基础的反爬机制,实际开发中需注意以下几点:
- 请求频率控制 :避免短时间内发送大量请求,可设置随机休眠时间(如
<font style="color:rgb(0, 0, 0);">time.sleep(random.randint(5, 10))</font>)。 - 代理 IP 使用 :若出现 IP 被封禁,可结合
<font style="color:rgb(0, 0, 0);">亿牛云隧道代理</font>池,分散请求来源。 - 动态页面处理 :若商品价格通过 JS 动态渲染,可替换为
<font style="color:rgb(0, 0, 0);">Playwright</font>模拟浏览器加载页面,示例代码如下:
python
python
from playwright.sync_api import sync_playwright
def get_dynamic_product_info(product_url):
"""使用Playwright获取动态渲染的商品信息"""
with sync_playwright() as p:
browser = p.chromium.launch(headless=True) # 无头模式运行浏览器
page = browser.new_page()
page.set_extra_http_headers({'User-Agent': UserAgent().random})
page.goto(product_url, wait_until='networkidle') # 等待网络请求完成
# 提取商品名称(根据实际页面选择器调整)
product_name = page.locator('h1.product-title').inner_text().strip()
# 提取商品价格
price_str = page.locator('span.product-price').inner_text().strip().replace('$', '')
price = float(price_str)
product_id = product_url.split('/')[-1].replace('.html', '')
browser.close()
return product_id, product_name, price
三、价格数据趋势分析与可视化
当数据库中积累了一定的历史价格数据后,可利用 pandas 进行数据清洗与分析,并用 matplotlib 绘制价格趋势图。
1. 数据读取与清洗
python
运行
python
import pandas as pd
import matplotlib.pyplot as plt
# 设置中文字体,避免乱码
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def read_price_data(product_id):
"""读取指定商品的历史价格数据"""
conn = sqlite3.connect('temu_price.db')
# 从数据库读取数据并转换为DataFrame
df = pd.read_sql_query(f'''
SELECT product_id, product_name, price, crawl_time
FROM product_price
WHERE product_id = '{product_id}'
ORDER BY crawl_time
''', conn)
conn.close()
# 转换时间格式
df['crawl_time'] = pd.to_datetime(df['crawl_time'])
# 去重(避免重复采集的数据影响分析)
df = df.drop_duplicates(subset=['crawl_time', 'price'])
return df
2. 价格趋势可视化
python
运行
python
def plot_price_trend(df):
"""绘制商品价格趋势图"""
if df.empty:
print("无数据可绘制")
return
product_name = df['product_name'].iloc[0]
plt.figure(figsize=(12, 6))
plt.plot(df['crawl_time'], df['price'], marker='o', linestyle='-', color='#ff6700')
plt.title(f'{product_name} 价格趋势图', fontsize=16)
plt.xlabel('采集时间', fontsize=12)
plt.ylabel('价格(元/美元)', fontsize=12)
plt.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig(f'{df["product_id"].iloc[0]}_price_trend.png')
plt.show()
# 示例:分析指定商品的价格趋势
if __name__ == '__main__':
product_id = "123456" # 替换为实际的商品ID
df = read_price_data(product_id)
plot_price_trend(df)
四、总结与扩展方向
本文通过 Python 实现了 Temu 商品历史价格爬虫的核心功能,并完成了数据的存储、分析与可视化。从技术层面来看,该爬虫的核心在于应对平台的反爬机制与数据解析,而数据价值则体现在后续的趋势分析中。
在实际应用中,可从以下方向扩展:
- 分布式爬虫:结合 Scrapy-Redis 实现多节点分布式采集,提升数据采集效率;
- 数据深度分析:加入价格波动幅度计算、促销活动关联分析,挖掘价格变化的规律;
- 告警功能:设置价格阈值,当商品价格低于阈值时发送邮件或短信告警,辅助消费决策;
- 多平台适配:扩展爬虫至亚马逊、淘宝等电商平台,实现跨平台价格对比。