當前位置:
首頁 > 知識 > Python 爬取貓眼數據分析《無名之輩》為何能逆襲成黑馬?

Python 爬取貓眼數據分析《無名之輩》為何能逆襲成黑馬?

Python 爬取貓眼數據分析《無名之輩》為何能逆襲成黑馬?

打開今日頭條,查看更多精彩圖片

作者 | 羅昭成

責編 | 唐小引

出品 | CSDN(ID:CSDNNews)

最近幾天,有部國產電影因好評及口碑傳播而開始異軍突起以黑馬之勢逆襲,在朋友圈以及微博上都會不時看到相關內容,那便是由陳建斌、任素汐等主演的《無名之輩》。這樣一部沒有什麼特別大牌或流量明星,甚至名稱與海報都沒有什麼特色的國產電影卻引起了很多人的注意,更是在評分上直接將同期的如《毒液》、《神奇動物:格林德沃之罪》給 PK 了下去。這部劇從 16 日上映到現在,豆瓣評分 8.3 分,其中 5 星好評占 34.8%,而在貓眼上好評則直接超過了 50%。看這個數據,還是一部不錯的國產劇。在一個貌似平常的日子,筆者用著一台低配的 Mac 電腦跑了一下《無名之輩》貓眼的評論數據,來看看這部小成本喜劇片究竟值不值得看。

Python 爬取貓眼數據分析《無名之輩》為何能逆襲成黑馬?

需要特別說明一下,為什麼要用貓眼的數據,而不用豆瓣的?主要還是因為豆瓣是直接渲染的 HTML,而貓眼的數據是 JSON,處理起來比較方便。

1.獲取貓眼介面數據

作為一個長期宅在家的程序員,對各種抓包簡直是信手拈來。在 Chrome 中查看原代碼的模式,可以很清晰地看到介面,介面地址即為:


http://m.maoyan.com/mmdb/comments/movie/1208282.json?_v_=yes&offset=15

在 Python 中,我們可以很方便地使用 request 來發送網路請求,進而拿到返回結果:

def getMoveinfo(url):
session = requests.Session()
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X)"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
return response.text
return None

根據上面的請求,我們能拿到此介面的返回數據,數據內容有很多信息,但有很多信息是我們並不需要的,先來總體看看返回的數據:

{
"cmts":[
{
"approve":0,
"approved":false,
"assistAwardInfo":{
"avatar":"",
"celebrityId":0,
"celebrityName":"",
"rank":0,
"title":""
},
"authInfo":"",
"cityName":"貴陽",
"content":"必須十分,借錢都要看的一部電影。",
"filmView":false,
"id":1045570589,
"isMajor":false,
"juryLevel":0,
"majorType":0,
"movieId":1208282,
"nick":"nick",
"nickName":"nickName",
"oppose":0,
"pro":false,
"reply":0,
"score":5,
"spoiler":0,
"startTime":"2018-11-22 23:52:58",
"supportComment":true,
"supportLike":true,
"sureViewed":1,
"tagList":{
"fixed":[
{
"id":1,
"name":"好評"
},
{
"id":4,
"name":"購票"
}
]
},
"time":"2018-11-22 23:52",
"userId":1871534544,
"userLevel":2,
"videoDuration":0,
"vipInfo":"",
"vipType":0
}
]
}

如此多的數據,我們感興趣的只有以下這幾個欄位:

nickName, cityName, content, startTime, score

接下來,進行我們比較重要的數據處理,從拿到的JSON數據中解析出需要的欄位:

def parseInfo(data):
data = json.loads(html)["cmts"]
for item in data:
yield{
"date":item["startTime"],
"nickname":item["nickName"],
"city":item["cityName"],
"rate":item["score"],
"conment":item["content"]
}

拿到數據後,我們就可以開始數據分析了。但是為了避免頻繁地去貓眼請求數據,需要將數據存儲起來,在這裡,筆者使用的是 SQLite3,放到資料庫中,更加方便後續的處理。存儲數據的代碼如下:

def saveCommentInfo(moveId, nikename, comment, rate, city, start_time)
conn = sqlite3.connect("unknow_name.db")
conn.text_factory=str
cursor = conn.cursor()
ins="insert into comments values (?,?,?,?,?,?)"
v = (moveId, nikename, comment, rate, city, start_time)
cursor.execute(ins,v)
cursor.close()
conn.commit()
conn.close()

