day22_Ajax&Json.md

本文详细介绍了AJAX的工作原理及其实现方式,包括原生JS和jQuery的使用方法,同时探讨了JSON数据格式及其与Java对象之间的转换,旨在帮助读者掌握异步交互和数据交换的关键技术。

在这里插入图片描述

AJAX:

原生JS参考网址:https://www.runoob.com/ajax/ajax-tutorial.html

1. 概念: ASynchronous JavaScript And XML	异步的JavaScript 和 XML
	1. 异步和同步:客户端和服务器端相互通信的基础上
		* 客户端必须等待服务器端的响应。在等待的期间客户端不能做其他操作。
		* 客户端不需要等待服务器端的响应。在服务器处理请求的过程中,客户端可以进行其他的操作。

		Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。 [1] 
		通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,
		对网页的某部分进行更新。
		传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
		提升用户的体验

2. 实现方式:
	1. 原生的JS实现方式(了解)
				 //1.创建核心对象
	            var xmlhttp;
	            if (window.XMLHttpRequest)
	            {// code for IE7+, Firefox, Chrome, Opera, Safari
	                xmlhttp=new XMLHttpRequest();
	            }
	            else
	            {// code for IE6, IE5
	                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	            }
	
	            //2. 建立连接
	            /*
	                参数:
	                    1. 请求方式:GET、POST
	                        * get方式,请求参数在URL后边拼接。send方法为空参
	                        * post方式,请求参数在send方法中定义
	                    2. 请求的URL:
	                    3. 同步或异步请求:true(异步)或 false(同步)
	
	             */
	            xmlhttp.open("GET","ajaxServlet?username=tom",true);
	
	            //3.发送请求
	            xmlhttp.send();
	
	            //4.接受并处理来自服务器的响应结果
	            //获取方式 :xmlhttp.responseText
	            //什么时候获取?当服务器响应成功后再获取
	
	            //当xmlhttp对象的就绪状态改变时,触发事件onreadystatechange。
	            xmlhttp.onreadystatechange=function()
	            {
	                //判断readyState就绪状态是否为4,判断status响应状态码是否为200
	                if (xmlhttp.readyState==4 && xmlhttp.status==200)
	                {
	                   //获取服务器的响应结果
	                    var responseText = xmlhttp.responseText;
	                    alert(responseText);
	                }
	            }
	2. JQeury实现方式
		1. $.ajax()
			* 语法:$.ajax({键值对});
			 //使用$.ajax()发送异步请求
	            $.ajax({
	                url:"ajaxServlet1111" , // 请求路径
	                type:"POST" , //请求方式
	                //data: "username=jack&age=23",//请求参数
	                data:{"username":"jack","age":23},
	                success:function (data) {
	                    alert(data);
	                },//响应成功后的回调函数
	                error:function () {
	                    alert("出错啦...")
	                },//表示如果请求响应出现错误,会执行的回调函数
	
	                dataType:"text"//设置接受到的响应数据的格式
	            });
		2. $.get():发送get请求
			* 语法:$.get(url, [data], [callback], [type])
				* 参数:
					* url:请求路径
					* data:请求参数
					* callback:回调函数
					* type:响应结果的类型

		3. $.post():发送post请求
			* 语法:$.post(url, [data], [callback], [type])
				* 参数:
					* url:请求路径
					* data:请求参数
					* callback:回调函数
					* type:响应结果的类型

JSON:

JSON在线教程 : https://www.runoob.com/json/json-tutorial.html

1. 概念: JavaScript Object Notation		JavaScript对象表示法
	Person p = new Person();
	p.setName("张三");
	p.setAge(23);
	p.setGender("男");

	var p = {"name":"张三","age":23,"gender":"男"};

	* json现在多用于存储和交换文本信息的语法
	* 进行数据的传输
	* JSON 比 XML 更小、更快,更易解析。

