考虑到大家期末课程作业或毕业设计等需要数据作为支撑,或者需要提交代码编程作业。本系列分别用三篇文章:京东、淘宝、拼多多数据爬取来讲述数据爬取过程,即便是python入门级小白也能掌握。本篇文章为京东爬取教程。
%pip install DrissionPage pandas openpyxl
# 爬虫库,使用谷歌模拟器
from DrissionPage import ChromiumPage
import time # 日期
import re # 正则
import pandas as pd # 办公操作库
from datetime import datetime # 时间库
在安装和导入完依赖库后,我们需要初始化浏览器并访问京东网站。
# 实例化浏览器对象
cp = ChromiumPage()
这行代码创建了一个
ChromiumPage 对象,它会自动启动一个 Chrome 浏览器窗口。DrissionPage 的优势在于它能够像真实用户一样操作浏览器,可以有效避免被网站识别为爬虫。
注意事项:
首次运行时,DrissionPage 会自动下载 Chrome 浏览器驱动确保你的电脑已安装 Chrome 浏览器浏览器窗口会实际打开,你可以看到整个操作过程
# 访问京东首页
cp.get('https://www.jd.com/')
使用
get() 方法访问京东首页,浏览器会像普通用户一样打开这个网址。

接下来我们要模拟真实用户在京东上搜索商品的操作。
注意:按F12打开谷歌dev调试工具选中元素


# 模拟搜索操作
cp.ele('xpath://*[@id="key"]').input('电脑')
这行代码做了两件事:
定位搜索框:使用 XPath 表达式
xpath://*[@id="key"] 找到京东首页的搜索框(id="key")输入关键词:使用
input() 方法输入搜索词"电脑"
XPath 小贴士:
XPath 是一种在网页中定位元素的语言
[@id="key"] 表示查找 id 属性为 "key" 的元素你可以把 "电脑" 改成任何你想搜索的商品关键词

cp.ele('css:.button').click()
使用 CSS 选择器
css:.button 定位搜索按钮并点击。
.button 表示查找 class 为 "button" 的元素。
cp.wait.load_start()
cp.wait.load_start()
time.sleep(2)
这段代码确保页面完全加载后再进行下一步操作:
wait.load_start():等待页面开始加载(调用两次是为了确保稳定性)
time.sleep(2):额外等待 2 秒,确保动态内容完全渲染
为什么需要等待?
现代网页大多是动态加载的如果不等待,可能抓取不到完整数据这也让我们的行为更像真实用户搜索结果页面加载完成后,我们开始抓取商品信息。

# 抓取商品信息
items = cp.eles('css:._info_8v3rv_44')
print(f"找到 {len(items)} 个商品")
eles() 方法(注意有 s)会返回所有匹配的元素列表
css:._info_8v3rv_44 是京东商品卡片的 CSS 类名打印出找到的商品数量,方便我们确认抓取是否成功
# 创建空列表存储商品数据
products_data = []
创建一个空列表,用于存储每个商品的信息字典,最后会转换成 Excel 文件。
现在进入核心环节:遍历每个商品,提取我们需要的信息。
for i, item in enumerate(items, 1):
使用
enumerate() 函数遍历商品列表,
i 是序号(从 1 开始),
item 是每个商品元素。

