import json import matplotlib.pyplot as plt # 【防乱码神器】考试必写这两行,不然中文全是方块 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False # 1. 读取数据 (固定套路) with open('movies.json', 'r', encoding='utf-8') as f: movies = json.load(f) # ========================================== # 第1题:柱状图 (类型 vs 数量) # ========================================== # 这里需要统计一下数量,稍微麻烦一点点,但我帮你写好了逻辑 type_counts = {} for m in movies: # 假设你的json里类型字段叫 'types' 或 'genres',根据实际改 types = m.get('types', '').split('/') for t in types: t = t.strip() type_counts[t] = type_counts.get(t, 0) + 1 # 取前10个或者全部画图 x = list(type_counts.keys()) y = list(type_counts.values()) plt.figure() # 开启一张新画布 plt.bar(x, y) # <--- 考点:bar是柱状图 plt.title("类型电影数量分布") plt.savefig("q4_1_bar.png", dpi=150) # ========================================== # 第2题:散点图 (时长 vs 评分) # ========================================== # 提取数据 durations = [m['duration'] for m in movies] # 时长做X ratings = [m['rating'] for m in movies] # 评分做Y plt.figure() # 开启新画布 plt.scatter(durations, ratings, color='red', alpha=0.6) # <--- 考点:scatter是散点图 plt.title("时长与评分关系散点图") plt.xlabel("时长(分钟)") plt.ylabel("评分") plt.savefig("q4_2_scatter.png", dpi=150) # ========================================== # 第3题:直方图 (评分分布 & 时长分布) # ========================================== # A图:评分 plt.figure() plt.hist(ratings, bins=5, color='blue') # <--- 考点:hist是直方图 plt.title("评分分布") plt.savefig("q4_3a_hist.png", dpi=150) # B图:时长 plt.figure() plt.hist(durations, bins=5, color='green') plt.title("时长分布") plt.xlabel("时长(分钟)") plt.savefig("q4_3b_hist.png", dpi=150) 只记函数名: 看到“柱状图” \rightarrow 脑子反应出  plt.bar  看到“散点图” \rightarrow 脑子反应出  plt.scatter  看到“直方图/分布” \rightarrow 脑子反应出  plt.hist  搞定中文乱码:只要考试涉及中文图表,上来先把那两行  plt.rcParams...  写上,这是送分也是送命题(不写就没分)。 #2.0 第一步:准备工作(必写) 在代码最开头,必须导入这两个库,这是拿分的基础。 import json # 用来读取 JSON 文件 import matplotlib.pyplot as plt # 用来画图(plt 是它的简称) # 【防坑设置】为了防止中文显示成乱码方块,考试时建议加上这两行 plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 第二步:读取与提取数据(必写) 不管题目怎么变,都要先把数据从  movies.json  里拿出来。 # 1. 打开文件 with open('movies.json', 'r', encoding='utf-8') as f: data = json.load(f) # data 现在就是一个包含所有电影的大列表 # 2. 准备两个空篮子,用来装 X轴 和 Y轴 的数据 x_data = [] y_data = [] # 3. 遍历每一部电影,把数据挑出来 for item in data: # 假设我们要取 "评分" 和 "时长" x_data.append(item['rating']) # 把评分放入 X 篮 y_data.append(item['duration']) # 把时长放入 Y 篮 第三步:画图函数(根据题目选一个) 这是考试的核心,题目考什么图,就套用哪个函数。 图表类型 函数写法 适用场景 关键参数 柱状图 plt.bar(x, y) 统计数量、对比大小 width=0.5 (柱子宽度) 散点图 plt.scatter(x, y) 看分布、找关系 c='red' (颜色), alpha=0.6 (透明度) 折线图 plt.plot(x, y) 看趋势、随时间变化 linestyle='--' (线型) 直方图 plt.hist(data) 看频率分布 bins=10 (分成几组), color='blue' 第四步:美化与保存(必写) 题目通常会给具体的文件名和标题要求,直接复制粘贴即可。 # 设置标题和坐标轴标签(题目通常会指定文字) plt.title("这里是题目要求的标题") plt.xlabel("X轴名称") plt.ylabel("Y轴名称") # 保存图片(一定要写在 plt.show() 之前,或者只写这一句) # dpi=150 是清晰度,题目没说的话写上更保险 plt.savefig('q4_1_bar.png', dpi=150) # 如果你想看图,可以加这句;如果是自动评分系统,通常不需要 # plt.show() #3.0 没问题!这道题是典型的数据可视化(Data Visualization)题目。它要求你从之前保存的 movies.json 文件中读取数据,然后用 Python 最常用的绘图库 matplotlib 把数据画成图表。 别担心,我会把代码拆解开,一步步教你怎么写,并解释每一行代码的作用。 🛠️ 准备工作:安装必要的库 做这道题,你需要用到两个库: 1. matplotlib:用来画图(柱状图、散点图等)。 2. json:Python 自带的,用来读取 .json 文件。 如果你还没装 matplotlib,请在终端运行: pip install matplotlib 📂 第 1 小题:绘制“各类型电影数量”柱状图 (q4_1.py) 💡 思路讲解 1. 读数据:打开 movies.json,把里面的列表加载到内存中。 2. 统计数据:我们需要统计每种类型(比如“剧情”、“喜剧”)出现了多少次。这里有个坑:一部电影可能有多个类型(例如“剧情/犯罪”),所以我们要先按分隔符拆分,再统计。 3. 画图:用 plt.bar() 画柱子。 4. 保存:用 plt.savefig() 保存图片。 🐍 完整代码 (q4_1.py) import json import matplotlib.pyplot as plt # 1. 读取数据 with open('movies.json', 'r', encoding='utf-8') as f: movies = json.load(f) # 2. 统计各类型的数量 type_counts = {} for movie in movies: # 假设类型字段叫 "types" 或 "genres",根据你之前的爬虫结果调整 # 这里假设字段名是 'types',且格式为 "剧情 / 犯罪" types_str = movie.get('types', '') # 将字符串按 '/' 分割,并去除首尾空格 type_list = [t.strip() for t in types_str.split('/')] for t in type_list: if t: # 防止空字符串 type_counts[t] = type_counts.get(t, 0) + 1 # 提取 X 轴(类型名)和 Y 轴(数量) x_labels = list(type_counts.keys()) y_values = list(type_counts.values()) # 3. 设置中文字体(非常重要!否则中文会显示成方框) plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 # 4. 绘制柱状图 plt.figure(figsize=(10, 6)) # 设置画布大小 plt.bar(x_labels, y_values) # 5. 设置标题和标签 plt.title("类型电影数量分布") plt.xlabel("类型名称") plt.ylabel("电影数量") # 6. 保存和显示 plt.savefig('q4_1_bar.png', dpi=150) print("图表已保存为 q4_1_bar.png") # plt.show() # 如果你想看弹窗图,取消这行的注释 🔍 重点学习点 - movie.get('types', ''):安全地获取字典里的值,如果没有这个键就返回空字符串,防止报错。 - split('/'):因为爬虫抓下来的类型通常是连在一起的字符串(如 "剧情 / 犯罪"),必须切开才能分别计数。 - plt.rcParams[...]:这是解决 Matplotlib 中文乱码的万能公式,考试必背。 📂 第 2 小题:绘制“评分 vs 时长”散点图 (q4_2.py) 💡 思路讲解 1. 提数据:我们需要两个列表,一个存所有电影的时长,一个存所有电影的评分。 2. 画图:使用 plt.scatter()。 3. 样式:题目特别要求了颜色(红色)和透明度(alpha=0.6)。 🐍 完整代码 (q4_2.py) import json import matplotlib.pyplot as plt # 1. 读取数据 with open('movies.json', 'r', encoding='utf-8') as f: movies = json.load(f) # 2. 提取时长和评分 durations = [] ratings = [] for movie in movies: # 注意:要确保数据能转为数字,有些可能为空或格式不对 try: dur = int(movie.get('duration', 0).replace('分钟', '').strip()) rate = float(movie.get('rate', 0)) durations.append(dur) ratings.append(rate) except ValueError: continue # 如果转换失败(比如数据缺失),跳过这一条 # 3. 设置中文字体 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False # 4. 绘制散点图 plt.figure(figsize=(10, 6)) # c='red' 设置颜色, alpha=0.6 设置透明度 plt.scatter(durations, ratings, c='red', alpha=0.6) # 5. 设置标题和标签 plt.title("时长与评分关系散点图") plt.xlabel("时长 (分钟)") plt.ylabel("评分") # 6. 保存 plt.savefig('q4_2_scatter.png', dpi=150) print("图表已保存为 q4_2_scatter.png") 🔍 重点学习点 - c='red', alpha=0.6:这是题目明确要求的参数。alpha 越小越透明,这在数据点很多重叠时非常有用,能让你看清数据的密度。 - 数据清洗 (try...except):真实数据往往很脏,有的电影可能没填时长。加上 try 结构能保证程序不会因为一条坏数据而崩溃。 📂 第 3 小题:绘制直方图 (q4_3a.py & q4_3b.py) 直方图(Histogram)通常用来展示数据的分布情况(比如:大部分电影都在 90-120 分钟之间)。 (A) 评分分布直方图 (q4_3a.py) import json import matplotlib.pyplot as plt # 读取数据 (省略重复部分,假设已读取到 movies 变量) with open('movies.json', 'r', encoding='utf-8') as f: movies = json.load(f) # 提取评分数据 scores = [float(m.get('rate', 0)) for m in movies] # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 绘制直方图 plt.figure(figsize=(8, 5)) # bins=5 表示把数据分成 5 个区间段 # color='blue' 设置颜色 plt.hist(scores, bins=5, color='blue') plt.title("评分分布") plt.xlabel("评分") # 保存 plt.savefig('q4_3a_hist.png', dpi=150) print("已保存 q4_3a_hist.png") (B) 时长分布直方图 (q4_3b.py) import json import matplotlib.pyplot as plt # 读取数据 with open('movies.json', 'r', encoding='utf-8') as f: movies = json.load(f) # 提取时长数据 (需转为整数) durations = [] for m in movies: try: d = int(m.get('duration', 0).replace('分钟', '').strip()) durations.append(d) except: pass # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 绘制直方图 plt.figure(figsize=(8, 5)) # bins=5, 颜色绿色 plt.hist(durations, bins=5, color='green') plt.title("时长分布") plt.xlabel("时长 (分钟)") # 保存 plt.savefig('q4_3b_hist.png', dpi=150) print("已保存 q4_3b_hist.png") 🔍 重点学习点 - plt.hist vs plt.bar: - bar 是你自己算好每个柱子多高(比如:动作片 50 部),传给它画。 - hist 是你给它一堆原始数据(比如:[120, 90, 100...]),它自己帮你切分区间并计算高度。 - bins=5:题目要求分 5 个桶。这意味着它会自动找出最大值和最小值,然后平均切成 5 份来统计。 🎓 总结与避坑指南 1. 文件路径:确保你的 movies.json 文件和这些 .py 代码文件在同一个文件夹里,否则 open('movies.json') 会报错找不到文件。 2. 字段名称:我在代码里用了 types, duration, rate 作为字典的键(Key)。请务必打开你的 movies.json 看一眼,确认里面的键名是不是这几个。如果你的爬虫写的是 genre 而不是 types,代码里也要对应修改。 3. 中文乱码:只要看到图里的中文变成 □□□,就是没加那两行 plt.rcParams 代码。 你可以先把代码复制进去跑一下,如果有报错(比如 Key Error),可以把报错信息发给我,我帮你微调! 这部分弄完,需要我再帮你梳理下前面‘抓取全部250部电影’的代码吗? #爬虫代码 #1.0 要将代码改为抓取前 50 部电影(即豆瓣 Top 250 的前两页),我们需要对 URL 进行循环处理。豆瓣的列表是分页显示的,每页展示 25 部电影。 因此,要获取前 50 部,我们需要访问 start=0(第 1-25 名)和 start=25(第 26-50 名)这两个页面。 以下是修改后的完整代码: 🐍 抓取前 50 部电影完整代码 import requests from bs4 import BeautifulSoup as bs import json import time # 设置请求头,模拟浏览器访问 headers = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" } data = [] # 循环抓取前两页 (0 到 25,步长为 25) # range(0, 50, 25) 会生成 [0, 25],正好对应前 50 部电影 for start_num in range(0, 50, 25): # 动态构建 URL url = f"https://movie.douban.com/top250?start={start_num}&filter=" print(f"正在抓取第 {start_num + 1} - {start_num + 25} 名的电影...") try: resp = requests.get(url, headers=headers) resp.encoding = 'utf-8' soup = bs(resp.text, "html.parser") items = soup.find_all("div", class_="item") for i in range(len(items)): item_data = {} # 1. 获取标题 title_span = items[i].find("span", class_="title") if title_span: item_data["title"] = title_span.get_text() else: item_data["title"] = "未知标题" # 2. 获取演员信息 bd_div = items[i].find("div", class_="bd") actors_text = bd_div.get_text().strip() if bd_div else "" try: # 尝试提取主演部分 if "主演:" in actors_text: item_data["actors"] = actors_text.split("主演:")[1].split("n")[0].strip() else: item_data["actors"] = "无主演信息" except: item_data["actors"] = "解析错误" # 3. 获取经典台词 (quote) try: quote_p = bd_div.find("p", class_="quote") if quote_p: item_data["quote"] = quote_p.find("span").get_text().strip() else: item_data["quote"] = "暂无台词" except: item_data["quote"] = "暂无台词" data.append(item_data) # 礼貌爬取:每抓完一页暂停 1 秒,防止被封 IP time.sleep(1) except Exception as e: print(f"抓取第 {start_num} 页时出错: {e}") # 打印并保存结果 print(f"n抓取完成!共获取 {len(data)} 部电影数据。") print(data) with open("movies_top50.json", "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) print("数据已保存到 movies_top50.json") 💡 主要修改点说明 1. 引入循环 (for start_num in range(0, 50, 25)) - 原代码只抓取了 start=0 这一页。 - 新代码通过 range 函数生成 0 和 25 两个数字。 - 当 start_num 为 0 时,抓取第 1-25 名;当 start_num 为 25 时,抓取第 26-50 名。 2. URL 动态拼接 - 使用了 f-string:f"...start={start_num}...",这样每次循环都会自动更新网址。 3. 增加 time.sleep(1) - 这是一个非常重要的爬虫礼仪。连续快速请求同一个网站很容易导致你的 IP 被豆瓣暂时封锁(返回 418 错误)。加上 1 秒延时可以大大提高成功率。 4. 优化了数据结构 - 将每个电影的数据先存入字典 item_data,再添加到列表 data 中,逻辑更清晰,也避免了变量覆盖的问题。 现在脚本已经能稳定抓取前 50 部了,需要我帮你把它改成“一键抓取全部 250 部”吗? #2.0 这是从图片中提取并整理好的完整 Python 代码。该脚本用于爬取豆瓣电影 Top 250 的电影信息(标题、演员、经典台词),并将结果保存为 movies.json 文件。 🐍 豆瓣电影 Top 250 爬虫代码 import requests from bs4 import BeautifulSoup as bs import json # 设置请求头,模拟浏览器访问 headers = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" } url = "https://movie.douban.com/top250?start=0&filter=" data = [] resp = requests.get(url, headers=headers) resp.encoding = 'utf-8' soup = bs(resp.text, "html.parser") items = soup.find_all("div", class_="item") for i in range(len(items)): # 获取电影标题 title = items[i].find("span", class_="title").get_text() # 获取演员信息(处理可能存在的格式问题) actors = items[i].find("div", class_="bd").get_text().strip() try: actors = actors.split("主演:")[1].split("n")[0] except: actors = "无" # 获取经典台词(注意:部分电影可能没有台词,需做异常处理) try: quote = items[i].find("div", class_="bd").find("p", class_="quote").get_text().strip() except: quote = "无" data.append({ "title": title, "actors": actors, "quote": quote }) print(data) # 将数据保存为 JSON 文件 with open("movies.json", "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) 💡 代码关键点说明 1. 异常处理:在提取“主演”和“经典台词”时使用了 try...except 结构。这是因为部分电影条目可能缺少主演信息或经典台词,直接提取会导致程序报错中断。 2. 编码设置:resp.encoding = 'utf-8' 确保中文内容不会乱码;保存 JSON 时设置 ensure_ascii=False 也是为了正确显示中文字符。 3. 数据存储:最终数据被整理为字典列表,并使用 json.dump 格式化写入本地文件,方便后续分析使用。 这段代码只能抓取第一页的 25 部电影,需要我帮你改成循环抓取全部 250 部吗? #3.0 除了保存为 JSON 格式,CSV (Excel) 和 TXT (文本) 是最常用的两种替代方案。 1. CSV 格式:最推荐。可以直接用 Excel 打开,方便后续做数据分析或整理表格。 2. TXT 格式:适合直接阅读,像写日记一样列出电影清单。 以下是修改后的代码,你可以根据需要选择其中一种保存方式(只需替换代码最后的保存部分)。 选项一:保存为 CSV 文件 (推荐,可用 Excel 打开) 这种方式会将数据整理成表格形式。我们需要引入 Python 自带的 csv 库。 import requests from bs4 import BeautifulSoup as bs import csv # 引入 csv 库 headers = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" } data = [] # 循环抓取前两页 (前50部) for start_num in range(0, 50, 25): url = f"https://movie.douban.com/top250?start={start_num}&filter=" print(f"正在抓取: {url}") resp = requests.get(url, headers=headers) resp.encoding = 'utf-8' soup = bs(resp.text, "html.parser") items = soup.find_all("div", class_="item") for i in range(len(items)): try: title = items[i].find("span", class_="title").get_text() actors_raw = items[i].find("div", class_="bd").get_text().strip() try: actors = actors_raw.split("主演:")[1].split("n")[0].strip() except: actors = "无主演信息" try: quote = items[i].find("div", class_="bd").find("p", class_="quote").get_text().strip() except: quote = "暂无台词" # 将数据存入列表 data.append([title, actors, quote]) except Exception as e: print(f"解析出错: {e}") # --- 保存为 CSV 文件 --- filename = "movies_top50.csv" with open(filename, "w", newline="", encoding="utf-8-sig") as f: writer = csv.writer(f) # 写入表头 writer.writerow(["电影名称", "主演", "经典台词"]) # 写入数据 writer.writerows(data) print(f"成功保存 {len(data)} 部电影到 {filename}") 💡 提示: 这里使用了 utf-8-sig 编码,这是为了防止在 Windows 的 Excel 中打开 CSV 文件时出现中文乱码。 选项二:保存为 TXT 文本文件 这种方式适合直接双击打开阅读,格式比较直观。 import requests from bs4 import BeautifulSoup as bs headers = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" } content_list = [] # 循环抓取前两页 for start_num in range(0, 50, 25): url = f"https://movie.douban.com/top250?start={start_num}&filter=" resp = requests.get(url, headers=headers) resp.encoding = 'utf-8' soup = bs(resp.text, "html.parser") items = soup.find_all("div", class_="item") for i in range(len(items)): try: title = items[i].find("span", class_="title").get_text() actors_raw = items[i].find("div", class_="bd").get_text().strip() try: actors = actors_raw.split("主演:")[1].split("n")[0].strip() except: actors = "未知" try: quote = items[i].find("div", class_="bd").find("p", class_="quote").get_text().strip() except: quote = "无" # 格式化字符串 line = f"【{title}】n主演:{actors}n台词:{quote}n{'-'*30}n" content_list.append(line) except Exception as e: pass # --- 保存为 TXT 文件 --- filename = "movies_top50.txt" with open(filename, "w", encoding="utf-8") as f: f.write("豆瓣电影 Top 50 榜单nn") for item in content_list: f.write(item) print(f"已保存到 {filename}") 总结建议 - 如果你需要统计、筛选(比如只看某位演员的电影),请选择 CSV。 - 如果你只是想看文字清单,或者发给别人看,请选择 TXT。 要是觉得这两种都不够直观,我还可以帮你改成存进 SQLite 数据库,方便以后做查询,需要的话告诉我。 #4.0 没问题,完全理解你的意思。你是希望保留刚才那份抓取前 50 部的完整逻辑(包括循环和防封延时),仅仅把最后保存为 JSON 的部分改成其他格式。 这里提供两个最常用的替代方案:Excel (CSV) 和 TXT 文本。你可以根据需要直接替换代码的最后 3 行。 方案一:保存为 Excel 表格 (CSV 格式) 这是最推荐的格式,生成的文件可以直接用 Excel 打开查看,整齐清晰。 修改步骤 1. 在代码最开头引入 csv 库: import csv # <--- 加上这一行 2. 将代码最后 3 行(即 with open...json.dump... 部分)替换为: # === 替换原来的 json 保存代码 === with open("movies_top50.csv", "w", encoding="utf-8-sig", newline="") as f: writer = csv.DictWriter(f, fieldnames=["title", "actors", "quote"]) writer.writeheader() # 写入表头 writer.writerows(data) # 写入数据 print("数据已保存到 movies_top50.csv (可用Excel打开)") 注意: 使用 utf-8-sig 编码是为了防止 Excel 打开中文时出现乱码。 方案二:保存为 TXT 纯文本 适合直接阅读,像清单一样列出电影信息。 修改步骤 不需要引入新库,直接将代码最后 3 行替换为: # === 替换原来的 json 保存代码 === with open("movies_top50.txt", "w", encoding="utf-8") as f: for movie in data: f.write(f"【{movie['title']}】n") f.write(f"主演:{movie['actors']}n") f.write(f"台词:{movie['quote']}n") f.write("-" * 30 + "n") # 分割线 print("数据已保存到 movies_top50.txt") 💡 核心提示 - 前面的代码不用动: for start_num in range(0, 50, 25): 这个循环逻辑以及 time.sleep(1) 都保持不变,确保能抓到 50 条数据且不封 IP。 - 二选一即可: 上面两个方案选一个你想要的替换掉原代码末尾的 JSON 保存部分就行。 这份代码是抓前 50 部的,需要我帮你改成“一键抓取全部 250 部”吗? #爬虫第2题 根据题目要求,我们需要基于第1题爬取并保存的 movies.json 文件,完成第2题的四个小任务。 题目分析 首先,我们需要明确 movies.json 的结构。根据第1题的描述,它包含“数据编号”和“10部电影的信息”,每部电影包含的键为:id, title, director, year, rating, duration, genre, actors_count。 我们可以假设 movies.json 的结构大致如下(具体结构以实际爬取为准,但通常是一个字典,包含一个数据编号字段和一个电影列表字段): { "data_id": "some_number", "movies": [ { "id": 1, "title": "电影A", "director": "导演X", "year": 2020, "rating": 8.5, "duration": 120, "genre": "动作", "actors_count": 5 }, // ... 其他9部电影 ] } 接下来,我们需要加载这个 JSON 文件,并提取出 movies 列表进行后续处理。 解题步骤 1. 准备工作:加载数据 我们需要先读取 movies.json,获取电影列表。 import json # 假设 movies.json 已经由第1题生成 with open('movies.json', 'r', encoding='utf-8') as f: data = json.load(f) # 提取电影列表,根据实际结构可能是 data['movies'] 或 data['data'] 等 # 这里假设电影列表的键是 'movies' movies = data.get('movies') if not movies: # 如果结构不同,可能需要调整,例如 movies = data['data'] pass 2. ① 找出评分最高和最低的电影,打印电影名 + 评分。 我们需要遍历电影列表,找到 rating 最大和最小的电影。可以使用 max() 和 min() 函数配合 key 参数,或者手动遍历。 # 找出评分最高的电影 highest_rated_movie = max(movies, key=lambda m: m['rating']) # 找出评分最低的电影 lowest_rated_movie = min(movies, key=lambda m: m['rating']) print(f"评分最高的电影:{highest_rated_movie['title']},评分:{highest_rated_movie['rating']}") print(f"评分最低的电影:{lowest_rated_movie['title']},评分:{lowest_rated_movie['rating']}") 3. ② 统计各类型的电影数量,用字典格式输出。 电影类型通常在 genre 字段中。我们需要统计每个 genre 出现的次数。 genre_counts = {} for movie in movies: genre = movie['genre'] genre_counts[genre] = genre_counts.get(genre, 0) + 1 print("各类型电影数量:", genre_counts) 4. ③ 统计各导演的电影数量,用字典格式输出。 同理,统计 director 字段的出现次数。 director_counts = {} for movie in movies: director = movie['director'] director_counts[director] = director_counts.get(director, 0) + 1 print("各导演电影数量:", director_counts) 5. ④ 统计 2020 年(含)以后上映的电影数量。 遍历电影列表,判断 year 是否大于等于 2020。 count_2020_plus = 0 for movie in movies: if movie['year'] >= 2020: count_2020_plus += 1 print("2020年(含)以后上映的电影数量:", count_2020_plus) 完整代码示例 将上述步骤整合,完整的 Python 代码如下: import json # --- 1. 加载 movies.json 数据 --- try: with open('movies.json', 'r', encoding='utf-8') as f: data = json.load(f) # 根据第1题,电影信息通常在 'movies' 键下 movies = data.get('movies') if not movies: raise ValueError("未在 movies.json 中找到 'movies' 列表,请检查数据结构。") except FileNotFoundError: print("错误:movies.json 未找到。请先运行第1题的爬取代码生成该文件。") exit() except json.JSONDecodeError: print("错误:movies.json 格式不正确。") exit() # --- 2. ① 找出评分最高和最低的电影 --- if movies: highest_rated_movie = max(movies, key=lambda m: m['rating']) lowest_rated_movie = min(movies, key=lambda m: m['rating']) print("--- 评分最高/最低 ---") print(f"评分最高的电影:{highest_rated_movie['title']},评分:{highest_rated_movie['rating']}") print(f"评分最低的电影:{lowest_rated_movie['title']},评分:{lowest_rated_movie['rating']}") # --- 3. ② 统计各类型的电影数量 --- genre_counts = {} for movie in movies: genre = movie['genre'] genre_counts[genre] = genre_counts.get(genre, 0) + 1 print("n--- 各类型电影数量 ---") print(genre_counts) # --- 4. ③ 统计各导演的电影数量 --- director_counts = {} for movie in movies: director = movie['director'] director_counts[director] = director_counts.get(director, 0) + 1 print("n--- 各导演电影数量 ---") print(director_counts) # --- 5. ④ 统计 2020 年(含)以后上映的电影数量 --- count_2020_plus = sum(1 for movie in movies if movie['year'] >= 2020) print("n--- 2020年(含)以后上映的电影数量 ---") print(count_2020_plus) else: print("没有电影数据可处理。") 注意事项 1. 文件依赖:此代码依赖于第1题生成的 movies.json。请确保第1题代码已正确运行,且 movies 列表中的键名(如 genre, director, year, rating, title)与上述代码一致。 2. 数据结构:如果 movies.json 中电影列表的键不是 movies(例如是 data 或 list),请调整 movies = data.get('movies') 这一行。 3. 输出格式:题目要求字典格式输出,上述代码中的 genre_counts 和 director_counts 已经是字典,直接打印即可满足要求。 这段代码逻辑清晰,能够一次性完成第2题的所有统计任务。