天天看點

爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊

作業要求來自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3075

本次爬取的目标日本電影《小偷家族》,是我最喜歡的電影之一,在貓眼上評分為8.0,在衆多電影中并不算優秀的,但是在我心中認為這部電影的地位遠不是評分所能衡量的。

爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊

  • 觀察網頁結構,擷取想要的資料

    如下圖所示,找到含有

    offset和startTime

    的加載條,發現它的

    Response

    中包含我們想要的資料,為

    json

    格式。
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
  • 爬取和存儲影評資料并存入csv檔案中

    源代碼:

    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    import requests
    import json
    import time
    import random
    import csv
    from datetime import datetime, timedelta
    import pymysql
    from sqlalchemy import create_engine
    import sqlite3
    
     
    def get_headers():
        user_agent_list = [
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
            "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
            "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
            "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
            "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
        ]
        user_agent = random.choice(user_agent_list)
        headers = {'User-Agent': user_agent}
        return headers
     
     
    def get_data(url):
        headers = get_headers()
        try:
            with requests.Session() as s:
                response = s.get(url, headers=headers, timeout=3)
                content = response.text
                return content
     
        except Exception as e:
            print(e)
     
     
    # 處理資料
    def parse_data(html):
        try:
            data = json.loads(html)['cmts']  # 将str轉換為json
        except Exception as e:
            return None
     
        comments = []
        for item in data:
            comment = [item['id'], item['nickName'], item["userLevel"], item['cityName'] if 'cityName' in item else '',
                       item['content'].replace('\n', ' '), item['score'], item['startTime']]
            comments.append(comment)
        return comments
     
     
    # 存儲資料
    def save_to_csv():
        start_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # 擷取目前時間,從目前時間向前擷取
     
        end_time = '2018-08-03 00:00:00'  # 影片的上映日期
     
        while start_time > end_time:  # 如果時間開始時間大于結束時間
     
            url = 'http://m.maoyan.com/mmdb/comments/movie/1216365.json?_v_=yes&offset=0&startTime=' + start_time.replace(
                ' ', '%20')
            html = None
     
            try:
                html = get_data(url)
     
            except Exception as e:
     
                time.sleep(0.5)
                html = get_data(url)
     
            else:
                time.sleep(1)
     
            comments = parse_data(html)
     
            if comments:
                start_time = comments[14][-1]  # 獲得末尾評論的時間
                start_time = datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') + timedelta(
                    seconds=-1)  # 轉換為datetime類型,減1秒,避免擷取到重複資料
                start_time = datetime.strftime(start_time, '%Y-%m-%d %H:%M:%S')  # 轉換為str
     
                print(comments)
               
     
                with open("comments.csv", "a", encoding='utf-8_sig', newline='') as csvfile:
                    writer = csv.writer(csvfile)
     
                    writer.writerows(comments)
    
     
    
    if __name__ == '__main__':
        save_to_csv()
       
    
       
             

    View Code

    運作結果圖:

    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
  • 爬取和存儲影評資料并存入資料庫中
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    import sqlite3
    import pandas as pd
    
    
    
    with sqlite3.connect(r'D:\maoyan.sqlite') as db:#儲存檔案為sql
                    comment = pd.DataFrame(comments)#轉化為二維的表格型資料結構
                    #print(comment)
                    comment.to_sql('maoyanex',db)      
  • 爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
  • 詞雲生成結果
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    import jieba
    import wordcloud
    from PIL import Image
    import  numpy as np
    result = jieba.lcut(open('comments.csv',encoding='utf-8').read())
    
    # 2). 打開圖檔
    imageObj = Image.open('./doc/5.jpg')
    cloud_mask = np.array(imageObj)
    
    # 4). 繪制詞雲
    wc = wordcloud.WordCloud(
        mask = cloud_mask,
        background_color='black',
        font_path='./font/msyh.ttf',    # 進行中文資料時
        min_font_size=5,    # 圖檔中最小字型大小;
        max_font_size=50,   # 圖檔中最大字型大小;
        width=500,  # 指定生成圖檔的寬度
        stopwords = {'上海','深圳','北京','可以','好看','電影', '非常', '這個', '那個', '因為', '沒有', '是以', '如果', '演員', '這麼', '那麼', '最後', '就是', '不過', '這個', '一個', '感覺', '這部', '雖然', '不是', '真的', '覺得', '還是', '但是'}#停用詞表
    )
    wc.generate(",".join(result))
    wc.to_file('小偷家族.png')      
     運作結果:
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
     從詞雲中就可以看出,這部電影是一部雖然平淡但又不失感動的感人至深的電影,但也有人認為看不太懂,認為整個情節過于平淡。
  • 評星餅狀圖
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    import pandas as pd
    from pyecharts import Pie  # 導入Pie元件,用于生成餅圖
     
    # pandas讀取資料
    df = pd.read_csv("comments.csv", names=["id", "nickName", "userLevel", "cityName", "content", "score", "startTime"])
     
    attr = ["一星", "二星", "三星", "四星", "五星"]
    score = df.groupby("score").size()  # 分組求和
     
    value = [
        score.iloc[0] + score.iloc[1] + score.iloc[1],
        score.iloc[3] + score.iloc[4],
        score.iloc[5] + score.iloc[6],
        score.iloc[7] + score.iloc[8],
        score.iloc[9] + score.iloc[10],
    ]
     
    pie = Pie('《小偷家族》評星比例', title_pos='center', width=900)
    pie.use_theme("dark")
    pie.add("評分", attr, value, center=[60, 50], radius=[25, 75], rosetype='raea', is_legend_show=True, is_label_show=True)
    pie.render('評星.html')      
     運作效果:
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
     從上面的柱狀圖也可以看出,《小偷家族》這部電影還是高評分還是占據了大部分的,是值得看的優秀的電影。
  • 評星人位置分布
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    import json
    import pandas as pd
    from pyecharts import Style  # 導入Style類,用于定義樣式風格
    from pyecharts import Geo  # 導入Geo元件,用于生成地理坐标類圖
    from pyecharts import Bar # 導入Geo元件,用于生成柱狀圖
    df = pd.read_csv("comments1.csv", names=["id", "nickName", "userLevel", "cityName", "content", "score", "startTime"])
     
     
    # 處理地名資料,解決坐标檔案中找不到地名的問題
    def handle(cities):
        cities = cities.tolist()
     
        # 擷取坐标檔案中所有地名
        data = None
        with open(
                'C:\ProgramData\Anaconda3\Lib\site-packages\pyecharts\datasets\city_coordinates.json',
                mode='r', encoding='utf-8_sig') as f:
            data = json.loads(f.read())  # 将str轉換為json
     
        # # 循環判斷處理
        data_new = data.copy()  # 拷貝所有地名資料
        for city in set(cities):  # 使用set去重
            # 處理地名為空的資料
            if city == '':
                while city in cities:
                    cities.remove(city)
     
            count = 0
            for k in data.keys():
                count += 1
                if k == city:
                    break
                if k.startswith(city):  # 處理簡寫的地名,如 萬甯市 簡寫為 萬甯
                    # print(k, city)
                    data_new[city] = data[k]
                    break
                if k.startswith(city[0:-1]) and len(city) >= 3:  # 查找包含關系的關鍵字等
                    data_new[city] = data[k]
                    break
     
            # 處理不存在的地名
            if count == len(data):
                while city in cities:
                    cities.remove(city)
     
        # 寫入覆寫坐标檔案
        with open(
                'C:\ProgramData\Anaconda3\Lib\site-packages\pyecharts\datasets\city_coordinates.json',
                mode='w', encoding='utf-8_sig') as f:
            f.write(json.dumps(data_new, ensure_ascii=False))  # 将json轉換為str
     
        return cities  # 把city傳回
     
     
    # 生成效果圖
    def render():
        city_counts = df.groupby("cityName").size()
        new_citys = handle(city_counts.index)
     
        tuple_city = list(city_counts.items())
     
        attr_values = []
        for item in tuple_city:
            # print(item[0],end=' ')
            if item[0] in new_citys:
                attr_values.append(item)
     
        # 定義樣式
        style = Style(
            title_color='#fff',
            title_pos='center',
            width=1200,
            height=600,
            background_color='#404a59',
            subtitle_color='#fff'
        )
        #
        # 根據城市資料生成地理坐标圖
        geo = Geo('《小偷家族》評星人位置分布', '圖表來源:貓眼小偷家族', **style.init_style)
        attr, value = geo.cast(attr_values)
     
        geo.add('', attr, value, visual_range=[0, 2500], type="scatter",
                visual_text_color='#fff', symbol_size=10,
                is_visualmap=True, visual_split_number=10)
        geo.render('評星人位置分布-地理坐标圖.html')
     
        # 根據城市資料生成柱狀圖
     
        city_sorted = city_counts.sort_values(ascending=False).head(20)
     
        bar = Bar("《小偷家族》評星人來源排行TOP20", "貓眼小偷家族", **style.init_style)
        attr, value = bar.cast(list(city_sorted.items()))
        bar.add("", attr, value, is_visualmap=True, visual_range=[0, 2500], visual_text_color='#fff', label_color='#fff',
                xaxis_label_textcolor='#fff', yaxis_label_textcolor='#fff', is_more_utils=True,
                is_label_show=True)
        bar.render("評星人來源排行-柱狀圖.html")
     
     
    if __name__ == '__main__':
        render()      
     運作效果圖:
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊
    爬蟲綜合大作業---爬取貓眼電影網上的電影《小偷家族》詳細資訊

     由圖檔可以知道看這部電影的人群主要是較發達城市人群。觀影人群以東部城市為主,觀影的top5城市為深圳、廣州、上海、鄭州、重慶。

    感受:

    這部電影要表達和诠釋的内容太多。 你可以看陽光的一面:幾個沒有任何血緣關系的人,能夠十分融洽的住在一起,并且建構成一個幸福的“家庭”。這是真情,這是溫暖。這也讓你我心生欣慰。 可這部電影的核心卻如整部電影的色調一般是暗黑的,所謂的家庭,所謂的幸福,隻不過是幾個被他人、被社會抛棄的人努力掙紮才換來的短暫時光,現實終究會把美好撕裂,将殘忍真實呈現。累累傷痕明示的家暴、棄屍之罪責卻大于抛棄活人的罪孽、生下孩子就成為母親,卻不濟一個陌生人給予孩子的愛與關懷多。 這都是對現實的正向拷問,對社會的直接質疑。