# 商品标题
title_elem = item.ele('css:._goods_title_container_1g56m_1')
title = title_elem.text if title_elem else "未找到标题"
在当前商品元素内查找标题元素使用
.text 获取文本内容如果找不到元素,返回默认值"未找到标题"(容错处理)
# 价格信息
price_elem = item.ele('css:._price_uqsva_14')
price_text = price_elem.text if price_elem else "未找到价格"
# 提取纯数字价格
price_match = re.search(r'[d.,]+', price_text)
price = price_match.group() if price_match else price_text
价格提取分两步:
获取原始文本:可能包含"¥"符号或其他文字正则表达式提取数字:
r'[d.,]+' 匹配数字、逗号和小数点
d 匹配数字
. 匹配小数点
, 匹配千位分隔符
+ 表示匹配一个或多个
# 原价信息
original_price_elem = item.ele('css:._gray_uqsva_61')
original_price_text = original_price_elem.text if original_price_elem else "无原价信息"
# 提取纯数字原价
original_price_match = re.search(r'[d.,]+', original_price_text)
original_price = original_price_match.group() if original_price_match else original_price_text
处理逻辑与价格类似,原价通常是被划掉的价格,用于对比显示优惠力度。
# 销量信息
sales_elem = item.ele('css:._goods_volume_1xkku_1')
sales_text = sales_elem.text if sales_elem else "未找到销量"
# 处理销量文本,将"万+"转换为数字
if "万" in sales_text:
sales_match = re.search(r'[d.]+', sales_text)
if sales_match:
sales = str(float(sales_match.group()) * 10000)
else:
sales = sales_text
else:
sales_match = re.search(r'[d.,]+', sales_text)
sales = sales_match.group() if sales_match else sales_text
销量处理较为复杂,因为京东显示销量时可能用"5.6万+"这样的格式:
检查是否包含"万":判断销量是否是万为单位提取数字并转换:如"5.6万"转换为 56000普通销量直接提取:如"1234"直接保留
# 店铺信息
shop_elem = item.ele('css:._name_d19t5_35')
shop = shop_elem.text if shop_elem else "未找到店铺"
直接提取店铺名称文本。
# 促销标签
tags_elems = item.eles('css:._textTag_1qbwk_10')
tags = [tag.text for tag in tags_elems] if tags_elems else []
tags_str = ", ".join(tags) if tags else "无促销信息"
促销标签可能有多个(如"秒杀"、"满减"等):
获取所有标签元素:使用
eles() 获取多个元素提取文本列表:用列表推导式提取每个标签的文本合并为字符串:用逗号连接所有标签,方便存储到 Excel
# 打印到控制台
print(f"{i}. {title}")
print(f" 价格: {price} | 原价: {original_price}")
print(f" 销量: {sales} | 店铺: {shop}")
print(f" 促销: {tags_str}")
print("-" * 80)
在控制台实时输出商品信息,方便我们观察爬取过程和调试。
# 将商品数据添加到列表
product_info = {
"序号": i,
"商品标题": title,
"当前价格": price,
"原价": original_price,
"销量": sales,
"店铺名称": shop,
"促销信息": tags_str
}
products_data.append(product_info)
将每个商品的信息组织成字典,添加到
products_data 列表中。
# 导出为Excel文件
if products_data:
# 创建DataFrame
df = pd.DataFrame(products_data)
使用 pandas 的
DataFrame 将数据列表转换为表格结构。
# 生成文件名(包含时间戳)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"jd_goods_data_{timestamp}.xlsx"
获取当前时间并格式化:如
20241102_143025生成唯一文件名,避免覆盖之前的数据
# 导出为Excel
df.to_excel(filename, index=False, engine='openpyxl')
print(f"
数据已导出到: {filename}")
index=False:不导出行索引
engine='openpyxl':指定 Excel 引擎文件会保存在代码运行的当前目录
# 关闭浏览器
cp.quit()
爬取完成后关闭浏览器,释放资源。
from DrissionPage import ChromiumPage
import time
import re
import pandas as pd
from datetime import datetime
def jd_product_crawler(keyword, max_products=20):
"""
京东商品爬虫函数
参数:
keyword: 搜索关键词
max_products: 最大爬取商品数量,默认20个
返回:
导出的Excel文件名
"""
# 实例化浏览器对象
cp = ChromiumPage()
try:
# 访问京东首页
cp.get('https://www.jd.com/')
# 模拟搜索操作
search_input = cp.ele('xpath://*[@id="key"]')
if search_input:
search_input.input(keyword)
else:
print("未找到搜索框,尝试备用选择器")
search_input = cp.ele('css:#key')
if search_input:
search_input.input(keyword)
else:
print("无法找到搜索框,退出")
return None
# 点击搜索按钮
search_btn = cp.ele('css:.button')
if search_btn:
search_btn.click()
else:
print("未找到搜索按钮,尝试备用选择器")
search_btn = cp.ele('css:.button_c2T4I')
if search_btn:
search_btn.click()
else:
print("无法找到搜索按钮,退出")
return None
# 等待页面加载
cp.wait.load_start()
time.sleep(2)
# 抓取商品信息
items = cp.eles('css:._info_8v3rv_44')
if not items:
print("未找到商品信息,尝试备用选择器")
items = cp.eles('css:.gl-item')
# 限制最大商品数量
items = items[:max_products]
print(f"找到 {len(items)} 个商品")
# 创建空列表存储商品数据
products_data = []
for i, item in enumerate(items, 1):
try:
# 商品标题
title_elem = item.ele('css:._goods_title_container_1g56m_1')
if not title_elem:
title_elem = item.ele('css:.p-name a')
title = title_elem.text if title_elem else "未找到标题"
# 价格信息
price_elem = item.ele('css:._price_uqsva_14')
if not price_elem:
price_elem = item.ele('css:.p-price')
price_text = price_elem.text if price_elem else "未找到价格"
# 提取纯数字价格
price_match = re.search(r'[d.,]+', price_text)
price = price_match.group() if price_match else price_text
# 原价信息
original_price_elem = item.ele('css:._gray_uqsva_61')
if not original_price_elem:
original_price_elem = item.ele('css:.p-price del')
original_price_text = original_price_elem.text if original_price_elem else "无原价信息"
# 提取纯数字原价
original_price_match = re.search(r'[d.,]+', original_price_text)
original_price = original_price_match.group() if original_price_match else original_price_text
# 销量信息
sales_elem = item.ele('css:._goods_volume_1xkku_1')
if not sales_elem:
sales_elem = item.ele('css:.p-commit strong')
sales_text = sales_elem.text if sales_elem else "未找到销量"
# 处理销量文本,将"万+"转换为数字
if "万" in sales_text:
sales_match = re.search(r'[d.]+', sales_text)
if sales_match:
sales = str(float(sales_match.group()) * 10000)
else:
sales = sales_text
else:
sales_match = re.search(r'[d.,]+', sales_text)
sales = sales_match.group() if sales_match else sales_text
# 店铺信息
shop_elem = item.ele('css:._name_d19t5_35')
if not shop_elem:
shop_elem = item.ele('css:.p-shop a')
shop = shop_elem.text if shop_elem else "未找到店铺"
# 促销标签
tags_elems = item.eles('css:._textTag_1qbwk_10')
if not tags_elems:
tags_elems = item.eles('css:.p-icons i')
tags = [tag.text for tag in tags_elems] if tags_elems else []
tags_str = ", ".join(tags) if tags else "无促销信息"
# 打印到控制台
print(f"{i}. {title}")
print(f" 价格: {price} | 原价: {original_price}")
print(f" 销量: {sales} | 店铺: {shop}")
print(f" 促销: {tags_str}")
print("-" * 80)
# 将商品数据添加到列表
product_info = {
"序号": i,
"商品标题": title,
"当前价格": price,
"原价": original_price,
"销量": sales,
"店铺名称": shop,
"促销信息": tags_str
}
products_data.append(product_info)
except Exception as e:
print(f"处理第 {i} 个商品时出错: {e}")
continue
# 导出为Excel文件
if products_data:
# 创建DataFrame
df = pd.DataFrame(products_data)
# 生成文件名(包含关键词和时间戳)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"京东_{keyword}_商品数据_{timestamp}.xlsx"
# 导出为Excel
df.to_excel(filename, index=False, engine='openpyxl')
print(f"
数据已导出到: {filename}")
return filename
else:
print("未找到任何商品数据,无法导出Excel文件")
return None
except Exception as e:
print(f"爬取过程中出错: {e}")
return None
finally:
# 关闭浏览器
try:
cp.quit()
except:
pass
# 使用示例
if __name__ == "__main__":
# 只需输入关键词即可爬取
keyword = input("请输入要搜索的商品关键词: ")
result_file = jd_product_crawler(keyword)
if result_file:
print(f"爬取完成,数据已保存到: {result_file}")
else:
print("爬取失败,请检查网络连接或关键词是否正确")
# 爬取"电脑"相关的商品
result_file = jd_product_crawler("电脑")
# 爬取"手机"相关的商品,最多30个
result_file = jd_product_crawler("手机", max_products=30)
