ビッグデータ可視化 - PythonをベースとしたDouban動画データ可視化解析

ビッグデータ可視化 - PythonをベースとしたDouban動画データ可視化解析

本プロジェクトは、Douban の動画データを統合的に解析し、視覚的に表示することにより、Python ベースのビッグデータ可視化システムを構築することを目的としています。データクローリングを通じてDouban映画データを収集、クリーニング、分析することで、当社は包括的な映画情報プラットフォームを提供し、映画業界のトレンド、映画の評価、俳優の演技を深く理解するためのツールをユーザーに提供します。プロジェクトの主要なステップには、データ収集、データ クリーニング、データ分析、視覚的表示が含まれます。まず、クローラー テクノロジーを使用して、映画の基本情報、評価、コメントなどを含む豊富な映画データを Douban 映画 Web サイトから取得し、Mysql データベースに保存します。次に、データのクリーニングと前処理を通じて、データの品質と一貫性が確保され、その後の分析の精度が向上します。データ分析段階には主に、映画の評価の分布、さまざまな種類の映画の本数の分布、評価、俳優の影響などに関する詳細な調査が含まれます。視覚的に表示する Echarts をベースに、Python のデータ分析ライブラリ (Pandas、NumPy など) と視覚化ライブラリ (Matplotlib、Seaborn など) の助けを借りて、映画データの特徴や傾向をグラフの形で明確に表示できます。 。最後に、分析結果をインタラクティブなビジュアルインターフェイスで表示し、ユーザーはシステムのカスタマイズされたクエリおよびフィルタリング機能を使用して、興味のある映画情報をさらに深く掘り下げることができます。このプロジェクトは、映画愛好家に包括的なデータ参照プラットフォームを提供するだけでなく、映画業界の実務者に業界のトレンドを洞察するためのツールも提供します。

クロールした最後のフィールド情報: 映画名、評価、カバー画像、詳細 URL、公開時間、監督、タイプ、製作国、言語、映画の長さ、映画の紹介、スター率、評価者数、予告編、トップ 5コメント、詳細写真5枚

 for i,moveInfomation in enumerate(moveisInfomation):
        try:
            resultData = {
    
    }
            # 详情
            resultData['detailLink'] = detailUrls[i]
            # 导演(数组)
            resultData['directors'] = ','.join(moveInfomation['directors'])
            # 评分
            resultData['rate'] = moveInfomation['rate']
            # 影片名
            resultData['title'] = moveInfomation['title']
            # 主演(数组)
            resultData['casts'] = ','.join(moveInfomation['casts'])
            # 封面
            resultData['cover'] = moveInfomation['cover']

            # =================进入详情页====================
            detailMovieRes = requests.get(detailUrls[i], headers=headers)
            soup = BeautifulSoup(detailMovieRes.text, 'lxml')
            # 上映年份
            resultData['year'] = re.findall(r'[(](.*?)[)]',soup.find('span', class_='year').get_text())[0]
            types = soup.find_all('span',property='v:genre')
            for i,span in enumerate(types):
                types[i] = span.get_text()
            # 影片类型(数组)
            resultData['types'] = ','.join(types)
            country = soup.find_all('span',class_='pl')[4].next_sibling.strip().split(sep='/')
            for i,c in enumerate(country):
                country[i] = c.strip()
            # 制作国家(数组)
            resultData['country'] = ','.join(country)
            lang = soup.find_all('span', class_='pl')[5].next_sibling.strip().split(sep='/')
            for i, l in enumerate(lang):
                lang[i] = l.strip()
            # 影片语言(数组)
            resultData['lang'] = ','.join(lang)

            upTimes = soup.find_all('span',property='v:initialReleaseDate')
            upTimesStr = ''
            for i in upTimes:
                upTimesStr = upTimesStr + i.get_text()
            upTime = re.findall(r'\d*-\d*-\d*',upTimesStr)[0]
            # 上映时间
            resultData['time'] = upTime
            if soup.find('span',property='v:runtime'):
                # 时间长度
                resultData['moveiTime'] = re.findall(r'\d+',soup.find('span',property='v:runtime').get_text())[0]
            else:
                # 时间长度
                resultData['moveiTime'] = random.randint(39,61)
            # 评论个数
            resultData['comment_len'] = soup.find('span',property='v:votes').get_text()
            starts = []
            startAll = soup.find_all('span',class_='rating_per')
            for i in startAll:
                starts.append(i.get_text())
            # 星星比例(数组)
            resultData['starts'] = ','.join(starts)
            # 影片简介
            resultData['summary'] = soup.find('span',property='v:summary').get_text().strip()

            # 五条热评
            comments_info = soup.find_all('span', class_='comment-info')
            comments = [{
    
    } for x in range(5)]
            for i, comment in enumerate(comments_info):
                comments[i]['user'] = comment.contents[1].get_text()
                comments[i]['start'] = re.findall('(\d*)', comment.contents[5].attrs['class'][0])[7]
                comments[i]['time'] = comment.contents[7].attrs['title']
            contents = soup.find_all('span', class_='short')
            for i in range(5):
                comments[i]['content'] = contents[i].get_text()
            resultData['comments'] = json.dumps(comments)

            # 五张详情图
            imgList = []
            lis = soup.select('.related-pic-bd img')
            for i in lis:
                imgList.append(i['src'])
            resultData['imgList'] = ','.join(imgList)

