Python爬取京东商品数据保姆级教程(附源码及效果图)

  • 时间:2025-11-10 17:45 作者: 来源: 阅读:0
  • 扫一扫,手机访问
摘要:前言 考虑到大家期末课程作业或毕业设计等需要数据作为支撑,或者需要提交代码编程作业。本系列分别用三篇文章:京东、淘宝、拼多多数据爬取来讲述数据爬取过程,即便是python入门级小白也能掌握。本篇文章为京东爬取教程。 一、安装&导入依赖库 (1)安装库 %pip install DrissionPage pandas openpyxl (2)导入依赖 # 爬虫

前言

考虑到大家期末课程作业或毕业设计等需要数据作为支撑,或者需要提交代码编程作业。本系列分别用三篇文章:京东、淘宝、拼多多数据爬取来讲述数据爬取过程,即便是python入门级小白也能掌握。本篇文章为京东爬取教程。

一、安装&导入依赖库

(1)安装库


%pip install DrissionPage pandas openpyxl

(2)导入依赖



# 爬虫库,使用谷歌模拟器
from DrissionPage import ChromiumPage
import time # 日期
import re # 正则
import pandas as pd # 办公操作库
from datetime import datetime # 时间库

二、初始化浏览器并访问京东

在安装和导入完依赖库后,我们需要初始化浏览器并访问京东网站。

2.1 创建浏览器实例



# 实例化浏览器对象
cp = ChromiumPage()

这行代码创建了一个 ChromiumPage 对象,它会自动启动一个 Chrome 浏览器窗口。DrissionPage 的优势在于它能够像真实用户一样操作浏览器,可以有效避免被网站识别为爬虫。

注意事项:

首次运行时,DrissionPage 会自动下载 Chrome 浏览器驱动确保你的电脑已安装 Chrome 浏览器浏览器窗口会实际打开,你可以看到整个操作过程

2.2 访问京东首页



# 访问京东首页
cp.get('https://www.jd.com/')

使用 get() 方法访问京东首页,浏览器会像普通用户一样打开这个网址。


三、模拟用户搜索操作

接下来我们要模拟真实用户在京东上搜索商品的操作。

注意:按F12打开谷歌dev调试工具选中元素

3.1 定位搜索框并输入关键词



# 模拟搜索操作
cp.ele('xpath://*[@id="key"]').input('电脑')

这行代码做了两件事:

定位搜索框:使用 XPath 表达式 xpath://*[@id="key"] 找到京东首页的搜索框(id="key")输入关键词:使用 input() 方法输入搜索词"电脑"

XPath 小贴士:

XPath 是一种在网页中定位元素的语言 [@id="key"] 表示查找 id 属性为 "key" 的元素你可以把 "电脑" 改成任何你想搜索的商品关键词

3.2 点击搜索按钮


cp.ele('css:.button').click()

使用 CSS 选择器 css:.button 定位搜索按钮并点击。 .button 表示查找 class 为 "button" 的元素。

3.3 等待页面加载



cp.wait.load_start()
cp.wait.load_start()
time.sleep(2)

这段代码确保页面完全加载后再进行下一步操作:

wait.load_start():等待页面开始加载(调用两次是为了确保稳定性) time.sleep(2):额外等待 2 秒,确保动态内容完全渲染

为什么需要等待?

现代网页大多是动态加载的如果不等待,可能抓取不到完整数据这也让我们的行为更像真实用户

四、抓取商品列表

搜索结果页面加载完成后,我们开始抓取商品信息。

4.1 获取所有商品元素



# 抓取商品信息
items = cp.eles('css:._info_8v3rv_44')
print(f"找到 {len(items)} 个商品")
eles() 方法(注意有 s)会返回所有匹配的元素列表 css:._info_8v3rv_44 是京东商品卡片的 CSS 类名打印出找到的商品数量,方便我们确认抓取是否成功

4.2 创建数据存储列表



# 创建空列表存储商品数据
products_data = []

创建一个空列表,用于存储每个商品的信息字典,最后会转换成 Excel 文件。


五、解析商品详细信息

现在进入核心环节:遍历每个商品,提取我们需要的信息。

5.1 遍历商品列表


for i, item in enumerate(items, 1):

使用 enumerate() 函数遍历商品列表, i 是序号(从 1 开始), item 是每个商品元素。

5.2 提取商品标题



    # 商品标题
    title_elem = item.ele('css:._goods_title_container_1g56m_1')
    title = title_elem.text if title_elem else "未找到标题"
在当前商品元素内查找标题元素使用 .text 获取文本内容如果找不到元素,返回默认值"未找到标题"(容错处理)

5.3 提取价格信息



    # 价格信息
    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 匹配数字 . 匹配小数点 , 匹配千位分隔符 + 表示匹配一个或多个

5.4 提取原价信息



    # 原价信息
    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

处理逻辑与价格类似,原价通常是被划掉的价格,用于对比显示优惠力度。

5.5 提取并处理销量信息



    # 销量信息
    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"直接保留

5.6 提取店铺信息



    # 店铺信息
    shop_elem = item.ele('css:._name_d19t5_35')
    shop = shop_elem.text if shop_elem else "未找到店铺"

直接提取店铺名称文本。

5.7 提取促销标签



    # 促销标签
    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

六、输出与存储数据

6.1 控制台输出



    # 打印到控制台
    print(f"{i}. {title}")
    print(f"   价格: {price} | 原价: {original_price}")
    print(f"   销量: {sales} | 店铺: {shop}")
    print(f"   促销: {tags_str}")
    print("-" * 80)

在控制台实时输出商品信息,方便我们观察爬取过程和调试。

6.2 构建数据字典



    # 将商品数据添加到列表
    product_info = {
        "序号": i,
        "商品标题": title,
        "当前价格": price,
        "原价": original_price,
        "销量": sales,
        "店铺名称": shop,
        "促销信息": tags_str
    }
    products_data.append(product_info)

将每个商品的信息组织成字典,添加到 products_data 列表中。


七、导出为 Excel 文件

7.1 创建 DataFrame



# 导出为Excel文件
if products_data:
    # 创建DataFrame
    df = pd.DataFrame(products_data)

使用 pandas 的 DataFrame 将数据列表转换为表格结构。

7.2 生成带时间戳的文件名



    # 生成文件名(包含时间戳)
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"jd_goods_data_{timestamp}.xlsx"
获取当前时间并格式化:如 20241102_143025生成唯一文件名,避免覆盖之前的数据

7.3 导出 Excel



    # 导出为Excel
    df.to_excel(filename, index=False, engine='openpyxl')
    print(f"
数据已导出到: {filename}")
index=False:不导出行索引 engine='openpyxl':指定 Excel 引擎文件会保存在代码运行的当前目录

7.4 关闭浏览器



# 关闭浏览器
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)

运行效果

  • 全部评论(0)
手机二维码手机访问领取大礼包
返回顶部