Python分析44130条用户观影数据,挖掘用户与电影之间的隐藏信息!
01、前言
很多电影也上映,看电影前很多人都喜欢去 『豆瓣』 看影评,所以我爬取44130条 『豆瓣』 的用户观影数据,分析用户之间的关系,电影之间的联系,以及用户和电影之间的隐藏关系。
02、爬取观影数据
数据来源
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条用户的名称。
查看网页的标签,可以找到『用户名称』值对应的标签属性。
编程实现
i=0
url = "https://movie.douban.com/subject/24733428/reviews?start=" + str(i * 20)
r = requests.get(url, headers=headers)
r.encoding = 'utf8'
s = (r.content)
selector = etree.HTML(s)
for item in selector.xpath('//*[@class="review-list  "]/div'):
    userid = (item.xpath('.//*[@class="main-hd"]/a[2]/@href'))[0].replace("https://www.douban.com/people/","").replace("/", "")
    username = (item.xpath('.//*[@class="main-hd"]/a[2]/text()'))[0]
    print(userid)
    print(username)
    print("-----")
爬取用户的观影记录
上一步爬取到『用户名称』,接着爬取用户观影记录需要用到『用户名称』。
网页分析
#https://movie.douban.com/people/{用户名称}/collect?start=15&sort=time&rating=all&filter=all&mode=grid
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条观影记录称。
查看网页的标签,可以找到『电影名』值对应的标签属性。
编程实现
url = "https://movie.douban.com/people/mumudancing/collect?start=15&sort=time&rating=all&filter=all&mode=grid"
r = requests.get(url, headers=headers)
r.encoding = 'utf8'
s = (r.content)
selector = etree.HTML(s)
for item in selector.xpath('//*[@class="grid-view"]/div[@class="item"]'):
    text1 = item.xpath('.//*[@class="title"]/a/em/text()')
    text2 = item.xpath('.//*[@class="title"]/a/text()')
    text1 = (text1[0]).replace(" ", "")
    text2 = (text2[1]).replace(" ", "").replace("\n", "")
    print(text1+text1)
    print("-----")
保存到excel
定义表头
# 初始化execl表
def initexcel(filename):
    # 创建一个workbook 设置编码
    workbook = xlwt.Workbook(encoding='utf-8')
    # 创建一个worksheet
    worksheet = workbook.add_sheet('sheet1')
    workbook.save(str(filename)+'.xls')
    ##写入表头
    value1 = [["用户", "影评"]]
    book_name_xls = str(filename)+'.xls'
    write_excel_xls_append(book_name_xls, value1)
excel表有两个标题(用户, 影评)
写入excel
# 写入execl
def write_excel_xls_append(path, value):
    index = len(value)  # 获取需要写入数据的行数
    workbook = xlrd.open_workbook(path)  # 打开工作簿
    sheets = workbook.sheet_names()  # 获取工作簿中的所有表格
    worksheet = workbook.sheet_by_name(sheets[0])  # 获取工作簿中所有表格中的的第一个表格
    rows_old = worksheet.nrows  # 获取表格中已存在的数据的行数
    new_workbook = copy(workbook)  # 将xlrd对象拷贝转化为xlwt对象
    new_worksheet = new_workbook.get_sheet(0)  # 获取转化后工作簿中的第一个表格
    for i in range(0, index):
        for j in range(0, len(value[i])):
            new_worksheet.write(i+rows_old, j, value[i][j])  # 追加写入数据,注意是从i+rows_old行开始写入
    new_workbook.save(path)  # 保存工作簿
定义了写入excel函数,这样爬起每一页数据时候调用写入函数将数据保存到excel中。
最后采集了44130条数据(原本是4614个用户,每个用户大约有500~1000条数据,预计400万条数据)。但是为了演示分析过程,只爬取每一个用户的前30条观影记录(因为前30条是最新的)。
最后这44130条数据会在下面分享给大家。
03、数据分析挖掘
读取数据集
def read_excel():
    # 打开workbook
    data = xlrd.open_workbook('豆瓣.xls')
    # 获取sheet页
    table = data.sheet_by_name('sheet1')
    # 已有内容的行数和列数
    nrows = table.nrows
    datalist=[]
    for row in range(nrows):
        temp_list = table.row_values(row)
        if temp_list[0] != "用户" and temp_list[1] != "影评":
            data = []
            data.append([str(temp_list[0]), str(temp_list[1])])
            datalist.append(data)
    return datalist