結果を CSV ファイルと SQL データベースに保存し、完了したらページ数レコードを更新します。

Douban の映画データから俳優と監督の映画数量情報を抽出し、その後の分析と視覚的な表示を可能にします。

def getAllActorMovieNum():
    allData = homeData.getAllData()
    ActorMovieNum = {
    
    }
    for i in allData:
        for j in i[1]:
            if ActorMovieNum.get(j,-1) == -1:
                ActorMovieNum[j] = 1
            else:
                ActorMovieNum[j] = ActorMovieNum[j] + 1
    ActorMovieNum = sorted(ActorMovieNum.items(), key=lambda x: x[1])[-20:]
    x = []
    y = []
    for i in ActorMovieNum:
        x.append(i[0])
        y.append(i[1])
    return x,y

監督が監督した映画の数をカウントする関数 getAllDirectorMovieNum() を定義します。

def getAllDirectorMovieNum():
    allData = homeData.getAllData()
    ActorMovieNum = {
    
    }
    for i in allData:
        for j in i[4]:
            if ActorMovieNum.get(j,-1) == -1:
                ActorMovieNum[j] = 1
            else:
                ActorMovieNum[j] = ActorMovieNum[j] + 1
    ActorMovieNum = sorted(ActorMovieNum.items(), key=lambda x: x[1])[-20:]
    x = []
    y = []
    for i in ActorMovieNum:
        x.append(i[0])
        y.append(i[1])
    return x,y
  1. allData = homeData.getAllData():homeDataモジュール内の関数を呼び出してgetAllData、すべてのムービー データを取得し、allData変数に保存します。
  2. ActorMovieNum = {}ActorMovieNum:監督と監督した映画の数とのマッピングを保存する空の辞書を作成します。
  3. for i in allData:i:各映画の情報を表すすべての映画データを走査します。
  4. for j in i[4]:: 各映画の情報で、i[4]ディレクターの情報にアクセスし、各ディレクターを反復処理します。
  5. if ActorMovieNum.get(j, -1) == -1::ActorMovieNumディレクターのレコードが辞書にすでに存在するかどうかを確認してください。存在しない場合は、director をキーとして辞書に追加し、対応する値を 1 に初期化します。
  6. else:: 監督のレコードが辞書にすでに存在する場合は、対応する値に 1 を加算し、監督が別の映画を監督したことを示します。
  7. ActorMovieNum = sorted(ActorMovieNum.items(), key=lambda x: x[1])[-20:]: 辞書に登録されている監督とその作品数を映画数の多い順にソートし、ソート後の最初の 20 項目を取得します。ソートの基本はkey=lambda x: x[1]、辞書の値に従ってソートすることです。
  8. x = []およびy = []: 監督名と監督された映画の対応する数を保存する 2 つの空のリストを作成します。
  9. for i in ActorMovieNum:: ソートされた上位 20 人の監督とその監督した映画の数を横断します。
  10. x.append(i[0])およびy.append(i[1]): 監督の名前と監督した映画の数をそれぞれリストに追加しxますy
  11. return x, y: 監督の名前と監督された映画の数を保存する 2 つのリストを返します。

