《python項目開發案例集錦》讀書筆記

說明

對本書,基本都是案列;我個人對本書的例子,僅對第13章"開心麻花影視作品分析"感興趣,所以下面的內容主要是對該章進行描述

數據獲取

從網上所說的,用chrome的F12模擬手機對maoyan電影評論進行獲取,方法已經失效,但鏈接依然是可以用的,不知道原來是啥樣的,offset的數字貌似不是分頁的內容

經過測試,offset到99的時候獲取的數據僅僅只有124條(過濾重複後的)

但不影響進行本章節內容的學習

本部分代碼完成的內容主要有

  • 訪問夏洛特煩惱在貓眼的評論鏈接,返回json
  • 解析json數據,存放到panda中
  • 對panda中的數據進行去重,寫到excel文件中

貼出獲取評論內容代碼如下

def getData(totalPage):
    header = {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
        "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36"}
    tomato = pd.DataFrame(columns=['date', 'score', 'city', 'comment', 'nick'])
    i = 1
    while True:
        # 測試用代碼
        print(i)
        if i == totalPage:
            break
        try:
            url = 'http://m.maoyan.com/mmdb/comments/movie/' + filmId + '.json?_v_=yes&offset=' + str(i)
            response = requests.get(url, headers=header)
            # 讀取返回內容
            # print(response.text)
            print(url)
            content = response.text
            total = json.loads(content)['total']
            if total == 0:
                # 結束循環
                break
            else:
                data = json.loads(content)['cmts']
                datah = json.loads(content)['hcmts']
                # print(data)
                for item in data:
                    # print(item)
                    tomato = tomato.append(
                        {'date': item['time'].split(' ')[0], 'city': item.get("cityName", ""),
                         'score': item['score'], 'comment': item['content'],
                         'nick': item['nick']}, ignore_index=True)
                for item in datah:
                    # print(item)
                    tomato = tomato.append(
                        {'date': item['time'].split(' ')[0], 'city': item.get("cityName", ""),
                         'score': item['score'], 'comment': item['content'],
                         'nick': item['nick']}, ignore_index=True)
            i += 1
            time.sleep(2)
        except Exception as ee:
            i += 1
            # 跳出本次循環
            print(ee, url)
            continue
    # 去掉重複數據
    tomato = tomato.drop_duplicates(subset=['date', 'score', 'city', 'comment', 'nick'], keep='first')
    # 生成xlsx文件
    tomato.to_excel(moveName+'.xlsx', sheet_name='data')

得到的文件內容

在這裏插入圖片描述

評論內容生成柱狀圖+折線圖

獲取到了對應的評論信息,只需要讀取進行,利用這些信息去構建想要的柱狀圖、折線圖。panda允許我們對某一列數據做分組和聚合,我們會對score進行聚合,得到mean和count,放到pyecharts中的對應圖表進行展示

pyecharts把結果保存到html文件中

本部分代碼如下