2.數據處理

因為前文我們是使用資料庫來進行數據存儲的,因此可以直接使用 SQL 來查詢自己想要的結果,比如評論前五的城市都有哪些:

SELECT city, count(*) rate_count FROM comments GROUP BY city ORDER BY rate_count DESC LIMIT 5

結果如下:

Python 爬取貓眼數據分析《無名之輩》為何能逆襲成黑馬?

從上面的數據, 我們可以看出來,來自北京的評論數最多。

不僅如此,還可以使用更多的 SQL 語句來查詢想要的結果。比如每個評分的人數、所佔的比例等。如筆者有興趣,可以嘗試著去查詢一下數據,就是如此地簡單。

而為了更好地展示數據,我們使用 Pyecharts 這個庫來進行數據可視化展示。

根據從貓眼拿到的數據,按照地理位置,直接使用 Pyecharts 來在中國地圖上展示數據:

data = pd.read_csv(f,sep="{",header=None,encoding="utf-8",names=["date","nickname","city","rate","comment"])
city = data.groupby(["city"])
city_com = city["rate"].agg(["mean","count"])
city_com.reset_index(inplace=True)
data_map = [(city_com["city"][i],city_com["count"][i]) for i in range(0,city_com.shape[0])]
geo = Geo("GEO 地理位置分析",title_pos = "center",width = 1200,height = 800)
while True:
try:
attr,val = geo.cast(data_map)
geo.add("",attr,val,visual_range=[0,300],visual_text_color="#fff",
symbol_size=10, is_visualmap=True,maptype="china")
except ValueError as e:
e = e.message.split("No coordinate is specified for ")[1]
data_map = filter(lambda item: item[0] != e, data_map)
else :
break
geo.render("geo_city_location.html")

註:使用 Pyecharts 提供的數據地圖中,有一些貓眼數據中的城市找不到對應的從標,所以在代碼中,GEO 添加出錯的城市,我們將其直接刪除,過濾掉了不少的數據。

使用 Python,就是如此簡單地生成了如下地圖:

Python 爬取貓眼數據分析《無名之輩》為何能逆襲成黑馬?

從可視化數據中可以看出,既看電影又評論的人群主要分布在中國東部,又以北京、上海、成都、深圳最多。雖然能從圖上看出來很多數據,但還是不夠直觀,如果想看到每個省/市的分布情況,我們還需要進一步處理數據。

而在從貓眼中拿到的數據中,城市包含數據中具備縣城的數據,所以需要將拿到的數據做一次轉換,將所有的縣城轉換到對應省市裡去,然後再將同一個省市的評論數量相加,得到最後的結果。

data = pd.read_csv(f,sep="{",header=None,encoding="utf-8",names=["date","nickname","city","rate","comment"])
city = data.groupby(["city"])
city_com = city["rate"].agg(["mean","count"])
city_com.reset_index(inplace=True)
fo = open("citys.json","r")
citys_info = fo.readlines()
citysJson = json.loads(str(citys_info[0]))
data_map_all = [(getRealName(city_com["city"][i], citysJson),city_com["count"][i]) for i in range(0,city_com.shape[0])]
data_map_list = {}
for item in data_map_all:
if data_map_list.has_key(item[0]):
value = data_map_list[item[0]]
value += item[1]
data_map_list[item[0]] = value
else:
data_map_list[item[0]] = item[1]
data_map = [(realKeys(key), data_map_list[key] ) for key in data_map_list.keys()]

def getRealName(name, jsonObj):
for item in jsonObj:
if item.startswith(name) :
return jsonObj[item]
return name
def realKeys(name):
return name.replace(u"省", "").replace(u"市", "")
.replace(u"回族自治區", "").replace(u"維吾爾自治區", "")
.replace(u"壯族自治區", "").replace(u"自治區", "")

經過上面的數據處理,使用 Pyecharts 提供的 map 來生成一個按省/市來展示的地圖:

def generateMap(data_map):
map = Map("城市評論數", width= 1200, height = 800, title_pos="center")
while True:
try:
attr,val = geo.cast(data_map)
map.add("",attr,val,visual_range=[0,800],
visual_text_color="#fff",symbol_size=5,
is_visualmap=True,maptype="china",
is_map_symbol_show=False,is_label_show=True,is_roam=False,
)
except ValueError as e:
e = e.message.split("No coordinate is specified for ")[1]
data_map = filter(lambda item: item[0] != e, data_map)
else :
break
map.render("city_rate_count.html")

