当前位置:   article > 正文

Python爬取44130条用户观影数据,分析挖掘用户与电影之间的隐藏信息!_根据用户之前观影记录、提问记录或用户提供的反馈分析用户的观看习惯、历史记录以

根据用户之前观影记录、提问记录或用户提供的反馈分析用户的观看习惯、历史记录以

1.前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。

PS:如有需要Python学习资料的小伙伴可以点击下方链接自行获取

Python免费学习资料、代码以及交流解答点击即可加入


看电影前很多人都喜欢去『豆瓣』看影评,所以我爬取44130条『豆瓣』的用户观影数据,分析用户之间的关系,电影之间的联系,以及用户和电影之间的隐藏关系。

 

2.爬取观影数据

数据来源

  1. https://movie.douban.com/

 

在『豆瓣』平台爬取用户观影数据。

爬取用户列表

网页分析

 

为了获取用户,我选择了其中一部电影的影评,这样可以根据评论的用户去获取其用户名称(后面爬取用户观影记录只需要『用户名称』)。

https://movie.douban.com/subject/24733428/reviews?start=0

url中start参数是页数(page*20,每一页20条数据),因此start=0、20、40...,也就是20的倍数,通过改变start参数值就可以获取这4614条用户的名称。

 

 

查看网页的标签,可以找到『用户名称』值对应的标签属性。

编程实现

  1. i=0
  2. url = "https://movie.douban.com/subject/24733428/reviews?start=" + str(i * 20)
  3. r = requests.get(url, headers=headers)
  4. r.encoding = 'utf8'
  5. s = (r.content)
  6. selector = etree.HTML(s)
  7. for item in selector.xpath('//*[@class="review-list "]/div'):
  8. userid = (item.xpath('.//*[@class="main-hd"]/a[2]/@href'))[0].replace("https://www.douban.com/people/","").replace("/", "")
  9. username = (item.xpath('.//*[@class="main-hd"]/a[2]/text()'))[0]
  10. print(userid)
  11. print(username)
  12. print("-----")

爬取用户的观影记录

上一步爬取到『用户名称』,接着爬取用户观影记录需要用到『用户名称』。

网页分析

  1. #https://movie.douban.com/people/{用户名称}/collect?start=15&sort=time&rating=all&filter=all&mode=grid
  2. https://movie.douban.com/people/mumudancing/collect?start=15&sort=time&rating=all&filter=all&mode=grid

通过改变『用户名称』,可以获取到不同用户的观影记录。

url中start参数是页数(page*15,每一页15条数据),因此start=0、15、30...,也就是15的倍数,通过改变start参数值就可以获取这1768条观影记录称。

 

 

查看网页的标签,可以找到『电影名』值对应的标签属性。

编程实现

  1. url = "https://movie.douban.com/people/mumudancing/collect?start=15&sort=time&rating=all&filter=all&mode=grid"
  2. r = requests.get(url, headers=headers)
  3. r.encoding = 'utf8'
  4. s = (r.content)
  5. selector = etree.HTML(s)
  6. for item in selector.xpath('//*[@class="grid-view"]/div[@class="item"]'):
  7. text1 = item.xpath('.//*[@class="title"]/a/em/text()')
  8. text2 = item.xpath('.//*[@class="title"]/a/text()')
  9. text1 = (text1[0]).replace(" ", "")
  10. text2 = (text2[1]).replace(" ", "").replace("\n", "")
  11. print(text1+text1)
  12. print("-----")

保存到excel

定义表头

  1. # 初始化execl表
  2. def initexcel(filename):
  3. # 创建一个workbook 设置编码
  4. workbook = xlwt.Workbook(encoding='utf-8')
  5. # 创建一个worksheet
  6. worksheet = workbook.add_sheet('sheet1')
  7. workbook.save(str(filename)+'.xls')
  8. ##写入表头
  9. value1 = [["用户", "影评"]]
  10. book_name_xls = str(filename)+'.xls'
  11. write_excel_xls_append(book_name_xls, value1)

excel表有两个标题(用户, 影评)

写入excel

  1. # 写入execl
  2. def write_excel_xls_append(path, value):
  3. index = len(value) # 获取需要写入数据的行数
  4. workbook = xlrd.open_workbook(path) # 打开工作簿
  5. sheets = workbook.sheet_names() # 获取工作簿中的所有表格
  6. worksheet = workbook.sheet_by_name(sheets[0]) # 获取工作簿中所有表格中的的第一个表格
  7. rows_old = worksheet.nrows # 获取表格中已存在的数据的行数
  8. new_workbook = copy(workbook) # 将xlrd对象拷贝转化为xlwt对象
  9. new_worksheet = new_workbook.get_sheet(0) # 获取转化后工作簿中的第一个表格
  10. for i in range(0, index):
  11. for j in range(0, len(value[i])):
  12. new_worksheet.write(i+rows_old, j, value[i][j]) # 追加写入数据,注意是从i+rows_old行开始写入
  13. new_workbook.save(path) # 保存工作簿

