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

时间:2022-10-02 08:52:30

0x00目标

对<<功夫>>影片的短评进行数据分析,算是童年回忆吧。
站点: aHR0cHM6Ly93d3cuYmlsaWJpbGkuY29tL2Jhbmd1bWkvbWVkaWEvbWQyODIyNzgyMC8/c3BtX2lkX2Zyb209NjY2LjI1LmJfNzI2NTc2Njk2NTc3NWY2ZDZmNjQ3NTZjNjUuMSNzaG9ydA==
项目结构如下:
使用python进行数据分析(二)

0x01爬虫部分

1.1接口分析

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

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

1.2存储设计

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

1.3程序运行的情况

有如下error:
使用python进行数据分析(二)
使用python进行数据分析(二)
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数据分析部分

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

星爷经典电影!!!
词云图如下:
使用python进行数据分析(二)
情感分析的话就不做了,得选一个负面评论多点的例子。

0x03总结

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