Python 爬取貓眼數據分析《無名之輩》為何能逆襲成黑馬?

當然,我們還可以來可視化一下每一個評分的人數,這個地方採用柱狀圖來顯示:

data = pd.read_csv(f,sep="{",header=None,encoding="utf-8",names=["date","nickname","city","rate","comment"])
# 按評分分類
rateData = data.groupby(["rate"])
rateDataCount = rateData["date"].agg([ "count"])
rateDataCount.reset_index(inplace=True)
count = rateDataCount.shape[0] - 1
attr = [rateDataCount["rate"][count - i] for i in range(0, rateDataCount.shape[0])]
v1 = [rateDataCount["count"][count - i] for i in range(0, rateDataCount.shape[0])]
bar = Bar("評分數量")
bar.add("數量",attr,v1,is_stack=True,xaxis_rotate=30,yaxix_min=4.2,
xaxis_interval=0,is_splitline_show=True)
bar.render("html/rate_count.html")

畫出來的圖,如下所示,在貓眼的數據中,五星好評的佔比超過了 50%,比豆瓣上 34.8% 的五星數據好很多。

Python 爬取貓眼數據分析《無名之輩》為何能逆襲成黑馬?

從以上觀眾分布和評分的數據可以看到,這一部劇,觀眾朋友還是非常地喜歡。前面,從貓眼拿到了觀眾的評論數據。現在,筆者將通過 jieba 把評論進行分詞,然後通過 Wordcloud 製作詞雲,來看看,觀眾朋友們對《無名之輩》的整體評價:

data = pd.read_csv(f,sep="{",header=None,encoding="utf-8",names=["date","nickname","city","rate","comment"])
comment = jieba.cut(str(data["comment"]),cut_all=False)
wl_space_split = " ".join(comment)
backgroudImage = np.array(Image.open(r"./unknow_3.png"))
stopword = STOPWORDS.copy()
wc = WordCloud(width=1920,height=1080,background_color="white",
mask=backgroudImage,
font_path="./Deng.ttf",
stopwords=stopword,max_font_size=400,
random_state=50)
wc.generate_from_text(wl_space_split)
plt.imshow(wc)
plt.axis("off")
wc.to_file("unknow_word_cloud.png")

導出:

Python 爬取貓眼數據分析《無名之輩》為何能逆襲成黑馬?

再說從這張詞雲圖我們可以明顯地看到「小人物」、「好看」、「喜劇」、「演技」這四個字非常地突出,歷來能夠稱得上黑馬的都是小成本並且反映小人物的荒誕喜劇為多,從這四個關鍵詞中我們似乎看出了這部電影究竟為什麼會收穫眾多好評。一如豆瓣上的一條短評所言:「不是愛情,勝似愛情。喪的剛剛好,黑的剛剛好,暖的剛剛好。有人說,中國沒有『治癒系』的電影。從此片起,就有了。看這片,我們笑著流淚。刻畫底層人物的現實主義題材的電影不在少數,但此片是我近年來看過的,最具誠意、三觀最正,也最『哀而不傷』的一部。你將充分感受到什麼叫『真正的演技』,你將看到陳建斌任素汐章宇王硯輝等『頂級演技天團』如何飆戲。真心期盼,從此片起,國產片將真正迎來『好演員+好電影的春天』。」


徵稿啦

CSDN 公眾號秉持著「與千萬技術人共成長」理念,不僅以「極客頭條」、「暢言」欄目在第一時間以技術人的獨特視角描述技術人關心的行業焦點事件,更有「技術頭條」專欄,深度解讀行業內的熱門技術與場景應用,讓所有的開發者緊跟技術潮流,保持警醒的技術嗅覺,對行業趨勢、技術有更為全面的認知。

如果你有優質的文章,或是行業熱點事件、技術趨勢的真知灼見,或是深度的應用實踐、場景方案等的新見解,歡迎聯繫 CSDN 投稿,聯繫方式:微信(guorui_1118,請備註投稿+姓名+公司職位),郵箱(guorui@csdn.net)。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CSDN 的精彩文章:

一個月面試 4 家,3家Offer,來看看面霸真君是如何面試的!
Facebook 正式公開 React Native 重構細節!

TAG:CSDN |