从豆瓣.xls中读取全部数据放到datalist集合中。
分析1:电影观看次数排行
###分析1:电影观看次数排行
def analysis1():
    dict ={}
    ###从excel读取数据
    movie_data = read_excel()
    for i in range(0, len(movie_data)):
        key = str(movie_data[i][0][1])
        try:
            dict[key] = dict[key] +1
        except:
            dict[key]=1
    ###从小到大排序
    dict = sorted(dict.items(), key=lambda kv: (kv[1], kv[0]))
    name=[]
    num=[]
    for i in range(len(dict)-1,len(dict)-16,-1):
        print(dict[i])
        name.append(((dict[i][0]).split("/"))[0])
        num.append(dict[i][1])
    plt.figure(figsize=(16, 9))
    plt.title('电影观看次数排行(高->低)')
    plt.bar(name, num, facecolor='lightskyblue', edgecolor='white')
    plt.savefig('电影观看次数排行.png')
分析
- 由于用户信息来源于 『心灵奇旅』 评论,因此其用户观看量最大。
- 最近的热播电影中,播放量排在第二的是 『送你一朵小红花』,信条和拆弹专家2也紧跟其后。
分析2:用户画像(用户观影相同率最高)
###分析2:用户画像(用户观影相同率最高)
def analysis2():
    dict = {}
    ###从excel读取数据
    movie_data = read_excel()
    userlist=[]
    for i in range(0, len(movie_data)):
        user = str(movie_data[i][0][0])
        moive = (str(movie_data[i][0][1]).split("/"))[0]
        #print(user)
        #print(moive)
        try:
            dict[user] = dict[user]+","+str(moive)
        except:
            dict[user] =str(moive)
            userlist.append(user)
    num_dict={}
    # 待画像用户(取第一个)
    flag_user=userlist[0]
    movies = (dict[flag_user]).split(",")
    for i in range(0,len(userlist)):
        #判断是否是待画像用户
        if flag_user != userlist[i]:
            num_dict[userlist[i]]=0
            #待画像用户的所有电影
            for j in range(0,len(movies)):
                #判断当前用户与待画像用户共同电影个数
                if movies[j] in dict[userlist[i]]:
                    # 相同加1
                    num_dict[userlist[i]] = num_dict[userlist[i]]+1
    ###从小到大排序
    num_dict = sorted(num_dict.items(), key=lambda kv: (kv[1], kv[0]))
    #用户名称
    username = []
    #观看相同电影次数
    num = []
    for i in range(len(num_dict) - 1, len(num_dict) - 9, -1):
        username.append(num_dict[i][0])
        num.append(num_dict[i][1])
    plt.figure(figsize=(25, 9))
    plt.title('用户画像(用户观影相同率最高)')
    plt.scatter(username, num, color='r')
    plt.plot(username, num)
    plt.savefig('用户画像(用户观影相同率最高).png')
分析
以用户 『mumudancing』 为例进行用户画像
- 从图中可以看出,与用户 『mumudancing』 观影相同率最高的是:“请带我回布拉格”,其次是“李校尉”。 
- 用户:'绝命纸牌', '笨小孩', '私享史', '温衡', '沈唐', '修左',的观影相同率****相同。 
分析3:用户之间进行电影推荐
###分析3:用户之间进行电影推荐(与其他用户同时被观看过)
def analysis3():
    dict = {}
    ###从excel读取数据
    movie_data = read_excel()
    userlist=[]
    for i in range(0, len(movie_data)):
        user = str(movie_data[i][0][0])
        moive = (str(movie_data[i][0][1]).split("/"))[0]
        #print(user)
        #print(moive)
        try:
            dict[user] = dict[user]+","+str(moive)
        except:
            dict[user] =str(moive)
            userlist.append(user)
    num_dict={}
    # 待画像用户(取第2个)
    flag_user=userlist[0]
    print(flag_user)
    movies = (dict[flag_user]).split(",")
    for i in range(0,len(userlist)):
        #判断是否是待画像用户
        if flag_user != userlist[i]:
            num_dict[userlist[i]]=0
            #待画像用户的所有电影
            for j in range(0,len(movies)):
                #判断当前用户与待画像用户共同电影个数
                if movies[j] in dict[userlist[i]]:
                    # 相同加1
                    num_dict[userlist[i]] = num_dict[userlist[i]]+1
    ###从小到大排序
    num_dict = sorted(num_dict.items(), key=lambda kv: (kv[1], kv[0]))
    # 去重(用户与观影率最高的用户两者之间重复的电影去掉)
    user_movies = dict[flag_user]
    new_movies = dict[num_dict[len(num_dict)-1][0]].split(",")
    for i in range(0,len(new_movies)):
        if new_movies[i] not in user_movies:
            print("给用户("+str(flag_user)+")推荐电影:"+str(new_movies[i]))
