你需要准备以下两样东西:一台安装了Python的电脑,以及一个可以正常访问京东的浏览器。
首先安装必要的Python库。打开命令行(Windows的CMD或PowerShell,Mac/Linux的终端),执行以下命令:
pip install requests beautifulsoup4 pandas selenium webdriver-manager
这条命令会安装四个核心库:requests用于发送网络请求,beautifulsoup4用于解析网页,pandas用于数据处理,selenium和webdriver-manager用于自动化控制浏览器获取动态加载的数据。
京东的“爆款”商品通常出现在特定频道页。我们以“家用电器爆款”列表为例,其URL模式固定。打开浏览器,访问以下地址,你将看到目标页面:
https://list.jd.com/list.html?cat=737,738,751&ev=4155_76344&sort=sort_totalsales15_desc
这个链接的关键参数是ev=4155_76344(代表“爆款”筛选)和sort=sort_totalsales15_desc(按15日销量降序排列)。你可以通过修改cat参数的值来更换品类。
对于商品列表、价格等初始信息,使用requests库直接抓取效率更高。创建一个名为jd_spider.py的Python文件,输入以下代码:
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
def fetch_goods_list(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
response.encoding = 'utf-8'
return response.text
except requests.RequestException as e:
print(f"请求失败: {e}")
return None
def parse_list_page(html):
soup = BeautifulSoup(html, 'html.parser')
items = soup.find_all('div', class_='gl-i-wrap')
goods_list = []
for item in items:
try:
sku_id = item.get('data-sku')
title_elem = item.find('div', class_='p-name').find('em')
title = title_elem.text.strip() if title_elem else 'N/A'
price_elem = item.find('div', class_='p-price').find('strong')
price = price_elem.text.strip() if price_elem else 'N/A'
goods_list.append({
'商品ID': sku_id,
'商品标题': title,
'价格': price
})
except AttributeError:
continue
return goods_list
if __name__ == '__main__':
list_url = "https://list.jd.com/list.html?cat=737,738,751&ev=4155_76344&sort=sort_totalsales15_desc"
html = fetch_goods_list(list_url)
if html:
data = parse_list_page(html)
df = pd.DataFrame(data)
df.to_excel('京东爆款列表.xlsx', index=False)
print(f"成功抓取 {len(data)} 条商品列表数据,已保存至'京东爆款列表.xlsx'。")
运行此脚本,即可在同目录下生成一个包含商品ID、标题和价格的Excel文件。这里的关键是正确匹配HTML元素的class名,如果京东页面结构更新导致抓取失败,你需要用浏览器开发者工具(F12)重新检查元素选择器。

商品详细销量和评价数据通常通过JavaScript动态加载,无法直接用requests获取。此时需要使用Selenium自动化浏览器。在jd_spider.py文件中追加以下函数:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def fetch_detail_with_selenium(sku_id):
"""使用Selenium获取单个商品详情页的销量和评价数"""
自动管理ChromeDriver
service = Service(ChromeDriverManager().install())
options = webdriver.ChromeOptions()
options.add_argument('--headless') 无头模式,不显示浏览器窗口
driver = webdriver.Chrome(service=service, options=options)
detail_url = f"https://item.jd.com/{sku_id}.html"
driver.get(detail_url)
detail_data = {'商品ID': sku_id, '累计评价': 'N/A', '销量文案': 'N/A'}
try:
等待评价元素加载
wait = WebDriverWait(driver, 10)
comment_elem = wait.until(
EC.presence_of_element_located((By.ID, "comment-count"))
)
detail_data['累计评价'] = comment_elem.text
尝试查找销量相关元素(位置可能变化)
sales_elements = driver.find_elements(By.CSS_SELECTOR, ".sellNum")
if sales_elements:
detail_data['销量文案'] = sales_elements[0].text
except Exception as e:
print(f"获取商品{sku_id}详情时出错: {e}")
finally:
driver.quit()
return detail_data
def enrich_goods_data(goods_list):
""" enrich goods data with sales and comment info """
enriched_list = []
for goods in goods_list[:5]: 演示用,只处理前5个商品,避免请求过多
print(f"正在处理商品: {goods['商品ID']}")
detail = fetch_detail_with_selenium(goods['商品ID'])
merged_data = {goods, detail}
enriched_list.append(merged_data)
time.sleep(2) 礼貌性延迟,避免给服务器带来压力
return enriched_list
修改主函数部分,将抓取的列表数据与详情数据合并:
if __name__ == '__main__':
list_url = "https://list.jd.com/list.html?cat=737,738,751&ev=4155_76344&sort=sort_totalsales15_desc"
html = fetch_goods_list(list_url)
if html:
basic_list = parse_list_page(html)
为前5个商品获取详情数据
final_list = enrich_goods_data(basic_list[:5])
df = pd.DataFrame(final_list)
df.to_excel('京东爆款详情数据.xlsx', index=False)
print("数据抓取与增强完成,已保存至'京东爆款详情数据.xlsx'。")
注意:Selenium脚本中加入了time.sleep(2),这是必要的请求间隔,请勿移除,以免触发反爬机制。
抓取到的原始数据(尤其是价格和销量文本)可能包含“¥”、“人评价”等字符,需要清洗。在同一目录下创建新的Python文件data_analysis.py:
import pandas as pd
import re
def clean_data(df):
"""清洗价格和评价数字"""
df_clean = df.copy()
清洗价格:提取数字
if '价格' in df_clean.columns:
df_clean['价格_数值'] = df_clean['价格'].apply(
lambda x: float(re.findall(r'\d+\.?\d', str(x))[0]) if re.findall(r'\d+\.?\d', str(x)) else None
)
清洗评价:提取数字
if '累计评价' in df_clean.columns:
df_clean['评价数_数值'] = df_clean['累计评价'].apply(
lambda x: int(re.findall(r'\d+', str(x).replace(',', ''))[0]) if re.findall(r'\d+', str(x)) else None
)
return df_clean
def basic_analysis(df):
"""执行基础分析并输出结果"""
print("=== 爆款商品基础分析报告 ===")
if '价格_数值' in df.columns:
print(f"1. 平均价格: ¥{df['价格_数值'].mean():.2f}")
print(f"2. 最高价格: ¥{df['价格_数值'].max():.2f} (商品: {df.loc[df['价格_数值'].idxmax(), '商品标题'][:30]}...)")
print(f"3. 最低价格: ¥{df['价格_数值'].min():.2f} (商品: {df.loc[df['价格_数值'].idxmin(), '商品标题'][:30]}...)")
if '评价数_数值' in df.columns:
print(f"4. 平均评价数: {df['评价数_数值'].mean():.0f}")
print(f"5. 最热门商品(按评价): {df.loc[df['评价数_数值'].idxmax(), '商品标题'][:50]}...")
计算性价比粗略指数 (评价数/价格)
if all(col in df.columns for col in ['评价数_数值', '价格_数值']):
df['性价比指数'] = df['评价数_数值'] / df['价格_数值']
top_value = df.nlargest(3, '性价比指数')[['商品标题', '价格_数值', '评价数_数值', '性价比指数']]
print("6. 性价比Top3 (评价数/价格):")
print(top_value.to_string(index=False))
if __name__ == '__main__':
读取之前抓取的数据
df_raw = pd.read_excel('京东爆款详情数据.xlsx')
df_cleaned = clean_data(df_raw)
保存清洗后的数据
df_cleaned.to_excel('清洗后的爆款数据.xlsx', index=False)
执行分析
basic_analysis(df_cleaned)
运行此脚本,控制台将输出基础分析报告,并生成一个清洗后的、包含数值型字段的新Excel文件。
将以上步骤整合,并加入日志和异常处理,形成一个健壮的自动化脚本。创建auto_run.py:
import logging
import traceback
from jd_spider import fetch_goods_list, parse_list_page, enrich_goods_data
from data_analysis import clean_data, basic_analysis
import pandas as pd
配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('jd_crawler.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
def main():
list_url = "https://list.jd.com/list.html?cat=737,738,751&ev=4155_76344&sort=sort_totalsales15_desc"
try:
logger.info("开始抓取商品列表...")
html = fetch_goods_list(list_url)
if not html:
raise Exception("获取列表页HTML失败")
basic_list = parse_list_page(html)
logger.info(f"成功解析到 {len(basic_list)} 个基础商品信息。")
logger.info("开始抓取商品详情(销量/评价)...")
生产环境建议控制数量或分批次进行
final_list = enrich_goods_data(basic_list[:10]) 本次抓取前10个
df_raw = pd.DataFrame(final_list)
df_raw.to_excel('raw_data.xlsx', index=False)
logger.info("原始数据已保存至 raw_data.xlsx")
logger.info("开始数据清洗与分析...")
df_clean = clean_data(df_raw)
df_clean.to_excel('cleaned_data.xlsx', index=False)
basic_analysis(df_clean)
logger.info("自动化任务执行完毕。")
except Exception as e:
logger.error(f"主流程执行出错: {e}")
logger.error(traceback.format_exc())
if __name__ == '__main__':
main()
运行auto_run.py,它将按顺序执行抓取、解析、增强、清洗、分析的全流程,并将日志输出到控制台和jd_crawler.log文件中。如果中途出错,日志会记录详细的错误信息,方便你定位问题。
至此,你已经拥有了一套从定位、抓取、解析到分析京东爆款商品数据的完整可执行代码。通过修改URL中的品类参数和调整抓取数量,你可以将此方案快速应用到其他品类的分析中。
易频IT社区是综合性互联网IT技术门户网站,专注分享网络技术、服务器运维、网络安全、编程开发、系统架构、云计算、大数据等行业干货,实时更新IT行业资讯、零基础教程、实战案例,为IT从业者、技术爱好者提供专业的学习交流平台。
Copyright © 2021-2026 易频IT社区. All Rights Reserved. 备案号:闽ICP备2023013482号 网站地图