电影信息爬取与聚类分析

article/2025/10/9 8:30:34

电影信息爬取与聚类分析

要求:爬取电影相关数据,条数不小于1000,结构自定,要求包含情感信息,类别,评论关键词等,然后基于这些信息根据用户的喜好做相关性聚类。

一、总体设计

(1)爬取豆瓣电影中的50部电影数据,包括片名、国家、时长、主演、导演、类型、评分、评价人数等信息
(2)爬取各部电影的短评数据,包括用户名、评价、评论、赞同数等
(3)对爬取的数据进行处理并写入相应的csv文件中
(4)读取csv文件,对数据进行分析处理,抛去不参与聚类的特征,将非数值型特征转换为数值型特征。
(5)对数据进行降维处理,并通过K-means进行聚类
(6)将聚类结果可视化,并进行结果分析与总结

二、详细设计

(1)爬取豆瓣电影中的50部电影数据,包括片名、国家、时长、主演、导演、类型、评分、评价人数等信息

//导入库函数
import json
import re
import requests
from lxml import etree
import numpy as np
import csvheader = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"}
res = requests.get(url="https://movie.douban.com/top250?start=0&filter=",headers=header)#排名1-20的影片地址
res1 =requests.get(url="https://movie.douban.com/top250?start=225&filter=",headers=header)#排名21-40的影片地址
res.encoding = 'utf8'
res1.encoding = 'utf8'
text = res.text
text1=res1.text
tree = etree.HTML(text)
tree1 = etree.HTML(text1)
items = tree.xpath('//ol/li/div/div[@class="info"]')
items1 = tree1.xpath('//ol/li/div/div[@class="info"]')
director = [] #导演
film = []  #影片名
film_date = []  #上映时间
film_country = []  #拍摄国家
film_type = []  #类型
star = []  #评分
assess_num = []  #评价人数
quote = []  #推荐语
url = []  #影片地址
#获取排名1-20的电影信息
for item in items:film_url = item.xpath("./div[@class='hd']/a/@href")url.append(film_url[0])film_name = item.xpath("./div[@class='hd']/a/span[1]/text()")[0]film.append(film_name)f_info = item.xpath("./div[@class='bd']/p[1]/text()")info_1 = f_info[1].replace("\xa0","").replace("\n"," ").split("/")film_date.append(info_1[0].replace(" ",""))country =info_1[1]film_country.append(country)film_type.append(info_1[2].replace("                         ",""))f_info = f_info[0].replace("\n","").split('       ')director_deal = f_info[4].split(":")[1].replace("主演","").replace("...","").replace("主","").replace("\xa0","").replace("\n"," ")director.append(director_deal) film_star = item.xpath("./div[@class='bd']/div[@class='star']/span[@class='rating_num']/text()")star.append(film_star[0])film_assess = item.xpath("./div[@class='bd']/div[@class='star']/span/text()")[1].replace("人评价","")assess_num.append(film_assess)film_quote = item.xpath("./div[@class='bd']/p/span[@class='inq']/text()")if len(film_quote)==0:film_quote = "无"else:film_quote = film_quote[0]quote.append(film_quote)#获取排名21-40的电影信息
for item in items1:film_url = item.xpath("./div[@class='hd']/a/@href")url.append(film_url[0])film_name = item.xpath("./div[@class='hd']/a/span[1]/text()")[0]film.append(film_name)f_info = item.xpath("./div[@class='bd']/p[1]/text()")info_1 = f_info[1].replace("\xa0","").replace("\n"," ").split("/")film_date.append(info_1[0].replace(" ",""))country =info_1[1]film_country.append(country)film_type.append(info_1[2].replace("                         ",""))f_info = f_info[0].replace("\n","").split('       ')director_deal = f_info[4].split(":")[1].replace("主演","").replace("...","").replace("主","").replace("\xa0","").replace("\n"," ")director.append(director_deal)film_star = item.xpath("./div[@class='bd']/div[@class='star']/span[@class='rating_num']/text()")star.append(film_star[0])film_assess = item.xpath("./div[@class='bd']/div[@class='star']/span/text()")[1].replace("人评价","")assess_num.append(film_assess)film_quote = item.xpath("./div[@class='bd']/p/span[@class='inq']/text()")if len(film_quote)==0:film_quote = "无"else:film_quote = film_quotequote.append(film_quote[0])#获取电影的时长以及主演
actor = []
time = []
for URL in url:header = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"}res = requests.get(url=URL,headers=header)res.encoding = 'utf8'text = res.texttree = etree.HTML(text)items = tree.xpath('//body/div/div[@id="content"]')for item in items:film_actor = item.xpath('./div[@class="grid-16-8 clearfix"]/div[@class="article"]/div[@class="indent clearfix"]/div[@class="subjectwrap clearfix"]/div[@class="subject clearfix"]/div[@id="info"]/span[@class="actor"]/span[@class="attrs"]//text()')film_actor = set(film_actor)film_actor = list(film_actor)film_actor.remove(' / ')p = ' '.join(film_actor)actor.append(p)film_runtime =item.xpath('./div[@class="grid-16-8 clearfix"]/div[@class="article"]/div[@class="indent clearfix"]/div[@class="subjectwrap clearfix"]/div[@class="subject clearfix"]/div[@id="info"]/span[@property="v:runtime"]//text()')time.append(film_runtime[0])//获取电影好评的短评信息,包括用户名、评分、评论内容、赞同人数
header = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"}
coments_data = []
p = 0
for i in url:print(film[p])k = 0;while k < 10:short_view_url = "https://movie.douban.com/subject/{}/comments?start={}&limit=20&sort=new_score&status=P&percent_type=h".format(i.split('/')[-2],str(k*20))r = requests.get(short_view_url,headers=header).texts = etree.HTML(r)infos = s.xpath("//div[@id='comments']/div[@class='comment-item']")check = s.xpath("//div[@id='comments']/div[@class='comment-item']/text()")check = check[0].replace(" ","").replace("\n","")if check !="还没有人写过短评":for info in infos:c_data = []coments_user = info.xpath('./div[@class="comment"]/h3/span[@class="comment-info"]/a/text()')if len(coments_user) == 0:coments_user = "无用户名"else:coments_user = coments_user[0]coments_info = info.xpath('./div[@class="comment"]/p/span/text()')if len(coments_info) == 0:coments_info = ""else:coments_info = coments_info[0]coments_agree_num = info.xpath('./div[@class="comment"]/h3/span[@class="comment-vote"]/span/text()')if len(coments_agree_num) == "":coments_agree_num="0"else:coments_agree_num=coments_agree_num[0]coments_rate = info.xpath('./div[@class="comment"]/h3/span[@class="comment-info"]/span/@title')if(len(coments_rate)==1):coments_rate = "无"coments_time = info.xpath('./div[@class="comment"]/h3/span[@class="comment-info"]/span/@title')[0]else:coments_rate = info.xpath('./div[@class="comment"]/h3/span[@class="comment-info"]/span/@title')[0]coments_time = info.xpath('./div[@class="comment"]/h3/span[@class="comment-info"]/span/@title')[1]c_data.append(film[p])c_data.append(coments_user)c_data.append(coments_info)c_data.append(coments_rate)c_data.append(coments_time)c_data.append(coments_agree_num)coments_data.append(c_data)k += 1p += 1