分析
以用户 『mumudancing』 为例,对用户之间进行电影推荐
- 根据与用户 『mumudancing』 观影率最高的用户(A)进行进行关联,然后获取用户(A)的全部观影记录 
- 将用户(A)的观影记录推荐给用户 『mumudancing』(去掉两者之间重复的电影)。 
分析4:电影之间进行电影推荐
###分析4:电影之间进行电影推荐(与其他电影同时被观看过)
def analysis4():
    dict = {}
    ###从excel读取数据
    movie_data = read_excel()
    userlist=[]
    for i in range(0, len(movie_data)):
        user = str(movie_data[i][0][0])
        moive = (str(movie_data[i][0][1]).split("/"))[0]
        try:
            dict[user] = dict[user]+","+str(moive)
        except:
            dict[user] =str(moive)
            userlist.append(user)
    movie_list=[]
    # 待获取推荐的电影
    flag_movie = "送你一朵小红花"
    for i in range(0,len(userlist)):
        if flag_movie in dict[userlist[i]]:
             moives = dict[userlist[i]].split(",")
             for j in range(0,len(moives)):
                 if moives[j] != flag_movie:
                     movie_list.append(moives[j])
    data_dict = {}
    for key in movie_list:
        data_dict[key] = data_dict.get(key, 0) + 1
    ###从小到大排序
    data_dict = sorted(data_dict.items(), key=lambda kv: (kv[1], kv[0]))
    for i in range(len(data_dict) - 1, len(data_dict) -16, -1):
            print("根据电影"+str(flag_movie)+"]推荐:"+str(data_dict[i][0]))
