京东关键词搜索商品列表的Python爬虫实战

京东关键词搜索商品列表 Python 爬虫实战

你想要实现京东关键词搜索商品的爬虫,我会从合规声明、环境准备、页面分析、代码实现、反爬优化五个方面展开,帮助你完成实战项目。

一、前置声明(重要!)

  1. 京东拥有商品数据的版权,爬虫仅可用于个人学习、研究,禁止用于商业用途、批量爬取造成京东服务器压力。
  2. 遵守京东《用户协议》和robots.txt协议(京东https://www.jd.com/robots.txt明确限制了部分爬虫行为)。
  3. 本实战仅演示基础爬虫思路,爬取频率极低,避免对平台造成影响。

二、环境准备

需要安装 3 个核心 Python 库,打开终端执行以下命令:

bash

运行

复制代码
pip install requests beautifulsoup4 fake-useragent
  • requests:发送 HTTP 网络请求,获取页面数据。
  • beautifulsoup4:解析 HTML 页面,提取目标商品信息。
  • fake-useragent:生成随机 User-Agent,规避简单的反爬检测。

三、京东搜索页面分析

  1. 搜索 URL 构造 :打开京东官网,搜索关键词(例如 "Python 书籍"),观察浏览器地址栏,得到搜索 URL 格式:

    plaintext

    复制代码
    https://search.jd.com/Search?keyword=关键词&enc=utf8&page=页码
    • keyword:需要搜索的商品关键词(需 URL 编码,requests会自动处理)。
    • page:商品列表页码(京东每页展示 60 件商品,页码为 1、3、5... 奇数递增,对应第 1、2、3... 页)。
  2. 商品标签定位 :京东商品列表的核心 HTML 标签为 <li class="gl-item">,每个该标签对应一件商品,包含商品 ID、名称、价格、链接、店铺等信息。

  3. 价格特殊说明 :京东商品价格采用动态加载(JS 渲染),直接爬取静态 HTML 无法获取准确价格,需单独请求价格接口或后续通过 JS 解析补充,本实战先提取静态页面可获取的核心信息,再补充价格接口优化方案。

四、完整代码实现(基础版)

版本 1:基础爬虫(提取商品核心信息)

实现功能:指定关键词,爬取第 1 页商品的商品 ID、商品名称、商品链接、店铺名称(价格后续优化)。

python

运行

复制代码
# 导入所需模块
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
import time

def get_jd_goods(keyword, page=1):
    """
    爬取京东关键词搜索商品列表
    :param keyword: 搜索关键词
    :param page: 页码(默认第1页)
    :return: 商品信息列表
    """
    # 1. 构造请求参数
    url = "https://search.jd.com/Search"
    params = {
        "keyword": keyword,
        "enc": "utf8",
        "page": page,  # 京东页码为奇数,1=第1页,3=第2页,以此类推
        "wq": keyword  # 补充参数,提高请求成功率
    }
    
    # 2. 构造请求头(规避简单反爬)
    ua = UserAgent()
    headers = {
        "User-Agent": ua.random,  # 随机生成User-Agent
        "Referer": "https://www.jd.com/",  # 来源页,模拟浏览器跳转
        "Accept-Language": "zh-CN,zh;q=0.9",  # 接受语言
        "Connection": "keep-alive"
    }
    
    try:
        # 3. 发送GET请求(设置超时,避免卡死;禁止重定向,提高效率)
        response = requests.get(
            url=url,
            params=params,
            headers=headers,
            timeout=15,
            allow_redirects=False
        )
        response.raise_for_status()  # 若请求状态码不是200,抛出异常
        response.encoding = "utf-8"  # 指定编码,避免中文乱码
        
        # 4. 解析HTML页面,提取商品信息
        soup = BeautifulSoup(response.text, "lxml")  # lxml解析器,高效快速
        goods_list = []  # 存储最终商品信息
        
        # 定位所有商品标签 <li class="gl-item">
        goods_items = soup.find_all("li", class_="gl-item")
        
        for item in goods_items:
            # 提取商品ID
            goods_id = item.get("data-sku", "未知ID")
            
            # 提取商品名称
            goods_name_tag = item.find("div", class_="p-name").find("em")
            goods_name = goods_name_tag.get_text(strip=True) if goods_name_tag else "未知名称"
            
            # 提取商品链接
            goods_href_tag = item.find("a", class_="p-img")
            goods_href = "https:" + goods_href_tag.get("href", "") if goods_href_tag else "未知链接"
            
            # 提取店铺名称
            shop_name_tag = item.find("div", class_="p-shop").find("a")
            shop_name = shop_name_tag.get_text(strip=True) if shop_name_tag else "未知店铺"
            
            # 组装商品信息
            goods_info = {
                "商品ID": goods_id,
                "商品名称": goods_name,
                "商品链接": goods_href,
                "店铺名称": shop_name
            }
            goods_list.append(goods_info)
            
            # 打印单条商品信息(实时查看进度)
            print(f"已提取商品:{goods_name[:30]}...")
        
        # 5. 模拟人类操作,添加延时(核心反爬手段之一)
        time.sleep(2)
        
        return goods_list
    
    except requests.exceptions.RequestException as e:
        print(f"请求失败:{e}")
        return []

def save_goods_to_txt(goods_list, keyword):
    """
    将商品信息保存到本地TXT文件
    :param goods_list: 商品信息列表
    :param keyword: 搜索关键词(用于文件名)
    """
    if not goods_list:
        print("无商品信息可保存")
        return
    
    filename = f"京东_{keyword}_商品列表.txt"
    with open(filename, "w", encoding="utf-8") as f:
        f.write(f"京东关键词「{keyword}」商品搜索结果\n")
        f.write("-" * 100 + "\n")
        for index, goods in enumerate(goods_list, 1):
            f.write(f"第{index}件商品\n")
            f.write(f"商品ID:{goods['商品ID']}\n")
            f.write(f"商品名称:{goods['商品名称']}\n")
            f.write(f"商品链接:{goods['商品链接']}\n")
            f.write(f"店铺名称:{goods['店铺名称']}\n")
            f.write("-" * 100 + "\n")
    
    print(f"商品信息已成功保存到:{filename}")

# 主函数调用
if __name__ == "__main__":
    target_keyword = "Python书籍"  # 自定义搜索关键词
    target_page = 1  # 自定义页码(奇数)
    
    # 爬取商品信息
    jd_goods = get_jd_goods(keyword=target_keyword, page=target_page)
    
    # 保存到本地
    if jd_goods:
        save_goods_to_txt(goods_list=jd_goods, keyword=target_keyword)
    else:
        print("未爬取到任何商品信息")

版本 2:优化版(补充准确价格获取)

由于京东静态页面价格为空,需单独请求价格接口获取准确价格,优化后的核心代码如下(仅修改价格提取部分):

python

运行

复制代码
# 新增:获取商品准确价格的函数
def get_goods_price(goods_id):
    """
    调用京东价格接口,获取商品准确价格
    :param goods_id: 商品ID(data-sku)
    :return: 商品价格
    """
    price_url = f"https://p.3.cn/prices/mgets"
    params = {
        "skuIds": f"J_{goods_id}",  # 价格接口需要J_前缀+商品ID
        "type": "1"
    }
    
    headers = {
        "User-Agent": UserAgent().random,
        "Referer": "https://search.jd.com/"
    }
    
    try:
        response = requests.get(price_url, params=params, headers=headers, timeout=10)
        response.raise_for_status()
        price_data = response.json()
        return price_data[0].get("p", "未知价格") if price_data else "未知价格"
    except Exception as e:
        print(f"获取商品{goods_id}价格失败:{e}")
        return "未知价格"

# 修改解析部分,添加价格获取
# 在for item in goods_items: 循环中,添加:
goods_price = get_goods_price(goods_id)
# 然后在goods_info中补充:
"商品价格": f"{goods_price} 元"

五、反爬策略与注意事项

1. 核心反爬应对措施

  • 随机 User-Agent :使用fake-useragent生成不同浏览器的 UA,避免固定 UA 被识别为爬虫。
  • 请求延时 :通过time.sleep(2)添加 2 秒延时,模拟人类浏览节奏,避免高频请求。
  • 完整请求头 :补充RefererAccept-Language等字段,让请求更接近浏览器行为。
  • 避免重定向 :设置allow_redirects=False,防止被京东重定向到验证页面。
  • 分页爬取限制:若需爬取多页,页码递增间隔≥5 秒,且总页数不超过 5 页(仅用于学习)。

2. 常见问题与解决方案

  • 问题 1 :中文乱码。解决方案:指定response.encoding = "utf-8",保存文件时指定encoding="utf-8"
  • 问题 2:返回空商品列表。解决方案:检查页码是否为奇数、请求头是否完整、是否被京东限制(可更换关键词或重启网络)。
  • 问题 3 :价格接口返回空值。解决方案:增加价格接口请求延时、更换 UA,部分商品需登录后才能获取价格(进阶需求可使用requests.Session()保持登录状态)。

六、后续扩展方向

  1. 数据持久化:将商品信息保存到 CSV、Excel 或 MySQL 数据库,方便后续分析。
  2. 多页爬取:实现自动遍历多页(1、3、5...),批量获取商品列表。
  3. 多线程 / 异步爬取 :使用threadingaiohttp提高爬取效率(需严格控制并发量,避免反爬)。
  4. 商品详情页爬取:通过商品链接,进一步爬取商品参数、评价等信息。
  5. 反爬进阶 :处理京东的验证码、Cookie 验证(可使用selenium模拟浏览器,但效率较低,仅用于学习)。

总结

  1. 京东爬虫核心是构造合法请求、定位商品标签、规避反爬检测,基础版可满足个人学习的信息提取需求。
  2. 动态加载的价格需单独请求专用接口,这是电商平台爬虫的常见特点。
  3. 爬虫的核心原则是 "低调"------ 低频率、低并发、非商用,避免触碰平台红线和法律边界。
  4. 本实战的代码可直接运行,修改target_keyword即可爬取不同商品,运行后会在当前目录生成 TXT 格式的商品列表文件。
相关推荐
逻极8 小时前
数据分析项目:Pandas + SQLAlchemy,从数据库到DataFrame的丝滑实战
python·mysql·数据分析·pandas·sqlalchemy
小白学大数据8 小时前
Java 异步爬虫高效获取小红书短视频内容
java·开发语言·爬虫·python·音视频
solar应急响应8 小时前
域控宕机!如何强制夺取五大角色恢复业务?
开发语言·php
数据的世界018 小时前
C# 获评2025年度编程语言-编程语言排行榜2026年1月
开发语言
luoluoal8 小时前
基于python的英汉电子词典软件(源码+文档)
python·mysql·django·毕业设计·源码
我想吃烤肉肉8 小时前
Python 中 asyncio 是什么?
爬虫·python·自动化
2201_757830878 小时前
Bean原理篇
java·开发语言
咕噜签名-铁蛋8 小时前
英伟达旗下
python
草原上唱山歌8 小时前
推荐学习的C++书籍
开发语言·c++·学习
皮肤科大白8 小时前
图像处理的 Python库
图像处理·人工智能·python