という名前のモジュールから関数homeDataをインポートしgetAllData、ライブラリを使用してpandasDataFrame を作成しますdfgetAllData関数の戻り値はDataFrame、データ フレームの列名を指定してコンストラクターに渡されます。

  1. from . import homeData: このコード行は、現在のディレクトリ (現在のディレクトリを意味します) からモジュール.をインポートします。homeData
  2. import pandas as ps: このコード行はpandasライブラリをインポートし、それをpsエイリアスとして使用します。一般にpandasエイリアスは ですpdが、ここではそれを使用しますps
  3. df = ps.DataFrame(homeData.getAllData(), columns=[...]): このコード行はデータ フレームを作成しdfhomeData.getAllData()そのデータ フレームに の戻り値を入れます。列名はcolumnsパラメータで指定され、列の順序はリスト内の順序に対応します。列名には次のものが含まれます。
    • 'id': 映画ID
    • 「ディレクター」: ディレクター
    • 「レート」: 評価
    • 'タイトル': タイトル
    • 「キャスト」: 俳優
    • 「カバー」: カバー
    • '年': リリース年
    • 'タイプ': タイプ
    • 「国」: 生産国
    • 'lang': 言語
    • 'time': 期間
    • 'moveiTime': 映画の長さ
    • 'comment_len': コメントの長さ
    • 'starts': 星評価
    • 「概要」: 概要
    • 'コメント': コメント
    • 'imgList': 画像リスト
    • 'movieUrl': 映画のリンク
    • 'detailLink': 詳細リンク

homeData.getAllData()これにより、関数から返されたデータを使用して、特定の列名を含むデータ フレームが作成されます。

from . import homeData
import pandas as ps
df = ps.DataFrame(homeData.getAllData(),columns=[
        'id',
        'directors',
        'rate',
        'title',
        'casts',
        'cover',
        'year',
        'types',
        'country',
        'lang',
        'time',
        'moveiTime',
        'comment_len',
        'starts',
        'summary',
        'comments',
        'imgList',
        'movieUrl',
        'detailLink'
    ])

DataFrame の「country」列から住所データを抽出します。データフレーム内のアドレスデータを抽出し、各アドレスの出現回数をカウントします。まず、「country」列の各要素をチェックし、要素がリストの場合は、リスト内の各要素を新しいリスト (アドレス) に追加します。次に、アドレスをキー、出現箇所を値として持つ辞書 (addressDic) を作成し、最後にアドレスのリストと対応する出現リストを返します。

def getAddressData():
    # 获取名为 'country' 的列的值
    addresses = df['country'].values
    
    # 创建一个空列表来存储地址
    address = []
    
    # 遍历 'country' 列的每个元素
    for i in addresses:
        # 如果元素是列表类型
        if isinstance(i, list):
            # 遍历列表中的每个元素并添加到 address 列表中
            for j in i:
                address.append(j)
        else:
            # 如果元素不是列表类型,直接将其添加到 address 列表中
            address.append(i)
    
    # 创建一个空字典来存储地址及其出现次数
    addressDic = {
    
    }
    
    # 遍历地址列表中的每个元素
    for i in address:
        # 如果地址字典中不存在该地址,则将其添加并设置出现次数为1
        if addressDic.get(i, -1) == -1:
            addressDic[i] = 1
        else:
            # 如果地址字典中已存在该地址,则将其出现次数加1
            addressDic[i] = addressDic[i] + 1
    
    # 返回地址列表和对应的出现次数列表
    return list(addressDic.keys()), list(addressDic.values())