(2)将爬取的数据进行处理并写入相应的csv文件中

short_view_feature = ["片名","用户名","短评","评价","时间","赞同数"]
with open("short_view.csv","w",encoding="utf8",newline="") as f:writer =csv.writer(f)writer.writerow(short_view_feature)writer.writerows(coments_data)
all_data = []
for i in range(len(film)):A_data = []A_data.append(film[i]) #片名A_data.append(time[i])#时长A_data.append(director[i])#导演 A_data.append(actor[i])#主演A_data.append(film_date[i])#年份A_data.append(film_country[i])#国家/地区A_data.append(film_type[i]) #类型A_data.append(star[i]) #评分A_data.append(assess_num[i])#评价人数A_data.append(quote[i])#推荐语all_data.append(A_data)
feature_name = ["片名","时长","导演","主演","年份","国家/地区","类型","评分","评价人数","推荐语"]
all_data.insert(0,feature_name)
with open("movies.csv","w",encoding="utf8",newline="") as f:writer =csv.writer(f)writer.writerows(all_data)

Csv文件内容如下图
在这里插入图片描述
在这里插入图片描述
(3)读取csv文件,对数据进行分析处理,抛去不参与聚类的特征,将非数值型特征转换为数值型特征。
对数据进行处理,去掉不参与聚类的信息,比如“导演”、“主演”、“推
荐语”等。