定义了写入excel函数,这样爬起每一页数据时候调用写入函数将数据保存到excel中。

 

 

最后采集了44130条数据(原本是4614个用户,每个用户大约有500~1000条数据,预计400万条数据)。但是为了演示分析过程,只爬取每一个用户的前30条观影记录(因为前30条是最新的)。

3.数据分析挖掘

读取数据集

  1. def read_excel():
  2. # 打开workbook
  3. data = xlrd.open_workbook('豆瓣.xls')
  4. # 获取sheet页
  5. table = data.sheet_by_name('sheet1')
  6. # 已有内容的行数和列数
  7. nrows = table.nrows
  8. datalist=[]
  9. for row in range(nrows):
  10. temp_list = table.row_values(row)
  11. if temp_list[0] != "用户" and temp_list[1] != "影评":
  12. data = []
  13. data.append([str(temp_list[0]), str(temp_list[1])])
  14. datalist.append(data)
  15. return datalist

 

从豆瓣.xls中读取全部数据放到datalist集合中。

分析1:电影观看次数排行

  1. ###分析1:电影观看次数排行
  2. def analysis1():
  3. dict ={}
  4. ###从excel读取数据
  5. movie_data = read_excel()
  6. for i in range(0, len(movie_data)):
  7. key = str(movie_data[i][0][1])
  8. try:
  9. dict[key] = dict[key] +1
  10. except:
  11. dict[key]=1
  12. ###从小到大排序
  13. dict = sorted(dict.items(), key=lambda kv: (kv[1], kv[0]))
  14. name=[]
  15. num=[]
  16. for i in range(len(dict)-1,len(dict)-16,-1):
  17. print(dict[i])
  18. name.append(((dict[i][0]).split("/"))[0])
  19. num.append(dict[i][1])
  20. plt.figure(figsize=(16, 9))
  21. plt.title('电影观看次数排行(高->低)')
  22. plt.bar(name, num, facecolor='lightskyblue', edgecolor='white')
  23. plt.savefig('电影观看次数排行.png')

分析

1.由于用户信息来源于『心灵奇旅』评论,因此其用户观看量最大。
2.最近的热播电影中,播放量排在第二的是『送你一朵小红花』,信条和拆弹专家2也紧跟其后。

分析2:用户画像(用户观影相同率最高)

  1. ###分析2:用户画像(用户观影相同率最高)
  2. def analysis2():
  3. dict = {}
  4. ###从excel读取数据
  5. movie_data = read_excel()
  6. userlist=[]
  7. for i in range(0, len(movie_data)):
  8. user = str(movie_data[i][0][0])
  9. moive = (str(movie_data[i][0][1]).split("/"))[0]
  10. #print(user)
  11. #print(moive)
  12. try:
  13. dict[user] = dict[user]+","+str(moive)
  14. except:
  15. dict[user] =str(moive)
  16. userlist.append(user)
  17. num_dict={}
  18. # 待画像用户(取第一个)
  19. flag_user=userlist[0]
  20. movies = (dict[flag_user]).split(",")
  21. for i in range(0,len(userlist)):
  22. #判断是否是待画像用户
  23. if flag_user != userlist[i]:
  24. num_dict[userlist[i]]=0
  25. #待画像用户的所有电影
  26. for j in range(0,len(movies)):
  27. #判断当前用户与待画像用户共同电影个数
  28. if movies[j] in dict[userlist[i]]:
  29. # 相同加1
  30. num_dict[userlist[i]] = num_dict[userlist[i]]+1
  31. ###从小到大排序
  32. num_dict = sorted(num_dict.items(), key=lambda kv: (kv[1], kv[0]))
  33. #用户名称
  34. username = []
  35. #观看相同电影次数
  36. num = []
  37. for i in range(len(num_dict) - 1, len(num_dict) - 9, -1):
  38. username.append(num_dict[i][0])
  39. num.append(num_dict[i][1])
  40. plt.figure(figsize=(25, 9))
  41. plt.title('用户画像(用户观影相同率最高)')
  42. plt.scatter(username, num, color='r')
  43. plt.plot(username, num)
  44. plt.savefig('用户画像(用户观影相同率最高).png')

分析