データ フレームの 'lang' 列から言語データを抽出し、各言語の出現数をカウントします。最後に、言語リストと対応する出現回数リストが返されます。

def getLangData():
    # 获取名为 'lang' 的列的值
    langs = df['lang'].values
    
    # 创建一个空列表来存储语言数据
    languages = []
    
    # 遍历 'lang' 列的每个元素
    for i in langs:
        # 如果元素是列表类型
        if isinstance(i, list):
            # 遍历列表中的每个元素并添加到 languages 列表中
            for j in i:
                languages.append(j)
        else:
            # 如果元素不是列表类型,直接将其添加到 languages 列表中
            languages.append(i)
    
    # 创建一个空字典来存储语言及其出现次数
    langsDic = {
    
    }
    
    # 遍历语言列表中的每个元素
    for i in languages:
        # 如果语言字典中不存在该语言,则将其添加并设置出现次数为1
        if langsDic.get(i, -1) == -1:
            langsDic[i] = 1
        else:
            # 如果语言字典中已存在该语言,则将其出现次数加1
            langsDic[i] = langsDic[i] + 1
    
    # 返回语言列表和对应的出现次数列表
    return list(langsDic.keys()), list(langsDic.values())

データベースに 4 つのテーブルを作成します。
ここに画像の説明を挿入します
ここに画像の説明を挿入します
独自のデータベースのホスト名とアカウントのパスワードに変更します。
ここに画像の説明を挿入します
プロジェクトを開始します。
ここに画像の説明を挿入します

サービスポート: 5000 http://127.0.0.1:5000

ユーザー登録 http://127.0.0.1:5000/registry

ここに画像の説明を挿入します

ユーザーログイン

ここに画像の説明を挿入します

ホームページの表示:

ここに画像の説明を挿入します

映画のタイトル、評価、スタジオ、予告編、その他のデータを含む映画データもあります。

ここに画像の説明を挿入します

映画の予告編を見る

ここに画像の説明を挿入します

映画検索

ここに画像の説明を挿入します

映画制作分析

ここに画像の説明を挿入します

動画データの再生時間配分割合

ここに画像の説明を挿入します

映画評価統計分析

ここに画像の説明を挿入します

ここに画像の説明を挿入します

Douban 評価スター円グラフ、Douban 年間評価評価棒グラフ

ここに画像の説明を挿入します

Douban映画の国内外評価分布表

ここに画像の説明を挿入します

データビュースイッチ

ここに画像の説明を挿入します
ここに画像の説明を挿入します

映画撮影地の統計地図

ここに画像の説明を挿入します

映画言語統計グラフ

ここに画像の説明を挿入します

映画ジャンルの円グラフ

ここに画像の説明を挿入します

作品数別監督トップ20

ここに画像の説明を挿入します

ここに画像の説明を挿入します

データテーブルの操作

ここに画像の説明を挿入します

タイトルワードクラウドチャート

ここに画像の説明を挿入します

はじめにワードクラウドチャート

ここに画像の説明を挿入します
s4XV8qh-1701860368769)

俳優名詞の雲図

ここに画像の説明を挿入します

コメントの単語の雲

ここに画像の説明を挿入します
ここに画像の説明を挿入します

さらに詳しい情報/ビジネス協力/コミュニケーションとディスカッションが必要な場合は、以下に個人の名刺を追加してください。「いいね!」とサポートをありがとうございます。

時間とエネルギーがあれば、ビッグデータの分野に関するさらに質の高いコンテンツを後で共有します。気に入ったら、いいね、フォローして収集してください。いいねとサポートをありがとうございます!

おすすめ

転載: blog.csdn.net/Myx74270512/article/details/134838865