import numpy as np
import csv
import pandas as pd
np.set_printoptions(suppress=True)
pd.set_option('display.float_format', lambda x: '%.2f' % x) #为了直观的显示数字,不采用科学计数法movies = pd.read_csv("movies.csv")
movies = movies.drop(["导演","主演","推荐语"],axis = 1)

将非数值型特征转换为数值型特征,比如国家特征,通过对所有电影排序,按照从高到低的出现频率,修改特征值

for i in range(len(movies["时长"])):p=movies["时长"][i].split("分钟")movies["时长"][i] = p[0]for i in range(len(movies["国家/地区"])):p=movies["国家/地区"][i].split(" ")movies["国家/地区"][i] = p[0]country = movies["国家/地区"].value_counts(normalize=True)
country=list(country.index)
for i in range(len(movies["国家/地区"])):p=country.index(movies["国家/地区"][i])movies["国家/地区"][i] = p+1country_chart = {}
for i in country:country_chart[country.index(i)+1] = itype_num = []
type = []
for i in range(len(movies["类型"])):p=len(movies["类型"][i].split(" "))type.append(movies["类型"][i].split(" "))type_num.append(p)movies["类型数量"] = type_num
for x in range(len(type)):for y in range(max(type_num)-len(type[x])):type[x].append("")type = np.array(type)
movies["第一类型"] = type[:,0]
movies["第二类型"] = type[:,1]
movies["第三类型"] = type[:,2]
movies["第四类型"] = type[:,3]
movies =  movies.drop(["类型"],axis = 1)type_all = []
for i in type:for x in range(4):type_all.append(i[x])
type_all = np.array(type_all)data = pd.DataFrame(data = type_all,index = None,columns = ["ALL"])
type_list=data["ALL"].value_counts()
type_name = list(type_list.index)
for i in range(len(movies["第一类型"])):p=type_name.index(movies["第一类型"][i])movies["第一类型"][i] = p
for i in range(len(movies["第二类型"])):p=type_name.index(movies["第二类型"][i])movies["第二类型"][i] = p
for i in range(len(movies["第三类型"])):p=type_name.index(movies["第三类型"][i])movies["第三类型"][i] = p
for i in range(len(movies["第四类型"])):p=type_name.index(movies["第四类型"][i])movies["第四类型"][i] = p
type_chart = {}
for i in type_name:type_chart[type_name.index(i)] = ishort_view = pd.read_csv("short_view.csv")
short_view = short_view.drop(["用户名","短评","时间"],axis = 1)
short_view["评价"].value_counts()
for i in range(len(short_view["评价"])):if short_view["评价"][i] == "力荐":short_view["评价"][i] = 10elif short_view["评价"][i] == "推荐":short_view["评价"][i] = 8elif short_view["评价"][i] == "还行":short_view["评价"][i] = 6elif short_view["评价"][i] == "较差":short_view["评价"][i] = 4else:short_view["评价"][i] = 2

对短评数据进行处理,去除用户名和评论内容,将评价和赞同人数作为聚类特征值,对所有数据进行统计

