Python+AI轻松抓取百度网盘多级文件目录

前言

在现代软件开发中,AI辅助编程已经成为提升开发效率的重要工具。本文将分享一个真实案例:如何利用AI快速完成网页数据抓取任务——百度网盘多级目录树的抓取实践。本文会揭秘python+ai网抓的全流程代码

视频演示

传统开发 vs AI辅助开发

传统开发流程的痛点

在没有AI辅助的情况下,完成一个网页数据抓取项目通常需要:

  1. 1. 分析页面结构:手动查看HTML源码,定位目标元素
  2. 2. 编写选择器:反复测试CSS Selector或XPath表达式
  3. 3. 处理异步加载:分析网络请求,找出数据接口
  4. 4. 调试代码:不断修改代码,处理各种边界情况
  5. 5. 重构优化:整理代码结构,提高可维护性

这个过程往往需要数小时甚至数天时间,尤其是面对复杂的单页应用(SPA)时。

本次实现 基本全部用AI实现 手写参与修改代码不到5行

AI编程带来的革命性改变

使用AI辅助编程,整个流程可以简化为:

  1. 1. 投喂页面数据:将HTML源码直接给AI
  2. 2. 描述需求:用自然语言说明要提取什么数据
  3. 3. 获得代码:AI自动生成提取逻辑(JavaScript)
  4. 4. 转换实现:AI将JS代码转为Python Playwright实现

效率提升:从数小时到几十分钟!

本文对应的直播视频回放 在郑广学python办公自动化课程里已更新

百度网盘多级目录树抓取

项目需求

抓取百度网盘分享链接中的完整目录结构,包括:

  • · 多级文件夹嵌套
  • · 文件名、大小、修改时间
  • · 导出为JSON格式
  • · 以树状结构打印

核心实现思路

1. 文件列表提取

使用Playwright定位页面元素,提取文件信息:

def extract_file_list(page) -> List[Dict[strstr]]:
    """从当前页面提取文件列表信息"""
    page.wait_for_selector("dd.g-clearfix.AuPKyz", timeout=10000)
    file_items = page.query_selector_all("dd.g-clearfix.AuPKyz")
    result = []

    for item in file_items:
        # 提取文件名
        filename_elem = item.query_selector("a.filename")
        filename = filename_elem.get_attribute("title"if filename_elem else "未知文件"

        # 提取大小和时间
        size_elem = item.query_selector(".file-size")
        time_elem = item.query_selector(".ctime")
        size = size_elem.text_content().strip() if size_elem else ""
        time = time_elem.text_content().strip() if time_elem else ""

        # 判断文件类型
        icon_elem = item.query_selector(".JS-fileicon")
        icon_class = icon_elem.get_attribute("class"if icon_elem else ""
        
        file_type = "folder" if "dir-small" in icon_class else "file"
        
        result.append({
            "filename": filename,
            "size": size,
            "time": time,
            "file_type": file_type
        })

    return result

AI编程技巧

  • · 这里的选择器 "dd.g-clearfix.AuPKyz" 是通过AI分析百度网盘页面HTML得到的
  • · 只需要告诉AI:”百度网盘文件列表是如何渲染的”,AI会自动找出最优选择器

2. 递归遍历目录

核心算法:递归构建目录树

def build_directory_tree(page, base_url: str, current_path: str = "/"
                        parent_path: str = ""
) -> List[Dict]:
    """递归构建目录树"""
    print(f"🔍 正在处理目录: {current_path}")

    # 构造新URL(URL编码)
    new_url = f"{base_url}#list/path={requote(current_path)}&parentPath=%2F"
    page.goto(new_url)

    # 获取当前目录下的所有项
    items = extract_file_list(page)

    result = []
    for item in items:
        # 构建完整路径
        full_path = (parent_path + item["filename"]).rstrip("/")
        if item["file_type"] == "folder":
            full_path += "/"
        
        item_with_path = item.copy()
        item_with_path["full_path"] = full_path
        result.append(item_with_path)

        # 如果是文件夹,递归进入
        if item["file_type"] == "folder":
            sub_items = build_directory_tree(
                page, base_url,
                current_path + item["filename"] + "/",
                full_path
            )
            result.extend(sub_items)

    return result

设计亮点

  • · 通过修改URL的 path 参数实现目录切换
  • · 递归深度优先遍历所有子目录
  • · 记录完整路径,便于后续数据处理

3. 数据结构转换

将平铺的列表转换为嵌套字典:

def convert_tree_to_dict(tree: List[Dict]) -> Dict:
    """将目录树列表转换为多级字典形式"""
    root = {}
    
    for item in tree:
        path_parts = [p for p in item["full_path"].split("/"if p]
        current_level = root
        
        # 遍历路径的每一级
        for i, part in enumerate(path_parts):
            if i == len(path_parts) - 1:  # 最后一级
                if item["file_type"] == "folder":
                    if part not in current_level:
                        current_level[part] = {}
                else:
                    current_level[part] = {
                        "type""file",
                        "size": item["size"],
                        "time": item["time"]
                    }
            else:  # 中间路径
                if part not in current_level:
                    current_level[part] = {}
                current_level = current_level[part]
    
    return root

4. 可视化输出

树状结构打印:

def print_directory_tree(dictionary: Dict, indent: int = 0) -> None:
    """以多层目录树样式打印"""
    for key, value in dictionary.items():
        # 判断是文件夹还是文件
        is_folder = isinstance(value, dictand not all(
            k in ["type""size""time"for k in value.keys()
        )
        icon = "📁" if is_folder else "📄"
        print("  " * indent + icon + " " + key)
python+ai轻松抓取百度网盘多级文件目录
        
        # 递归打印子目录
        if is_folder:
            print_directory_tree(value, indent + 1)

主程序整合

def 抓取百度网盘文件目录树(share_url):
    """爬取百度网盘目录树的主函数"""
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.goto(share_url)
        
        # 获取基础URL
        base_url = share_url.split('#')[0]

        # 开始递归构建目录树
        tree = build_directory_tree(page, base_url)

        # 转换为字典形式
        tree_dict = convert_tree_to_dict(tree)
        
        # 打印树状结构
        print("n🌳 多级字典形式的目录树:")
        print_directory_tree(tree_dict)

        # 保存为JSON文件
        with open("directory_tree.json""w", encoding="utf-8"as f:
            json.dump(tree_dict, f, ensure_ascii=False, indent=2)
        print("n✅ 目录树已保存到 directory_tree.json")

        browser.close()
        return tree_dict

if __name__ == "__main__":
    share_url = "https://pan.baidu.com/s/1H_iu_2sPcvRMdPyXnxXs3w?pwd=e7vv"
    抓取百度网盘文件目录树(share_url)

AI编程的最佳实践

1. 精准的需求描述

❌ 不好的提问

帮我写一个爬虫

✅ 好的提问

使用Python Playwright抓取百度网盘分享链接的文件列表,需要:
1. 递归遍历所有子文件夹
2. 提取文件名、大小、修改时间
3. 输出为JSON格式
4. 处理中文文件名的URL编码

2. 分步骤实现

将复杂任务拆解:

  1. 1. 第一步:只提取单层目录
  2. 2. 第二步:添加递归逻辑
  3. 3. 第三步:优化数据结构
  4. 4. 第四步:添加可视化功能

每一步都让AI生成代码,逐步验证。

3. 提供上下文

给AI提供足够的信息:

我已经有了提取单层目录的代码(附上代码),现在需要递归遍历子文件夹。
百度网盘通过修改URL的hash参数来切换目录,格式为:
#list/path=/文件夹名/&parentPath=%2F

请帮我实现递归遍历逻辑。

4. 迭代优化

第一版代码可能不完美,继续向AI提问:

这段代码有以下问题:
1. 中文路径没有正确编码
2. 空文件夹判断逻辑有误
3. 递归深度可能过大导致栈溢出

请帮我优化

关键技术点总结

1. Playwright选择器策略

# 等待元素加载
page.wait_for_selector("dd.g-clearfix.AuPKyz", timeout=10000)

# 批量查询
items = page.query_selector_all("dd.g-clearfix.AuPKyz")

# 属性提取
title = elem.get_attribute("title")
text = elem.text_content().strip()

2. URL参数处理

from urllib.parse import quote, unquote

def requote(path: str) -> str:
    """对路径进行URL编码"""
    return quote(path, safe='/')  # / 不编码

3. 递归算法设计

def recursive_crawl(current_path):
    items = get_items(current_path)
    for item in items:
        if is_folder(item):
            # 递归调用
            recursive_crawl(current_path + item.name)

4. 数据结构优化

# 列表形式(易于遍历)
tree_list = [
    {"full_path""/folder1/file1.txt""size""1MB"},
    {"full_path""/folder1/file2.txt""size""2MB"}
]

# 字典形式(易于查询和展示)
tree_dict = {
    "folder1": {
        "file1.txt": {"type""file""size""1MB"},
        "file2.txt": {"type""file""size""2MB"}
    }
}

常见问题与解决方案

问题1:选择器失效

原因:页面结构动态变化,元素延迟加载

解决

# 使用wait_for_selector确保元素加载完成
page.wait_for_selector("目标选择器", timeout=10000)

# 或者等待网络空闲
page.wait_for_load_state("networkidle")

问题2:中文路径乱码

原因:URL编码问题

解决

from urllib.parse import quote
encoded_path = quote(path, safe='/')

扩展应用场景

这套AI辅助开发的方法论可以应用于:

  1. 1. 电商数据采集:商品信息、价格监控
  2. 2. 社交媒体分析:微博、知乎内容抓取
  3. 3. 新闻聚合:多源新闻自动采集
  4. 4. 招聘信息整合:各大招聘网站数据汇总
  5. 5. 学术资源收集:论文、专利数据抓取

总结

AI辅助编程不是替代程序员,而是:

  1. 1. 提升效率:将重复性工作自动化
  2. 2. 降低门槛:让非专业人员也能完成数据抓取
  3. 3. 优化思路:AI提供的解决方案可能比人工更优
  4. 4. 快速迭代:从想法到实现只需几分钟

核心流程

需求描述 → 投喂HTML → 获得JS代码 → 转为Playwright → 测试优化 → 完成

掌握这套方法,你也能在几十分钟内完成原本需要数小时的数据抓取项目!

作者声明:本文所述方法仅用于学习交流,请遵守网站robots.txt协议和相关法律法规,不要对目标网站造成过大压力。