分析
以电影 『送你一朵小红花』 为例,对电影之间进行电影推荐
- 获取观看过 『送你一朵小红花』 的所有用户,接着获取这些用户各自的观影记录。 
- 将这些观影记录进行统计汇总(去掉“送你一朵小红花”),然后进行从高到低进行排序,最后可以获取到与电影 『送你一朵小红花』 关联度最高排序的集合。 
- 将关联度最高的前15部电影给用户推荐。 
04、总结
- 分析爬取豆瓣平台数据思路,并编程实现。 
- 对爬取的数据进行分析(电影观看次数排行、用户画像、用户之间进行电影推荐、电影之间进行电影推荐) 
Python分析44130条用户观影数据,挖掘用户与电影之间的隐藏信息!的更多相关文章
- Python爬虫之抓取豆瓣影评数据
		脚本功能: 1.访问豆瓣最受欢迎影评页面(http://movie.douban.com/review/best/?start=0),抓取所有影评数据中的标题.作者.影片以及影评信息 2.将抓取的信息 ... 
- GPIO硬件资源的申请,内核空间和用户空间的数据交换,ioctl(.....),设备文件的自动创建
		1.通过GPIO库函数控制LED open("/dev/myleds",...) close(fd) ----------------------------- ... 
- 用python分析1225万条淘宝数据,终于搞清楚了我的交易行为
		大家好,我是黄同学 
- 基于Python项目的Redis缓存消耗内存数据简单分析(附详细操作步骤)
		目录 1 准备工作 2 具体实施 1 准备工作 什么是Redis? Redis:一个高性能的key-value数据库.支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使 ... 
- 用Python分析北京市蛋壳公寓租房数据
		本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 近期,蛋壳公寓"爆雷"事件持续发酵,期间因拖欠房东房租与租客退款,蛋壳公寓陷入讨 ... 
- Python分析数据难吗?某科技大学教授说,很难但有方法就简单
		用python分析数据难吗?某科技大学的教授这样说,很难,但要讲方法,主要是因为并不是掌握了基础,就能用python来做数据分析的. 所谓python的基础,也就是刚入门的python学习者,学习的基 ... 
- 科学计算:Python 分析数据找问题,并图形化
		对于记录的数据,如何用 Python 进行分析.或图形化呢? 本文将介绍 numpy, matplotlib, pandas, scipy 几个包,进行数据分析.与图形化. 准备环境 Python 环 ... 
- 【可视化分析案例】用python分析B站Top100排行榜数据
		一.数据源 之前,我分享过一期爬虫,用python爬取Top100排行榜: 最终数据结果,是这样的: 在此数据基础上,做python可视化分析. 二.数据读取 首先,读取数据源: # 读取csv数据 ... 
- 用Python抓取并分析了1982场英雄联盟数据,教你开局前预测游戏对局胜负!
		英雄联盟想必大多数读者不会陌生,这是一款来自拳头,由腾讯代理的大型网络游戏,现在一进网吧,你就能发现一大片玩英雄联盟的人.在2017年中国战队无缘鸟巢的世界总决赛后,一大片人选择了弃游,只是终究没躲过 ... 
随机推荐
- 放弃模拟器,安卓手机WiFi投屏到Ubuntu
			曾经使用过一些安卓的模拟器,但是特别占用资源,而且很多平时使用的非游戏生活类App都有兼容性问题,自然最终无奈而放弃了. 现在将学习环境迁移到了Ubuntu平台,发现各个方面还是不错的,平时使用的各种 ... 
- MD5加密以及登录获取设置token
			MD5简介 MD5是不可逆的加密算法,基本上是不可破解的,网上有些破解网站,其实是利用了穷举法,因为MD5生成的串是一样的,他们会将常规的密码生成MD5加密串,保存,然后破解的时候去穷举比对.(应对之 ... 
- 说明位图,矢量图,像素,分辨率,PPI,DPI?
			说明位图,矢量图,像素,分辨率,PPI,DPI? 显示全部 关注者 28 被浏览 7,031 关注问题写回答 邀请回答 添加评论 分享  2 个回答 默认排序 刘凯 21 人赞同了 ... 
- nginx版本无缝升级与回滚
			chookie和session 你们公司的会话保持怎么做的? 1.开发做的:记录用户登陆的状态,将用户登陆状态保存到,redis服务器中,nfs,mysql.  记录用户的登陆状态.  通过登陆用 ... 
- C++知识点案例 笔记-4
			1.纯虚函数 2.抽象类 3.内部类 4.运算符重载 5.类的函数重载 6.友元的函数重载 1.纯虚函数 ==纯虚函数== //有时基类中无法给出函数的具体体现,定义纯虚函数可以为派生函数保留一个函数 ... 
- k8s管理机密信息(12)
			一.启动应用安全信息的保护 1.Secret介绍 应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥.将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 ... 
- Java 常量值的数据类型
			Java 常量值(也叫字面量)和变量一样,也是有数据类型的. 经常有面试题考察你对 Java 常量值数据类型的理解,如下: float a = 3.3; 问你这一行代码是否正确?答案肯定是不正确.为什 ... 
- Centos7.4 docker安装包下载以及离线安装
			docker安装包下载地址:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/ 需要下载一个selinux包:dock ... 
- JS中的高阶函数
			JS中的高阶函数 高阶函数是指以函数作为参数的函数,并且可以将函数作为结果返回的函数. 1. 高阶函数 接受一个或多个函数作为输入 输出一个函数 至少满足以上一个条件的函数 在js的内置对象中同样存在 ... 
- 小程序中在设置了textarea后三个祖级内事件失效
			在一次写小程序项目中收货地址中的详细地址时,我用的是文本域,下边的三个bindtap事件却不能使用了:下图: 报错信息如下图: 通过一番查找以及尝试之后,我发现是因为textarea标签的问题,但是依 ... 