film_name = list(movies["片名"].values)
goal_10 = []
goal_10_agree = []
goal_8 = []
goal_8_agree = []
goal_6 = []
goal_6_agree = []
goal_4 = []
goal_4_agree = []
goal_2 = []
goal_2_agree = []
for i in film_name:goal_10.append(len(short_view[(short_view["片名"]== i )& (short_view["评价"]==10)]))goal_10_agree.append(sum(short_view[(short_view["片名"]== i )& (short_view["评价"]==10)]["赞同数"]))goal_8.append(len(short_view[(short_view["片名"]== i )& (short_view["评价"]==8)]))goal_8_agree.append(sum(short_view[(short_view["片名"]== i )& (short_view["评价"]==8)]["赞同数"]))goal_6.append(len(short_view[(short_view["片名"]== i )& (short_view["评价"]==6)]))goal_6_agree.append(sum(short_view[(short_view["片名"]== i )& (short_view["评价"]==6)]["赞同数"]))goal_4.append(len(short_view[(short_view["片名"]== i )& (short_view["评价"]==4)]))goal_4_agree.append(sum(short_view[(short_view["片名"]== i )& (short_view["评价"]==4)]["赞同数"]))goal_2.append(len(short_view[(short_view["片名"]== i )& (short_view["评价"]==2)]))goal_2_agree.append(sum(short_view[(short_view["片名"]== i )& (short_view["评价"]==2)]["赞同数"]))movies["力荐人数"] = goal_10
movies["力荐赞同数"] = goal_10_agree
movies["推荐人数"] = goal_8
movies["推荐赞同数"] = goal_8_agree
movies["还行人数"] = goal_6
movies["还行赞同数"] = goal_6_agree
movies["较差人数"] = goal_4
movies["较差赞同数"] = goal_4_agree
movies["很差人数"] = goal_2
movies["很差赞同数"] = goal_2_agree

处理完成后的数据集:
在这里插入图片描述
(4)通过肘部法则和轮廓系数确定聚类的类别数

from matplotlib import pyplot as plt
from sklearn.cluster import k_means
import pandas as pd
from sklearn.metrics import silhouette_score
#肘部法则
file = movies.drop(["片名"],axis = 1)
index = []
inertia = []for i in range(0,10):model = k_means(file,n_clusters = i + 1)index.append(i+1)inertia.append(model[2])plt.plot(index,inertia,"-o")
plt.show()

在这里插入图片描述

from matplotlib import pyplot as plt
from sklearn.cluster import k_means
import pandas as pd
from sklearn.metrics import silhouette_score
#轮廓系数
file = movies.drop(["片名","评分"],axis = 1)
index = []
silhouette = []
for i in range(9):model = k_means(file,n_clusters = i + 2)index.append(i+2)silhouette.append(silhouette_score(file,model[1]))
plt.plot(index,silhouette,"-o")
plt.show()

在这里插入图片描述
(5)通过主成分分析法(pca)对数据进行降维处理

from sklearn.decomposition import PCA
pca=PCA(n_components=3)
X3D=pca.fit_transform(file)
model = k_means(X3D,n_clusters = 2)
cluster_centers = model[0] # 聚类中心数组
cluster_labels = model[1] # 聚类标签数组
ax = plt.subplot(111, projection='3d')
ax.scatter(X3D[cluster_labels ==0,0],X3D[cluster_labels ==0,1],X3D[cluster_labels ==0,2], c='#ff1493', s=20, alpha=1, marker='o')
ax.scatter(X3D[cluster_labels ==1,0], X3D[cluster_labels ==1,0], X3D[cluster_labels ==1,0], c='#3333cc', s=20, alpha=1, marker='^')
ax.scatter(X3D[cluster_labels ==2,0], X3D[cluster_labels ==2,0], X3D[cluster_labels ==2,0], c='#4d3333', s=20, alpha=1, marker='*')
ax.scatter(cluster_centers[:][:,0],cluster_centers[:][:,1],cluster_centers[:][:,2], c='#FF0000', s=50, alpha=1, marker='o')
plt.show()

在这里插入图片描述

pca=PCA(n_components=3)
model = k_means(X3D,n_clusters = 2)
X2D=pca.fit_transform(file)
cluster_centers1 = model[0] # 聚类中心数组
cluster_labels1 = model[1] # 聚类标签数组
plt.scatter(X2D[:,0],X2D[:,1],c=cluster_labels1)

在这里插入图片描述

分析:本来是希望可能将50部电影依据评分聚类成三类,但是结果并不是很理想,虽然在二维的坐标上可以看出数据能被成功划分为三类。其中的原因可能是爬取的50部电影都是9.0评分的优秀电影,所以区分度有点小,于是我决定9分以上的电影爬取25部,9-8分的电影爬取25部,重新用上述方法进行聚类。结果如下:
在这里插入图片描述
查看数据的划分情况
在这里插入图片描述
在这里插入图片描述
从图片中可以看到,除了少数几个点的干扰外,这次聚类的效果还是很不错的,比较成功地将9.0评分的电影和9.0评分以下的电影区分开。分析原因也可以得出,在数据中,某些数据的基数比较大,可能对最后聚类结果的影响也比较大,比如力荐赞同数等数据。