2. 语法:
	1. 基本规则
		* 数据在名称/值对中:json数据是由键值对构成的
			* 键用引号(单双都行)引起来,也可以不使用引号
			* 值得取值类型:
				1. 数字(整数或浮点数)
				2. 字符串(在双引号中)
				3. 逻辑值(true 或 false)
				4. 数组(在方括号中)	{"persons":[{},{}]}
				5. 对象(在花括号中) {"address":{"province":"陕西"....}}
				6. null
		* 数据由逗号分隔:多个键值对由逗号分隔
		* 花括号保存对象:使用{}定义json 格式
		* 方括号保存数组:[]
	2. 获取数据:
		1. json对象.键名
		2. json对象["键名"]
		3. 数组对象[索引]
		4. 遍历
				 //1.定义基本格式
		        var person = {"name": "张三", age: 23, 'gender': true};
		
		        var ps = [{"name": "张三", "age": 23, "gender": true},
		            {"name": "李四", "age": 24, "gender": true},
		            {"name": "王五", "age": 25, "gender": false}];




​ //获取person对象中所有的键和值
​ //for in 循环
​ /* for(var key in person){
​ //这样的方式获取不行。因为相当于 person.“name”
​ //alert(key + “:” + person.key);
​ alert(key+":"+person[key]);
​ }*/

//获取ps中的所有值
for (var i = 0; i < ps.length; i++) {
var p = ps[i];
for(var key in p){
alert(key+":"+p[key]);
}
}

3. JSON数据和Java对象的相互转换

	* JSON解析器:
		* 常见的解析器:Jsonlib,Gson,fastjson,jackson
	
	1. JSON转为Java对象
		1. 导入jackson的相关jar包
		2. 创建Jackson核心对象 ObjectMapper
		3. 调用ObjectMapper的相关方法进行转换
			1. readValue(json字符串数据,Class)
	2. Java对象转换JSON
		1. 使用步骤:
			1. 导入jackson的相关jar包
			2. 创建Jackson核心对象 ObjectMapper
			3. 调用ObjectMapper的相关方法进行转换
				1. 转换方法:
					*(了解) writeValue(参数1,obj):
	                    参数1:
	                        File:将obj对象转换为JSON字符串,并保存到指定的文件中
	                        Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中
	                        OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中
	                *(重点) writeValueAsString(obj):将对象转为json字符串

				2. 注解:
					1. @JsonIgnore:排除属性。
					2. @JsonFormat:属性值得格式化
						* @JsonFormat(pattern = "yyyy-MM-dd")

				3. 复杂java对象转换
					1.(重点) List:数组
					2.(了解) Map:对象格式一致

案例:

* 校验用户名是否存在
	1. 服务器响应的数据,在客户端使用时,要想当做json数据格式使用。有两种解决方案:
		1. $.get(type):将最后一个参数type指定为"json"
		2. 在服务器端设置MIME类型
			response.setContentType("application/json;charset=utf-8");

代码实现:




注册











		</body>
		</html>

		@WebServlet("/findServlet")
		public class FindServlet extends HttpServlet {
			protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				request.setCharacterEncoding("utf-8");
				response.setContentType("text/html;charset=utf-8");
				String name = request.getParameter("name");
				HashMap<String, Object> map = new HashMap<>();
				if("张三".equals(name)){
					map.put("flag",true);
					map.put("msg","该用户名已存在,请换一个");
				}else {
					map.put("flag", false);
					map.put("msg", "该用户名可以使用");
				}
				ObjectMapper om = new ObjectMapper();
				om.writeValue(response.getWriter(),map);
			}

			protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				this.doPost(request, response);
			}
		}