def buildChart():
    # getData(1000)
    # 讀取文件內容
    tomato_com = pd.read_excel(moveName + '.xlsx')
    grouped = tomato_com.groupby(['city'])
    grouped_pct = grouped['score']  # 得到分組後的score
    city_com = grouped_pct.agg(['mean', 'count']) # 對score進行聚合,得到mean和count
    # reset_index可以還原索引,從新變爲默認的整型索引
    city_com.reset_index(inplace=True)
    # 返回浮點數 0.01 返回到後兩位
    city_com['mean'] = round(city_com['mean'], 2)
    city_main = city_com.sort_values('count', ascending=False)[0:10]
    attr = city_main['city']
    v1 = city_main['count']
    v2 = city_main['mean']

    # 柱狀圖的繪製
    bar = Bar({"theme": ThemeType.MACARONS})
    bar.add_xaxis(attr.tolist())
    bar.extend_axis(
            yaxis=opts.AxisOpts(
                # name="評分",
                type_="value",
                min_=0,
                max_=5,
                interval=1,
                axislabel_opts=opts.LabelOpts(formatter="{value} °分"),
            )
        )

    bar.set_global_opts(
        title_opts=opts.TitleOpts(title="主要城市評論數"),
        tooltip_opts=opts.TooltipOpts(
            is_show=True, trigger="axis", axis_pointer_type="cross" # 十字軸
        ),
        xaxis_opts=opts.AxisOpts(
            # name="城市名",
            type_="category",
            axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow"),
        ),
        yaxis_opts=opts.AxisOpts(
            name="評論數量",
            type_="value",
            min_=0,
            max_=10,
            interval=2,
            axislabel_opts=opts.LabelOpts(formatter="{value}"),
            axistick_opts=opts.AxisTickOpts(is_show=True),
            splitline_opts=opts.SplitLineOpts(is_show=True),
        ),
    )

    bar.add_yaxis("評論數", v1.tolist())

    # 折線圖的繪製
    line = (
        Line()
            .add_xaxis(xaxis_data=attr.tolist())
            .add_yaxis(
            series_name="評分",
            yaxis_index=1,
            y_axis=v2.tolist(),
            label_opts=opts.LabelOpts(is_show=True),
            # linestyle_opts=opts.LineStyleOpts(color="#fff"),
            # itemstyle_opts=opts.ItemStyleOpts(
            #     color="red", border_color="#fff", border_width=3
            # ),
            markpoint_opts=opts.MarkPointOpts(
                data=[
                    opts.MarkPointItem(type_="max", name="最大值"),
                    opts.MarkPointItem(type_="min", name="最小值"),
                ]
            ),
        )
        .set_global_opts(
            yaxis_opts=opts.AxisOpts(
                type_="category",
                boundary_gap=False,
                axislabel_opts=opts.LabelOpts(margin=30, color="#ffffff63"),
                axisline_opts=opts.AxisLineOpts(is_show=False),
                axistick_opts=opts.AxisTickOpts(
                    is_show=True,
                    length=250,
                    linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
                ),
                splitline_opts=opts.SplitLineOpts(
                    is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
                ),
            ),
        )
    )
    bar.overlap(line).render(outputHtmlName)

可以看到得到的html文件內容如下

在這裏插入圖片描述

評論內容生成詞雲

圖雲需要首先進行分詞,這裏使用的jieba,讀入詞雲背景.jpg作爲背景模板,如果不設置模板生成是一張矩形圖

得到了分詞的結果,需要對每個詞出現的次數做統計,在詞雲中出現次數越多的詞,繪製字體越大

接着就是繪製到內存中,保存到file

完整代碼如下

def buildWordCloud():
    tomato_com = pd.read_excel(moveName + '.xlsx')
    # 評論內容
    tomato_str = ' '.join(tomato_com['comment'])
    words_list = []
    # 用結巴分詞
    word_generator = jieba.cut_for_search(tomato_str)
    for word in word_generator:
        words_list.append(word)
    words_list = [k for k in words_list if len(k) > 1]
    back_color = imageio.imread(wcMaskFileName)  # 解析該圖片
    wc = WordCloud(background_color='white',  # 背景顏色
                   max_words=200,  # 最大詞數
                   mask=back_color,  # 以該參數值作圖繪製詞雲,這個參數不爲空時,width和height會被忽略
                   max_font_size=300,  # 顯示字體的最大值
                   font_path=fontFileName,  # 字體
                   # random_state=42,  # 爲每個詞返回一個PIL顏色
                   # width=800,  # 圖片的寬
                   # height=600  # 圖片的長
                   )
    tomato_count = collections.Counter(words_list) # 統計元素出現的次數
    wc.generate_from_frequencies(tomato_count) # 給定詞頻去繪製詞
    # 基於彩色圖像生成相應彩色
    image_colors = ImageColorGenerator(back_color)
    # 繪製詞雲
    plt.figure()
    plt.imshow(wc.recolor(color_func=image_colors))
    # 去掉座標軸
    plt.axis('off')
    # 保存詞雲圖片
    wc.to_file(outputWcFileName)

生成的詞雲效果

在這裏插入圖片描述

其餘部分代碼

# -*- coding: utf-8 -*-

import json
import requests
import time
import collections

import pandas as pd
import matplotlib.pyplot as plt
from pyecharts.charts import Line, Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType
from wordcloud import WordCloud, ImageColorGenerator

import jieba
import imageio


filmId = "246082"
moveName = "夏洛特煩惱"
outputHtmlName = "bar_base.html"
wcMaskFileName = "詞雲背景.jpg"
fontFileName = "STFANGSO.ttf"
outputWcFileName = "詞雲.png"


if __name__ == "__main__":
    # 從貓眼電影中獲取數據
    getData(100)

    # 生成對應柱狀圖的的html文件
    buildChart()

    # 生成圖雲
    buildWordCloud()

整個項目代碼下載

CSDN鏈接:https://download.csdn.net/download/zengraoli/12257686

參考鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章