当前位置: 首页 > news >正文

使用python进行数据分析(二)

0x00目标

对<<功夫>>影片的短评进行数据分析,算是童年回忆吧。
站点: aHR0cHM6Ly93d3cuYmlsaWJpbGkuY29tL2Jhbmd1bWkvbWVkaWEvbWQyODIyNzgyMC8/c3BtX2lkX2Zyb209NjY2LjI1LmJfNzI2NTc2Njk2NTc3NWY2ZDZmNjQ3NTZjNjUuMSNzaG9ydA==
项目结构如下:
在这里插入图片描述

0x01爬虫部分

1.1接口分析

在源代码里也有部分数据,但应该不够。
在这里插入图片描述
这里可以看到是xhr。
在这里插入图片描述
直接在浏览器访问这个接口,可以发现数据全给我们了,因此可以判定没啥反爬。
在这里插入图片描述
在这里插入图片描述
对下一次请求需要拿到cursor,但是最后一次的cursor不知道是什么。那就换一个少评论的影片,观察即可。是0
在这里插入图片描述

总结一下:请求方式为get.携带的参数有media_id,ps,sort,cursor,均不难得到。返回的数据类型是json格式。没什么特别的反爬,注意模拟浏览器即可。

1.2存储设计

这里我将uname,score,disliked,liked,likes,ctime,content写入xls文件里,后面转成了csv方便读取数据,感觉xls还是比csv慢。

1.3程序运行的情况

有如下error:
在这里插入图片描述
在这里插入图片描述
recursion的默认最大深度应该是1000,导入sys 修改下即可,但是这里就浪费了40分钟了,因为没写日志…后面开了个线程

1.4代码

# !/usr/bin/env python
# -*- coding: utf-8 -*-

# @author: yjp
# @software: PyCharm
# @file: main.py
# @time: 2022-09-30 22:57
import sys
import os
import xlwt
import xlrd
from xlutils.copy import copy
from requests_html import HTMLSession
import time
from threading import *
sys.setrecursionlimit(3000)  # 将默认的递归深度修改为3000
session = HTMLSession()

class plSpider(object):
    def __init__(self):
        self.start_url = "https://api.bilibili.com/pgc/review/short/list?media_id=28227820&ps=20&sort=0&cursor={}"
        self.headers = {
            'user-agent' : 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
        }
        self.cnt = 0
    def parse_start_url(self):
        start_url = self.start_url.format(0)
        response = session.get(start_url,headers = self.headers).json()
        self.parse_start_response(response)
    def parse_start_response(self,response):
        data = response["data"]['list']
        cursor = response["data"]["next"]
        self.parse_data(data)
        self.get_next_url(cursor)
    def get_next_url(self,cursor):

        next_url = self.start_url.format(cursor)
        response = session.get(next_url, headers=self.headers).json()
        self.parse_next_response(response)
    def parse_next_response(self,response):
        data = response["data"]['list']
        cursor = response["data"]["next"]
        if cursor == 0:
            exit(0)
        self.parse_data(data)
        self.get_next_url(cursor)
    def parse_data(self,data):
        """
        提取 uname,score,disliked,liked,likes,ctime,content
        :param data:
        :return:
        """

        for item in data:
            self.cnt += 1
            print(f"{self.cnt}")
            uname = item['author']['uname']
            content = item['content']
            score = item['score']
            ctime = item['ctime']
            timeArray = time.localtime(int(ctime))
            otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray)
            disliked, liked, likes = item["stat"]["disliked"],item["stat"]["liked"],item["stat"]["likes"]
            dict = {
                '评论数据':[uname,score,disliked,liked,likes,otherStyleTime,content]
            }
            self.save_excel(dict)
    def save_excel(self, data):
            #传入的是字典
            # data = {
            #     '基本详情': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
            # }
            os_path_1 = os.getcwd() + '/短评数据/'
            if not os.path.exists(os_path_1):
                os.mkdir(os_path_1)
            # os_path = os_path_1 + self.os_path_name + '.xls'
            os_path = os_path_1 + '功夫短评数据1.xls'
            if not os.path.exists(os_path):
                # 创建新的workbook(其实就是创建新的excel)
                workbook = xlwt.Workbook(encoding='utf-8')
                # 创建新的sheet表
                worksheet1 = workbook.add_sheet("评论数据", cell_overwrite_ok=True)
                borders = xlwt.Borders()  # Create Borders
                """定义边框实线"""
                borders.left = xlwt.Borders.THIN
                borders.right = xlwt.Borders.THIN
                borders.top = xlwt.Borders.THIN
                borders.bottom = xlwt.Borders.THIN
                borders.left_colour = 0x40
                borders.right_colour = 0x40
                borders.top_colour = 0x40
                borders.bottom_colour = 0x40
                style = xlwt.XFStyle()  # Create Style
                style.borders = borders  # Add Borders to Style
                """居中写入设置"""
                al = xlwt.Alignment()
                al.horz = 0x02  # 水平居中
                al.vert = 0x01  # 垂直居中
                style.alignment = al
                # 合并 第0行到第0列 的 第0列到第13列
                '''基本详情13'''
                # worksheet1.write_merge(0, 0, 0, 13, '基本详情', style)
                excel_data_1 = ('uname','score','disliked','liked','likes','ctime','content')
                for i in range(0, len(excel_data_1)):
                    worksheet1.col(i).width = 2560 * 3
                    #               行,列,  内容,            样式
                    worksheet1.write(0, i, excel_data_1[i], style)
                workbook.save(os_path)
            # 判断工作表是否存在
            if os.path.exists(os_path):
                # 打开工作薄
                workbook = xlrd.open_workbook(os_path)
                # 获取工作薄中所有表的个数
                sheets = workbook.sheet_names()
                for i in range(len(sheets)):
                    for name in data.keys():
                        worksheet = workbook.sheet_by_name(sheets[i])
                        # 获取工作薄中所有表中的表名与数据名对比
                        if worksheet.name == name:
                            # 获取表中已存在的行数
                            rows_old = worksheet.nrows
                            # 将xlrd对象拷贝转化为xlwt对象
                            new_workbook = copy(workbook)
                            # 获取转化后的工作薄中的第i张表
                            new_worksheet = new_workbook.get_sheet(i)
                            for num in range(0, len(data[name])):
                                new_worksheet.write(rows_old, num, data[name][num])
                            new_workbook.save(os_path)
    def Thread_Run(self):
        Thread(target=self.parse_start_url()).start()