http://chatgpt.dhexx.cn/article/6rbN0w1k.shtml

相关文章

算法推导 | 卷积神经网络(CNN)反向传播

作者丨南柯一梦宁沉沦知乎 编辑丨极市平台 来源丨https://zhuanlan.zhihu.com/p/61898234 多层感知机反向传播的数学推导&#xff0c;主要是用数学公式来进行表示的&#xff0c;在全连接神经网络中&#xff0c;它们并不复杂&#xff0c;即使是纯数学公式也比较好理解。而卷积神…

深入浅出学习Hive

本文是基于CentOS 7.9系统环境&#xff0c;进行hive的学习和使用 一、Hive的简介 1.1 Hive基本概念 (1) 什么是hive Hive是用于解决海量结构化日志的数据统计工具&#xff0c;是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张表&#xff0c;并提供…

你知道豆瓣电影是怎么评分的吗?(实战篇—手把手教你分析豆瓣电影)

点赞再看&#xff0c;养成好习惯 Python版本3.8.0&#xff0c;开发工具&#xff1a;Pycharm 写在前面的话&#xff1a; 如果你是因为看到标题进来的&#xff0c;那恭喜你&#xff0c;又多了一个涨&#xff08;入&#xff09;知&#xff08;坑&#xff09;识的机会。 在这篇豆…

万字入门推荐系统!

最近一周我、强子、Y哥三人&#xff0c;根据自身如何入门推荐系统&#xff0c;再结合三人分别在腾讯做广告推荐、字节做视频推荐、百度做信息流推荐的经历&#xff0c;整理出了这份万字入门推荐系统。内容十分详细&#xff0c;涵盖了推荐系统基础、进阶、实战的全部知识点&…

【原创】LeetCode刷题-Python版

文章目录 LeetCode1、两数之和*2、两数相加3、无重复字符的最长子串**4、寻找两个正序数组的中位数**5、最长回文子串**动态规划思维导图6、Z 字形变换7、整数反转8、字符串转换整数 (atoi)9、回文数10、正则表达式匹配*11、盛最多水的容器*12、整数转罗马数字13、 罗马数字转整…

c语言 字符串切片重组成完整,bash脚本之一(变量+数组)

bash的变量与数组 变量&#xff1a;存储单个元素的内存空间&#xff1b; 也相当于是数组的0号索引。 数组&#xff1a;存储多个元素的连续的内存空间&#xff1b; 一、变量 1、介绍&#xff1a; 任何程序都需要变量。 变量是用来存储数据的。程序指令数据。 按照其变量是否需要…

最重要Python面试题,逻辑题,Python与数学之美

从数学归纳法谈起&#xff1a; 什么是数学归纳法&#xff1f; 从两个有趣的问题谈起&#xff1a; 1&#xff09;怎么证明一堆人中所有人都是希腊人&#xff1f; 2&#xff09;思考题&#xff1a;怎么证明所有人都是秃子&#xff1f; 什么是数学归纳法&#xff1f; 最简单和常…

OpenCV--Python

1、cv2.imread()读入图像&#xff1b;第一个参数为图像路径&#xff1b;第二个为cv2.IMREAD_COLOR&#xff1a;读入彩色图像&#xff1b;cv2.IMREAD_GRAYSCALE:读入灰度图像。 2、显示图像cv2.imshow() 3、保存图像cv2.imwrite() 4、获取视频先创建一个videocapture对象。参…

python - Pandas基础

pandas 简介 基于numpy的工具 高效提供了大量库和一些标准的数据模型 相当于Numpy的一维数组,但是与普通的一维数组不同,Series支持对数据的自定义标签也就是index(索引)&#xff0c;通过索引可以访问Series的元素 Series 索引 简单的创建 import pandas as pd sel pd.…

【阿里内部教程】python初阶:基础语法 python全栈自动化测试系类

目录 很多小伙伴可能都没有看过凡哥的视频&#xff0c;所以大家可能对凡哥不是很了解这里先和大家来个自我介绍 凡哥我已经有着十二年互联网自动化测试和测试开发工程师&#xff0c;拥有丰富的自动化测试平台及测试开发经验&#xff0c;擅长接口测试、Python自动化全栈&#x…

