星海无海 2024-09-30 09:06 采纳率: 0%
浏览 1

如何在爬取百度小说中的西游记时,最后的文章内容存储在“content”中,但是运行代码就显示 “ KeyError: 'content' ”?(相关搜索:python爬虫)

在爬取百度小说中的西游记时,最后的文章内容存储在“content”中,但是运行代码就显示 “ KeyError: 'content' ” ,下面是我的代码


```python
# https://dushu.baidu.com/api/pc/getCatalog?data={"book_id":"4306063500"}
# 所有章节的内容(名称,cid)

# https://dushu.baidu.com/api/pc/getChapterContent?data={"book_id":"4306063500","cid":"4306063500|1569782244","need_bookinfo":1}
# 具体内容

import requests
import asyncio
import aiohttp
import json
import aiofiles

async def aiodownload(cid,b_id,title):
    date = {
        "book_id": b_id,
        "cid": f"{b_id}|{cid}",
        "need_bookinfo": 1
    }
    date_json = json.dumps(date)
    url = f"https://dushu.baidu.com/api/pc/getCatalog?data={date_json}"
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            dic = await resp.json()

            async with aiofiles.open(title, "w", encoding="utf-8") as f:
                await f.write(dic['data']['novel']['content']) # 把小说内容写出


async def getCatalog(url):
            resp = requests.get(url)
            dic = resp.json()
            tasks = []
            for item in dic['data']['novel']['items']:  # item 对应每一个章节的内容
                title = item['title']
                cid = item['cid']
                # 准备异步任务
                tasks.append(aiodownload(cid, b_id, title))
            
            await asyncio.gather(*tasks)

if __name__ == '__main__':
    b_id = "4306063500"
    data = json.dumps({"book_id": b_id})
    # 构建 URL
    url = f'https://dushu.baidu.com/api/pc/getCatalog?data={data}'
    asyncio.run(getCatalog(url))

```

  • 写回答

2条回答 默认 最新

  • 白驹_过隙 算法领域新星创作者 2024-09-30 09:08
    关注

    回答参考gpt4
    出现 KeyError: 'content' 错误的原因是,代码尝试访问 JSON 响应中的 'content' 键,但实际返回的数据结构中可能没有这个键,或者路径不正确。因此,我们需要确认两点:

    1. 请求的 URL 和 JSON 响应格式:确保从 API 获取的数据结构中确实包含 'content' 字段。
    2. 修正 JSON 响应的路径:有时响应的结构并非如预期,所以我们要检查并找到正确的路径。

    改进代码的步骤:

    1. 检查获取章节内容的 URL 是 https://dushu.baidu.com/api/pc/getChapterContent 而不是 getCatalog,因为 getCatalog 仅提供章节列表,具体的内容应该通过 getChapterContent 来获取。
    2. 确保正确解析 getChapterContent 返回的内容并正确提取 'content' 字段。

    修改后的代码:

    import requests
    import asyncio
    import aiohttp
    import json
    import aiofiles
    
    # 异步下载章节内容
    async def aiodownload(cid, b_id, title):
        # 构建请求数据
        data = {
            "book_id": b_id,
            "cid": f"{b_id}|{cid}",
            "need_bookinfo": 1
        }
        data_json = json.dumps(data)
        # 请求具体章节内容
        url = f"https://dushu.baidu.com/api/pc/getChapterContent?data={data_json}"
        
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as resp:
                # 确保响应是JSON格式
                dic = await resp.json()
                # 检查返回数据中是否有 'data' 和 'novel' 键
                try:
                    content = dic['data']['novel']['content']  # 获取小说内容
                except KeyError as e:
                    print(f"Error fetching content for {title}: {e}")
                    return
    
                # 异步写入章节内容到文件
                async with aiofiles.open(f"{title}.txt", "w", encoding="utf-8") as f:
                    await f.write(content)  # 把小说内容写入文件
    
    # 获取章节目录
    async def getCatalog(url, b_id):
        resp = requests.get(url)
        dic = resp.json()
        tasks = []
        
        # 获取所有章节的 'title' 和 'cid'
        for item in dic['data']['novel']['items']:  # item 对应每一个章节的内容
            title = item['title']
            cid = item['cid']
            # 准备异步任务
            tasks.append(aiodownload(cid, b_id, title))
        
        # 等待所有任务完成
        await asyncio.gather(*tasks)
    
    if __name__ == '__main__':
        b_id = "4306063500"  # 西游记的书ID
        data = json.dumps({"book_id": b_id})
        # 构建获取章节目录的 URL
        url = f'https://dushu.baidu.com/api/pc/getCatalog?data={data}'
        asyncio.run(getCatalog(url, b_id))
    

    关键改动:

    1. 请求章节内容的 URL:章节内容的获取应该使用 getChapterContent API 而不是 getCatalog
    2. 错误处理:增加了 try-except 来捕获 KeyError 错误并进行打印,方便调试和确保程序不崩溃。
    3. 异步写文件:将章节内容保存到文本文件中,使用章节名作为文件名。

    注意事项:

    • 在运行该代码之前,确保实际的 API 返回格式与期望一致,特别是 dic['data']['novel']['content'] 路径是否正确。如果该路径仍然导致错误,可以通过打印整个响应 JSON 检查其实际结构,并调整相应路径。
    评论

报告相同问题?

问题事件

  • 创建了问题 今天

悬赏问题

  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?
  • ¥15 nasm x86 变量归零
  • ¥65 Tree 树形控件实现单选功能,可以使用element也可以手写一个,实现全选为全选状态
  • ¥60 寻抓云闪付tn组成网页付款链接
  • ¥16 寻字节跳动内部人员帮推简历