import base64 import hashlib import math import random import time import requests import json import pandas as pd from datetime import datetime, timedelta import os class MaoyanAPISpider: def __init__(self): self.session = requests.Session() self.setup_headers() def setup_headers(self): """设置请求头""" self.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', 'Referer': 'https://piaofang.maoyan.com/dashboard/movie', 'Origin': 'https://piaofang.maoyan.com', 'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', 'Cookie': self.generate_cookies() } def generate_cookies(self): """生成必要的Cookie避免弹窗""" cookies = [ '__mta=', '_lxsdk_cuid=' + str(random.randint(1000000000, 9999999999)), '_lxsdk=' + str(random.randint(1000000000, 9999999999)), '_lx_utm=', '_lxsdk_s=%s' % (''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=10))), 'uuid=' + self.generate_uuid(), 'userTicket=', 'ci=1', ] return '; '.join(cookies) def generate_uuid(self): """生成UUID""" return f'{random.randint(1000000000, 9999999999)}{int(time.time())}' def generate_signature(self, timestamp, user_agent_encoded, index): """生成签名""" content = f"method=GET&timeStamp={timestamp}&User-Agent={user_agent_encoded}&index={index}&channelId=40009&sVersion=2&key=A013F70DB97834C0A5492378BD76C53A" md5 = hashlib.md5() md5.update(content.encode('utf-8')) return md5.hexdigest() def get_daily_data(self, date_str): """获取单日票房数据""" try: # 生成加密参数 user_agent = self.headers['User-Agent'] user_agent_encoded = str(base64.b64encode(user_agent.encode('utf-8')), 'utf-8') index = str(round(random.random() * 1000)) timestamp = str(math.ceil(time.time() * 1000)) # 生成签名 sign = self.generate_signature(timestamp, user_agent_encoded, index) # 构造请求参数 params = { 'orderType': '0', 'uuid': self.generate_uuid(), 'timeStamp': timestamp, 'User-Agent': user_agent_encoded, 'index': index, 'channelId': '40009', 'sVersion': '2', 'signKey': sign, 'date': date_str } url = 'https://piaofang.maoyan.com/dashboard-ajax/movie' # 发送请求 response = self.session.get(url, headers=self.headers, params=params, timeout=10) response.raise_for_status() # 检查响应内容 if response.text.strip() == '': print(f"日期 {date_str}: 返回空数据") return [] # 解析JSON数据 data = response.json() return self.parse_movie_data(data, date_str) except requests.exceptions.RequestException as e: print(f"网络请求失败 {date_str}: {e}") return [] except json.JSONDecodeError as e: print(f"JSON解析失败 {date_str}: {e}") print(f"响应内容: {response.text[:200]}...") return [] except Exception as e: print(f"获取 {date_str} 数据失败: {e}") return [] def parse_movie_data(self, data, date_str): """解析电影数据 - 修复字段映射问题""" movies_data = [] try: if 'movieList' in data and 'list' in data['movieList']: for movie in data['movieList']['list']: # 调试输出原始数据 if len(movies_data) == 0: # 只打印第一部电影的调试信息 print(f"调试信息 - 原始数据结构:") print(f"movie: {json.dumps(movie, ensure_ascii=False, indent=2)[:500]}...") # 正确解析字段 movie_info = { '日期': date_str, '电影名称': movie.get('movieInfo', {}).get('movieName', ''), '上映天数': movie.get('releaseInfo', {}).get('releaseDays', 0), # 修复:上映天数应该是数字 '累计票房': movie.get('sumBoxDesc', ''), '单日票房': movie.get('boxDesc', ''), '票房占比': movie.get('boxRate', ''), '排片占比': movie.get('showCountRate', ''), '上座率': movie.get('avgShowView', ''), '平均票价': movie.get('avgViewBox', ''), '场次': movie.get('showCount', ''), '人次': movie.get('showView', '') } # 检查数据是否正确 if len(movies_data) == 0: # 只打印第一部电影的检查信息 print(f"调试信息 - 解析后数据:") for key, value in movie_info.items(): print(f" {key}: {value}") movies_data.append(movie_info) print(f"日期 {date_str}: 解析到 {len(movies_data)} 部电影数据") return movies_data except Exception as e: print(f"解析数据失败: {e}") import traceback traceback.print_exc() return [] def crawl_range_data(self, start_date, end_date, target_count=10000): """爬取指定日期范围的数据""" all_data = [] current_date = datetime.strptime(start_date, "%Y-%m-%d") end_date = datetime.strptime(end_date, "%Y-%m-%d") print(f"开始爬取 {start_date} 到 {end_date} 的票房数据") print(f"目标数据量: {target_count} 条") while current_date <= end_date and len(all_data) < target_count: date_str = current_date.strftime("%Y-%m-%d") print(f"正在处理: {date_str}") daily_data = self.get_daily_data(date_str) if daily_data: all_data.extend(daily_data) print(f"当前总计: {len(all_data)} 条数据") # 避免请求过于频繁 time.sleep(random.uniform(1, 2)) current_date += timedelta(days=1) # 每100条保存一次备份 if len(all_data) % 100 == 0 and len(all_data) > 0: self.backup_data(all_data) return all_data def backup_data(self, data): """备份数据""" if data: df = pd.DataFrame(data) backup_dir = "D:\\毕业论文\\box_office_data\\backup" os.makedirs(backup_dir, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") backup_path = os.path.join(backup_dir, f"api_backup_{timestamp}.csv") df.to_csv(backup_path, index=False, encoding='utf-8-sig') print(f"数据已备份到: {backup_path}") def save_final_data(self, data, output_dir="D:\\毕业论文\\box_office_data"): """保存最终数据""" if not data: print("没有数据可保存") return None os.makedirs(output_dir, exist_ok=True) df = pd.DataFrame(data) # 保存各种格式 csv_path = os.path.join(output_dir, "maoyan_api_box_office.csv") df.to_csv(csv_path, index=False, encoding='utf-8-sig') json_path = os.path.join(output_dir, "maoyan_api_box_office.json") df.to_json(json_path, orient='records', force_ascii=False, indent=2) excel_path = os.path.join(output_dir, "maoyan_api_box_office.xlsx") df.to_excel(excel_path, index=False) print(f"数据保存完成:") print(f"CSV: {csv_path}") print(f"JSON: {json_path}") print(f"Excel: {excel_path}") print(f"总数据量: {len(df)} 条") # 显示数据预览 print("\n数据预览:") print(df[['日期', '电影名称', '上映天数', '累计票房', '单日票房']].head(10)) # 显示列名信息 print("\n列名信息:") for i, col in enumerate(df.columns, 1): print(f"{i}. {col}") return df def test_single_date(): """测试单日数据获取""" print("=" * 60) print("测试单日数据获取") print("=" * 60) spider = MaoyanAPISpider() # 测试不同日期 test_dates = ["2024-11-21", "2024-11-22", "2025-11-20"] for test_date in test_dates: print(f"\n正在测试日期: {test_date}") data = spider.get_daily_data(test_date) if data: df = pd.DataFrame(data) print(f"获取到 {len(data)} 条数据") print(f"日期列的值: {df['日期'].iloc[0]}") print(f"上映天数样例: {df['上映天数'].iloc[0]}") print(f"累计票房样例: {df['累计票房'].iloc[0]}") print(f"单日票房样例: {df['单日票房'].iloc[0]}") else: print("没有获取到数据") time.sleep(2) def main(): """主函数""" print("=" * 60) print("猫眼API票房数据爬虫") print("=" * 60) spider = MaoyanAPISpider() # 设置爬取参数 - 使用正确的日期范围 start_date = "2024-11-21" end_date = "2024-11-25" # 先测试小范围 target_count = 200 # 开始爬取 data = spider.crawl_range_data(start_date, end_date, target_count) # 保存数据 if data: df = spider.save_final_data(data) print("爬虫执行完成!") # 显示数据统计信息 if df is not None: print(f"\n数据统计:") print(f"日期范围: {df['日期'].min()} 到 {df['日期'].max()}") print(f"电影数量: {df['电影名称'].nunique()}") print(f"总记录数: {len(df)}") # 检查数据质量 print(f"\n数据质量检查:") print(f"上映天数为空: {df['上映天数'].isnull().sum()}") print(f"累计票房为空: {df['累计票房'].isnull().sum()}") print(f"单日票房为空: {df['单日票房'].isnull().sum()}") else: print("没有获取到数据") if __name__ == "__main__": # 先运行测试 test_single_date() # 再运行主程序 print("\n" + "=" * 60) print("开始主程序") print("=" * 60) main()显示D:\毕业论文\pythonProject3\.venv\Scripts\python.exe D:\毕业论文\pythonProject3\爬取.py ============================================================ 测试单日数据获取 ============================================================ 正在测试日期: 2024-11-21 调试信息 - 原始数据结构: movie: { "avgSeatView": "1.0%", "avgShowView": "1.5", "boxRate": "72.0%", "boxSplitUnit": { "num": ".", "unit": "万" }, "movieInfo": { "movieId": 1528577, "movieName": "鬼灭之刃:无限城篇 第一章 猗窝座再袭", "releaseInfo": "上映8天" }, "showCount": 129162, "showCountRate": "34.8%", "splitBoxRate": "71.2%", "splitBoxSplitUnit": { "num": ".", "unit": "万" }, "sumBoxDesc": "4.61亿", "sumSplitBo... 调试信息 - 解析后数据: 日期: 2024-11-21 电影名称: 鬼灭之刃:无限城篇 第一章 猗窝座再袭 上映天数: 0 累计票房: 4.61亿 单日票房: 票房占比: 72.0% 排片占比: 34.8% 上座率: 1.5 平均票价: 场次: 129162 人次: 日期 2024-11-21: 解析到 84 部电影数据 获取到 84 条数据 日期列的值: 2024-11-21 上映天数样例: 0 累计票房样例: 4.61亿 单日票房样例: 正在测试日期: 2024-11-22 调试信息 - 原始数据结构: movie: { "avgSeatView": "1.0%", "avgShowView": "1.5", "boxRate": "72.0%", "boxSplitUnit": { "num": ".", "unit": "万" }, "movieInfo": { "movieId": 1528577, "movieName": "鬼灭之刃:无限城篇 第一章 猗窝座再袭", "releaseInfo": "上映8天" }, "showCount": 129162, "showCountRate": "34.8%", "splitBoxRate": "71.2%", "splitBoxSplitUnit": { "num": ".", "unit": "万" }, "sumBoxDesc": "4.61亿", "sumSplitBo... 调试信息 - 解析后数据: 日期: 2024-11-22 电影名称: 鬼灭之刃:无限城篇 第一章 猗窝座再袭 上映天数: 0 累计票房: 4.61亿 单日票房: 票房占比: 72.0% 排片占比: 34.8% 上座率: 1.5 平均票价: 场次: 129162 人次: 日期 2024-11-22: 解析到 84 部电影数据 获取到 84 条数据 日期列的值: 2024-11-22 上映天数样例: 0 累计票房样例: 4.61亿 单日票房样例: 正在测试日期: 2025-11-20 调试信息 - 原始数据结构: movie: { "avgSeatView": "1.0%", "avgShowView": "1.5", "boxRate": "72.0%", "boxSplitUnit": { "num": ".", "unit": "万" }, "movieInfo": { "movieId": 1528577, "movieName": "鬼灭之刃:无限城篇 第一章 猗窝座再袭", "releaseInfo": "上映8天" }, "showCount": 129162, "showCountRate": "34.8%", "splitBoxRate": "71.2%", "splitBoxSplitUnit": { "num": ".", "unit": "万" }, "sumBoxDesc": "4.61亿", "sumSplitBo... 调试信息 - 解析后数据: 日期: 2025-11-20 电影名称: 鬼灭之刃:无限城篇 第一章 猗窝座再袭 上映天数: 0 累计票房: 4.61亿 单日票房: 票房占比: 72.0% 排片占比: 34.8% 上座率: 1.5 平均票价: 场次: 129162 人次: 日期 2025-11-20: 解析到 84 部电影数据 获取到 84 条数据 日期列的值: 2025-11-20 上映天数样例: 0 累计票房样例: 4.61亿 单日票房样例: ============================================================ 开始主程序 ============================================================ ============================================================ 猫眼API票房数据爬虫 ============================================================ 开始爬取 2024-11-21 到 2024-11-25 00:00:00 的票房数据 目标数据量: 200 条 正在处理: 2024-11-21 调试信息 - 原始数据结构: movie: { "avgSeatView": "1.0%", "avgShowView": "1.5", "boxRate": "72.0%", "boxSplitUnit": { "num": ".", "unit": "万" }, "movieInfo": { "movieId": 1528577, "movieName": "鬼灭之刃:无限城篇 第一章 猗窝座再袭", "releaseInfo": "上映8天" }, "showCount": 129162, "showCountRate": "34.8%", "splitBoxRate": "71.2%", "splitBoxSplitUnit": { "num": ".", "unit": "万" }, "sumBoxDesc": "4.61亿", "sumSplitBo... 调试信息 - 解析后数据: 日期: 2024-11-21 电影名称: 鬼灭之刃:无限城篇 第一章 猗窝座再袭 上映天数: 0 累计票房: 4.61亿 单日票房: 票房占比: 72.0% 排片占比: 34.8% 上座率: 1.5 平均票价: 场次: 129162 人次: 日期 2024-11-21: 解析到 84 部电影数据 当前总计: 84 条数据 正在处理: 2024-11-22 调试信息 - 原始数据结构: movie: { "avgSeatView": "1.0%", "avgShowView": "1.5", "boxRate": "72.0%", "boxSplitUnit": { "num": ".", "unit": "万" }, "movieInfo": { "movieId": 1528577, "movieName": "鬼灭之刃:无限城篇 第一章 猗窝座再袭", "releaseInfo": "上映8天" }, "showCount": 129162, "showCountRate": "34.8%", "splitBoxRate": "71.2%", "splitBoxSplitUnit": { "num": ".", "unit": "万" }, "sumBoxDesc": "4.61亿", "sumSplitBo... 调试信息 - 解析后数据: 日期: 2024-11-22 电影名称: 鬼灭之刃:无限城篇 第一章 猗窝座再袭 上映天数: 0 累计票房: 4.61亿 单日票房: 票房占比: 72.0% 排片占比: 34.8% 上座率: 1.5 平均票价: 场次: 129162 人次: 日期 2024-11-22: 解析到 84 部电影数据 当前总计: 168 条数据 正在处理: 2024-11-23 调试信息 - 原始数据结构: movie: { "avgSeatView": "1.0%", "avgShowView": "1.5", "boxRate": "72.0%", "boxSplitUnit": { "num": ".", "unit": "万" }, "movieInfo": { "movieId": 1528577, "movieName": "鬼灭之刃:无限城篇 第一章 猗窝座再袭", "releaseInfo": "上映8天" }, "showCount": 129162, "showCountRate": "34.8%", "splitBoxRate": "71.2%", "splitBoxSplitUnit": { "num": ".", "unit": "万" }, "sumBoxDesc": "4.61亿", "sumSplitBo... 调试信息 - 解析后数据: 日期: 2024-11-23 电影名称: 鬼灭之刃:无限城篇 第一章 猗窝座再袭 上映天数: 0 累计票房: 4.61亿 单日票房: 票房占比: 72.0% 排片占比: 34.8% 上座率: 1.5 平均票价: 场次: 129162 人次: 日期 2024-11-23: 解析到 84 部电影数据 当前总计: 252 条数据 数据保存完成: CSV: D:\毕业论文\box_office_data\maoyan_api_box_office.csv JSON: D:\毕业论文\box_office_data\maoyan_api_box_office.json Excel: D:\毕业论文\box_office_data\maoyan_api_box_office.xlsx 总数据量: 252 条 数据预览: 日期 电影名称 上映天数 累计票房 单日票房 0 2024-11-21 鬼灭之刃:无限城篇 第一章 猗窝座再袭 0 4.61亿 1 2024-11-21 惊天魔盗团3 0 1.94亿 2 2024-11-21 菜肉馄饨 0 1626.2万 3 2024-11-21 狂野时代 0 22.5万 4 2024-11-21 铁血战士:杀戮之地 0 9633.6万 5 2024-11-21 志愿军:浴血和平 0 6.35亿 6 2024-11-21 三滴血 0 1851.2万 7 2024-11-21 不该停止的追问 0 15.8万 8 2024-11-21 浪浪人生 0 4.48亿 9 2024-11-21 开心岭 0 114.7万 列名信息: 1. 日期 2. 电影名称 3. 上映天数 4. 累计票房 5. 单日票房 6. 票房占比 7. 排片占比 8. 上座率 9. 平均票价 10. 场次 11. 人次 爬虫执行完成! 数据统计: 日期范围: 2024-11-21 到 2024-11-23 电影数量: 84 总记录数: 252 数据质量检查: 上映天数为空: 0 累计票房为空: 0 单日票房为空: 0 Process finished with exit code 0怎么解决,且2024-11-21 鬼灭之刃:无限城篇 第一章 猗窝座再袭 0 4.61亿 1 2024-11-21 惊天魔盗团3 0 1.94亿 2 2024-11-21 菜肉馄饨 0 1626.2万 3 2024-11-21 狂野时代 0 22.5万 都是2025.11.20的数据,却显示2024,请给出完整代码
11-22
simple-ecommerce/ │ ├── pom.xml │ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/example/ecommerce/ │ │ │ ├── EcommerceApplication.java │ │ │ │ │ │ │ ├── controller/ │ │ │ │ ├── UserController.java │ │ │ │ ├── ProductController.java │ │ │ │ ├── OrderController.java │ │ │ │ ├── CommentController.java │ │ │ │ └── StatisticController.java │ │ │ │ │ │ │ ├── service/ │ │ │ │ ├── UserService.java │ │ │ │ ├── ProductService.java │ │ │ │ ├── OrderService.java │ │ │ │ ├── CommentService.java │ │ │ │ └── StatisticService.java │ │ │ │ │ │ │ ├── mapper/ │ │ │ │ ├── UserMapper.java │ │ │ │ ├── ProductMapper.java │ │ │ │ ├── OrderMapper.java │ │ │ │ └── CommentMapper.java │ │ │ │ │ │ │ ├── model/ │ │ │ │ ├── User.java │ │ │ │ ├── Product.java │ │ │ │ ├── Order.java │ │ │ │ └── Comment.java │ │ │ │ │ │ │ └── config/ │ │ │ └── WebConfig.java │ │ │ │ │ ├── resources/ │ │ │ ├── application.properties │ │ │ ├── static/ │ │ │ │ └── css/ │ │ │ │ └── style.css │ │ │ │ │ │ │ └── templates/ │ │ │ ├── login.html │ │ │ ├── register.html │ │ │ ├── product_list.html │ │ │ ├── cart.html │ │ │ ├── order_list.html │ │ │ ├── admin_product_manage.html │ │ │ └── comment_section.html │ │ │ │ │ └── webapp/ │ │ └── WEB-INF/ │ │ └── jsp/ │ │ ├── user_login.jsp │ │ ├── user_register.jsp │ │ ├── product_list.jsp │ │ ├── cart.jsp │ │ ├── order_list.jsp │ │ ├── admin_product_manage.jsp │ │ └── comment_section.jsp │ │ │ └── test/ │ └── java/ │ └── com/example/ecommerce/ │ └── EcommerceApplicationTests.java │ └── README.md 根据上述项目架构,分析是否缺少代码,并将所有代码根据之前的修改意见重新修改后的全部发给我,不要有遗漏,若有缺少的代码也给我发送过来,不要有任何省略
最新发布
12-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值