經(jīng)過了前面的努力缓溅,我們成功獲取到了數(shù)據(jù),并且學(xué)會(huì)了保存缤苫,但是只是用網(wǎng)頁展示出來速兔,是不是有一些不夠美觀呢?
所以本節(jié)的內(nèi)容是:數(shù)據(jù)的可視化活玲。拿到了數(shù)據(jù)卻不能使其簡(jiǎn)單易懂并且足夠突出涣狗,那就是不是好的數(shù)據(jù)工程師。
效果圖:
-
本節(jié)需要做的準(zhǔn)備
安裝pyecharts這個(gè)Python的圖表庫:在之前我們安裝了requests舒憾、lxml镀钓、bs4。所以只需要再在cmd里面 pip3 install pyecharts==0.5.6
就OK啦镀迂,如果失敗丁溅,請(qǐng)仔細(xì)閱讀教程:爬蟲入門教程⑥—安裝爬蟲常用工具包.
??ps:由于pyecharts升級(jí)到1.x版本,發(fā)生了較大的變化探遵,所以本教程安裝時(shí)候指定了版本為0.5.6窟赏,否則代碼會(huì)報(bào)錯(cuò)妓柜。
如果報(bào)錯(cuò)ImportError: cannot import name 'Page' from 'pyecharts'
那就是沒有加版本限制導(dǎo)致安裝了最新版的pyecharts,需要先執(zhí)行pip3 uninstall pyecharts
涯穷,按y確認(rèn)之后棍掐,再次執(zhí)行pip3 install pyecharts==0.5.6
。
后續(xù)會(huì)繼續(xù)更新教程的拷况。
?
-
pyecharts簡(jiǎn)介
這是百度echarts圖表庫塌衰,使用Python接口進(jìn)行生成圖表的一個(gè)庫,非常炫酷蝠嘉。在之前繪圖基本上是用的【Matplotlib】這個(gè)庫最疆,這個(gè)庫功能非常強(qiáng)大,但是缺點(diǎn)也比較明顯蚤告,api調(diào)用比較復(fù)雜努酸,新手上手很慢也很難。于是在去年杜恰,陳鍵冬大佬推出了一個(gè)簡(jiǎn)單易用的繪圖庫 pyecharts获诈。
我當(dāng)時(shí)懷著試一試的心情使用了一下,哇心褐,超好用的舔涎,對(duì)新手超友好的,代碼和圖都寫出來了逗爹,非常詳細(xì)亡嫌,同時(shí)配置項(xiàng)也非常清晰。一口氣畫5個(gè)圖都超快超簡(jiǎn)單的~掘而!
-
確定可視化的目標(biāo)
這是很重要的一步挟冠,先確認(rèn)哪些數(shù)據(jù)值得拿來可視化,然后再去編寫代碼袍睡。一部電影的信息有:名字知染、上映日期、地區(qū)斑胜、類型控淡、關(guān)注者數(shù)量。最明顯的當(dāng)然是關(guān)注者數(shù)量排行榜(柱狀圖)止潘,除此之外我還想了幾個(gè):
上映電影類型占比(餅圖)
上映地區(qū)占比(餅圖)
上映日期柱狀圖
-
采集所有電影信息
先上之前的代碼:
import requests
from bs4 import BeautifulSoup # 從bs4引入BeautifulSoup
#請(qǐng)求網(wǎng)頁
# 舊版教程
# url = "https://movie.douban.com/cinema/later/chengdu/"
# response = requests.get(url)
# 2019-12-23更新掺炭,解決不能獲取到響應(yīng)的問題
url = "https://movie.douban.com/cinema/later/chengdu/" # URL不變
# 新增偽裝成Chrome瀏覽器的header
fake_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'
}
response = requests.get(url, headers=fake_headers) # 請(qǐng)求參數(shù)里面把假的請(qǐng)求header加上
soup = BeautifulSoup(response.content.decode('utf-8'), 'lxml')
all_movies = soup.find('div', id="showing-soon") # 先找到最大的div
for each_movie in all_movies.find_all('div', class_="item"): # 從最大的div里面找到影片的div
# print(each_movie) # 輸出每個(gè)影片div的內(nèi)容
all_a_tag = each_movie.find_all('a')
all_li_tag = each_movie.find_all('li')
movie_name = all_a_tag[1].text
moive_href = all_a_tag[1]['href']
movie_date = all_li_tag[0].text
movie_type = all_li_tag[1].text
movie_area = all_li_tag[2].text
movie_lovers = all_li_tag[3].text
print('名字:{},鏈接:{}覆山,日期:{}竹伸,類型:{},地區(qū):{}, 關(guān)注者:{}'.format(
movie_name, moive_href, movie_date, movie_type, movie_area, movie_lovers))
這是數(shù)據(jù)的基礎(chǔ)信息勋篓,我們先全部拿到吧享,然后放進(jìn)一個(gè)list,方便后續(xù)的比較分析處理譬嚣。同時(shí)我們?cè)诖a頂部钢颂,從pyecharts引入Page(在一張圖顯示多個(gè)圖表)、Pie(餅圖)拜银、Bar(柱狀圖)殊鞭。
# 可視化爬取結(jié)果
import requests
from bs4 import BeautifulSoup # 從bs4引入BeautifulSoup
from pyecharts import Page, Pie, Bar # 引入繪圖需要的模塊
#請(qǐng)求網(wǎng)頁
# 舊版教程
# url = "https://movie.douban.com/cinema/later/chengdu/"
# response = requests.get(url)
# 2019-12-23更新,解決不能獲取到響應(yīng)的問題
url = "https://movie.douban.com/cinema/later/chengdu/" # URL不變
# 新增偽裝成Chrome瀏覽器的header
fake_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'
}
response = requests.get(url, headers=fake_headers) # 請(qǐng)求參數(shù)里面把假的請(qǐng)求header加上
soup = BeautifulSoup(response.content.decode('utf-8'), 'lxml')
all_movies = soup.find('div', id="showing-soon") # 先找到最大的div
# 先把所有的數(shù)據(jù)存到這個(gè)list里面
all_movies_info = []
for each_movie in all_movies.find_all('div', class_="item"): # 從最大的div里面找到影片的div
# print(each_movie) # 輸出每個(gè)影片div的內(nèi)容
all_a_tag = each_movie.find_all('a')
all_li_tag = each_movie.find_all('li')
movie_name = all_a_tag[1].text
moive_href = all_a_tag[1]['href']
movie_date = all_li_tag[0].text
movie_type = all_li_tag[1].text
movie_area = all_li_tag[2].text
movie_lovers = all_li_tag[3].text.replace('人想看', '') # 去掉除了數(shù)字之外的字
# 把電影數(shù)據(jù)添加到list
all_movies_info.append({'name': movie_name, 'date': movie_date, 'type': movie_type,
'area': movie_area, 'lovers': movie_lovers})
# print('名字:{}尼桶,日期:{}操灿,類型:{},地區(qū):{}泵督, 關(guān)注者:{}'.format(
# movie_name, movie_date, movie_type, movie_area, movie_lovers))
print(all_movies_info) # 輸出一下檢查數(shù)據(jù)是否傳遞成功
?
-
繪制關(guān)注者排行榜
處理邏輯:首先把所有的電影以關(guān)注者數(shù)量排個(gè)序趾盐,然后從所有電影里面以獲取到電影的名字和電影的關(guān)注者數(shù)量,最后添加到柱狀圖里小腊。
sorted函數(shù)救鲤,第一個(gè)參數(shù)接受一個(gè)可以遍歷的對(duì)象,key參數(shù)接受一個(gè)匿名函數(shù)秩冈,用以指定以遍歷對(duì)象內(nèi)的哪個(gè)元素作為排序的依據(jù)
以下代碼添加到上一個(gè)示例代碼后面即可本缠。
# 繪制關(guān)注者排行榜圖
# i['name'] for i in all_movies_info 這個(gè)是Python的快捷方式,
# 這一句的作用是從all_movies_info這個(gè)list里面依次取出每個(gè)元素入问,
# 并且取出這個(gè)元素的 name 屬性
sort_by_lovers = sorted(all_movies_info, key=lambda x: int(x['lovers']))
all_names = [i['name'] for i in sort_by_lovers]
all_lovers = [i['lovers'] for i in sort_by_lovers]
lovers_rank_bar = Bar('電影關(guān)注者排行榜') # 初始化圖表丹锹,給個(gè)名字
# all_names是所有電影名,作為X軸, all_lovers是關(guān)注者的數(shù)量队他,作為Y軸卷仑。二者數(shù)據(jù)一一對(duì)應(yīng)。
# is_convert=True設(shè)置x麸折、y軸對(duì)調(diào),。is_label_show=True 顯示y軸值垢啼。 label_pos='right' Y軸值顯示在右邊
lovers_rank_bar.add('', all_names, all_lovers, is_convert=True, is_label_show=True, label_pos='right')
lovers_rank_bar # jupyter下直接顯示圖表在輸出框內(nèi)