if __name__ == '__main__':
    p = plSpider()
    p.parse_start_url()

0x02数据分析部分

做点简单的分析。
主要从评分情况,评论时间,评论字数,情感分析等入手
在这里插入图片描述
可以看到五星率到达了99.28%,绝大部分人对这部作品还是很认可的。
在这里插入图片描述
评论字数的话,因为是短评,所以每条评论的字数都不多。
出现最多的关键字如下:
在这里插入图片描述

星爷经典电影!!!
词云图如下:
在这里插入图片描述
情感分析的话就不做了,得选一个负面评论多点的例子。

0x03总结

可视化是对数据的进一步挖掘,也是数据价值的体现,可以让人轻松地捕捉到自己想看到的内容。

相关文章:

  • C++实现二分法求零点(二分法求零点)
  • SECS/GEM半导体协议介绍
  • ARM接口实验-LED灯实验(A7核)
  • 经典卷积和深度卷积的神经网络
  • 【C语言】一篇文章彻底搞懂变量和常量
  • CSS基础12-canvas
  • javascript时钟的开发制作
  • 应用层协议 —— HTTP(二)
  • Qt之QCompleter的简单使用(自动补全、文本框提示、下拉框提示含源码+注释)
  • MyBatis-Plus(二)
  • Linux-常见命令(三)
  • 【国庆活动】Spring Boot 必知必会的核心理念(二)
  • c++:程序流程结构,顺序结构,选择结构if else,三目运算符
  • 使用 Amazon Rekognition API 进行文本检测和 OCR
  • 内核驱动踩坑记录
  • 2017年终总结、随想
  • 77. Combinations
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • canvas 高仿 Apple Watch 表盘
  • Python socket服务器端、客户端传送信息
  • python学习笔记-类对象的信息
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 讲清楚之javascript作用域
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 如何在 Tornado 中实现 Middleware
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 我这样减少了26.5M Java内存!
  • 智能合约Solidity教程-事件和日志(一)
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #Z0458. 树的中心2
  • #微信小程序(布局、渲染层基础知识)
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (2)Java 简介
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (二)windows配置JDK环境
  • (利用IDEA+Maven)定制属于自己的jar包
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转) ns2/nam与nam实现相关的文件
  • (转载)Google Chrome调试JS
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .net 获取url的方法
  • .net 提取注释生成API文档 帮助文档
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .NET企业级应用架构设计系列之结尾篇
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • @RestControllerAdvice异常统一处理类失效原因
  • @WebServiceClient注解,wsdlLocation 可配置
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