opencv python 常用方法

点击&#xff1a;OpenCV--Python 基本使用 一、基本方法 1、cv2.imread() 读入图像&#xff1b;第一个参数为图像路径&#xff1b;第二个为cv2.IMREAD_COLOR&#xff1a;读入彩色图像&#xff1b;cv2.IMREAD_GRAYSCALE:读入灰度图像。 import cv2 import matplotlib.pyplot …

iOS开发通过微信学习WCDB(四)

最近打算将封装一个基于wcdb操作的数据库私有库&#xff0c;在封装使用的过程中遇到了一些问题&#xff0c;将问题整理了一下&#xff0c;分享给大家。 私有pod库依赖于WCDB 造成lint失败 最开始遇到这个问题的时没有眉目&#xff0c;后来看到打包方式都是静态库&#xff0c;后…

微信移动端数据库组件WCDB系列(二) — 数据库修复三板斧

前言 长久以来SQLite DB都有损坏问题&#xff0c;从Android、iOS等移动系统&#xff0c;到Windows、Linux 等桌面系统都会出现。由于微信所有消息都保存在DB&#xff0c;服务端不保留备份&#xff0c;一旦损坏将导致用户消息被清空&#xff0c;显然不能接受。 我们即将开源的移…

微信 WCDB for Android的接入

接入 WCDB Android 项目接入 WCDB&#xff0c;可以选择通过 Maven 接入或通过 AAR 包接入。 通过 Maven 接入 对于大部分开发者&#xff0c;推荐使用 Maven 接入 WCDB&#xff0c;在 APP 模块的 build.gradle 下添加 WCDB 依赖即可 dependencies {// 修改"1.0.0"…

关于WCDB Swift 的一些简易使用

wcdb 开源地址&#xff1a;https://github.com/Tencent/wcdb 一、wcdb介绍 引用官方说法&#xff1a;“WCDB Swift 是一个易用、高效、完整的移动数据库框架&#xff0c;它基于 SQLite 和 SQLCipher 开发。” 鹅厂出品的值得信赖。于是就打算在新的项目中使用它。 三大特性…

微信 WCDB 正式开源——高效易用的移动数据库框架

前沿介绍 腾讯开源微信数据库框架WCDB,他是一个高效、完整、易用的移动数据库框架&#xff0c;基于SQLCipher&#xff0c;支持iOS, macOS和Android。 便捷地定义表、索引、约束&#xff0c;并进行增删改查操作 项目演示效果如下&#xff1a; 微信 即时通讯软件 微信&#x…

Wcdb android 目录,WCDB漫谈

前言 移动端的数据库选型一直是一个难题&#xff0c;直到前段时间看到了WeMobileDev(微信前端团队)放出了第三个开源组件-WCDB WCDB(WeChat DataBase)是微信官方的移动端数据库组件&#xff0c;致力于提供一个高效、易用、完整的移动端存储方案 微信团队怎么说 基于SQLCipher W…

iOS开发-关于微信WCDB的使用 WCDB嵌套模型的使用

iOS开发-关于微信WCDB的使用 WCDB嵌套模型的使用 前言开发前准备开发关于生成WCDB文件 选择new file即可找到关于嵌套模型的生成 分两步 选择new file即可找到增删改查的封装使用 总结 前言 iOS开发中有需要数据库的存储&#xff0c;表的增删改查等&#xff0c;FMDB和最近流行…

iOS开发通过微信学习WCDB(三)

通过之前的两篇文章对wcdb能够简单的使用了&#xff0c;这些知识储备多时&#xff0c;最近终于可以派上用场了&#xff0c;最近app有一个通讯录的新功能&#xff0c;实现联系人列表的排序&#xff0c;以及检索&#xff0c;刚好可以用用wcdb去实现。 联系人模型的建立 我首先建…

WCDB使用笔记

本地数据加密 由于项目涉及到一些用户隐私数据的存储&#xff0c;所以需要对保存在客户端本地的数据进行加密&#xff0c;以防止用户隐私数据在设备被root的情况下出现泄漏。目前android的本地数据存储基本分为file&#xff0c;sharepreference和database&#xff0c;所以对数…