以用户『mumudancing』为例进行用户画像
1.从图中可以看出,与用户『mumudancing』观影相同率最高的是:“请带我回布拉格”,其次是“李校尉”。
2.用户:'绝命纸牌', '笨小孩', '私享史', '温衡', '沈唐', '修左',的观影相同率相同。

分析3:用户之间进行电影推荐

  1. ###分析3:用户之间进行电影推荐(与其他用户同时被观看过)
  2. def analysis3():
  3. dict = {}
  4. ###从excel读取数据
  5. movie_data = read_excel()
  6. userlist=[]
  7. for i in range(0, len(movie_data)):
  8. user = str(movie_data[i][0][0])
  9. moive = (str(movie_data[i][0][1]).split("/"))[0]
  10. #print(user)
  11. #print(moive)
  12. try:
  13. dict[user] = dict[user]+","+str(moive)
  14. except:
  15. dict[user] =str(moive)
  16. userlist.append(user)
  17. num_dict={}
  18. # 待画像用户(取第2个)
  19. flag_user=userlist[0]
  20. print(flag_user)
  21. movies = (dict[flag_user]).split(",")
  22. for i in range(0,len(userlist)):
  23. #判断是否是待画像用户
  24. if flag_user != userlist[i]:
  25. num_dict[userlist[i]]=0
  26. #待画像用户的所有电影
  27. for j in range(0,len(movies)):
  28. #判断当前用户与待画像用户共同电影个数
  29. if movies[j] in dict[userlist[i]]:
  30. # 相同加1
  31. num_dict[userlist[i]] = num_dict[userlist[i]]+1
  32. ###从小到大排序
  33. num_dict = sorted(num_dict.items(), key=lambda kv: (kv[1], kv[0]))
  34. # 去重(用户与观影率最高的用户两者之间重复的电影去掉)
  35. user_movies = dict[flag_user]
  36. new_movies = dict[num_dict[len(num_dict)-1][0]].split(",")
  37. for i in range(0,len(new_movies)):
  38. if new_movies[i] not in user_movies:
  39. print("给用户("+str(flag_user)+")推荐电影:"+str(new_movies[i]))

分析

以用户『mumudancing』为例,对用户之间进行电影推荐
1.根据与用户『mumudancing』观影率最高的用户(A)进行进行关联,然后获取用户(A)的全部观影记录
2.将用户(A)的观影记录推荐给用户『mumudancing』(去掉两者之间重复的电影)。

分析4:电影之间进行电影推荐

  1. ###分析4:电影之间进行电影推荐(与其他电影同时被观看过)
  2. def analysis4():
  3. dict = {}
  4. ###从excel读取数据
  5. movie_data = read_excel()
  6. userlist=[]
  7. for i in range(0, len(movie_data)):
  8. user = str(movie_data[i][0][0])
  9. moive = (str(movie_data[i][0][1]).split("/"))[0]
  10. try:
  11. dict[user] = dict[user]+","+str(moive)
  12. except:
  13. dict[user] =str(moive)
  14. userlist.append(user)
  15. movie_list=[]
  16. # 待获取推荐的电影
  17. flag_movie = "送你一朵小红花"
  18. for i in range(0,len(userlist)):
  19. if flag_movie in dict[userlist[i]]:
  20. moives = dict[userlist[i]].split(",")
  21. for j in range(0,len(moives)):
  22. if moives[j] != flag_movie:
  23. movie_list.append(moives[j])
  24. data_dict = {}
  25. for key in movie_list:
  26. data_dict[key] = data_dict.get(key, 0) + 1
  27. ###从小到大排序
  28. data_dict = sorted(data_dict.items(), key=lambda kv: (kv[1], kv[0]))
  29. for i in range(len(data_dict) - 1, len(data_dict) -16, -1):
  30. print("根据电影"+str(flag_movie)+"]推荐:"+str(data_dict[i][0]))

分析

以电影『送你一朵小红花』为例,对电影之间进行电影推荐
1.获取观看过『送你一朵小红花』的所有用户,接着获取这些用户各自的观影记录。
2.将这些观影记录进行统计汇总(去掉“送你一朵小红花”),然后进行从高到低进行排序,最后可以获取到与电影『送你一朵小红花』关联度最高排序的集合。
3.将关联度最高的前15部电影给用户推荐。

4.总结

1.分析爬取豆瓣平台数据思路,并编程实现。
2.对爬取的数据进行分析(电影观看次数排行、用户画像、用户之间进行电影推荐、电影之间进行电影推荐)

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/841473
推荐阅读
相关标签
  

闽ICP备14008679号