Python使用Web API數據可視化

    Web應用編程接口 (API)自動請求網站的特定信息而不是整個網頁,再對這些信息進行可視化。由於這樣編寫的程序始終使用最新的數據來生成可視化,因此即便數據瞬息萬變,它呈現的信息也都是最新的。

    Web API是網站的一部分,用於與使用非常具體的URL請求特定信息的程序交互。這種請求稱爲API調用。請求的數據將以易於處理的格式(如JSON或CSV)返回。依賴於外部數據源的大多數應用程序都依賴於API調用,如集成社交媒體網站的應用序。

處理API響應

執行API調用並處理結果,找出GitHub上星級最高的Python項目:

python_repos.py

import requests

#執行API調用並存儲響應
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'

r = requests.get(url)    #使用requests 來執行調用,將響應對象存儲在變量r中
print("Status code:",r.status_code)#響應對象包含一個名爲status_code的屬性,它讓我們知道請求是否成功(狀態碼200表示請求成功)
#將API響應存儲在一個變量中
response_dict = r.json()

#處理結果
print(response_dict.keys())

處理響應字典

將API調用返回的信息存儲到字典中後,就可以處理這個字典中的數據了。下面生成一些概述這些信息的輸出。可確認收到了期望的信息,進而可以開始研究感興趣的信息:

import requests

#執行API調用並存儲響應
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'

r = requests.get(url)
print("Status code:",r.status_code)
#將API響應存儲在一個變量中
response_dict = r.json()
print("Total repositories:",response_dict['total_count'])#指出GitHub包含多少個Python倉庫
#探索有關倉庫的信息
repo_dicts=response_dict['items']#response_dict字典存儲在列表中,列表裏每個字典都包含有關一個Python倉庫的信息
print("Repositories returned:",len(repo_dicts))
#研究第一個倉庫
repo_dict = repo_dicts[0]
print("\nKeys:",len(repo_dict))
for key in sorted(repo_dict.keys()):
	print(key)

GitHub的API返回有關每個倉庫的大量信息:repo_dict 包含68個鍵(見❶)。通過仔細查看這些鍵,可大致知道可提取有關項目的哪些信息(要準確地獲悉API將返回哪些信息,要麼閱讀文檔,要麼像此處這樣使用代碼來查看這些信息)。

  Status code: 200
  Total repositories: 713062
  Repositories returned: 30

❶ Keys: 68
  archive_url
  assignees_url
  blobs_url
  --snip--
  url
  watchers
  watchers_count

概述最受歡迎的倉庫

對這些數據進行可視化時,我們需要涵蓋多個倉庫。下面就來編寫一個循環,打印API調用返回的每個倉庫的特定信息,以便能夠在可視化中包含所有這些信息:

--snip--
#研究第一個倉庫
repo_dict = repo_dicts[0]
print("\nKeys:",len(repo_dict))
for key in sorted(repo_dict.keys()):
	print(key)

print("\nSelected information about first repository:")
for repo_dict in repo_dicts:
	print('\nName:', repo_dict['name'])
	print('Owner:', repo_dict['owner']['login'])
	print('Stars:', repo_dict['stargazers_count'])
	print('Repository:', repo_dict['html_url'])
	print('Description:', repo_dict['description'])

監視API的速率限制

大多數API都存在速率限制,即你在特定時間內可執行的請求數存在限制。要獲悉你是否接近了GitHub的限制,請在瀏覽器中輸入https://api.github.com/rate_limit ,你將看到類似於下面的響應:

{
  "resources": {
    "core": {
      "limit": 60,
      "remaining": 60,
      "reset": 1521446243
    },
    "search": {#搜索API的速率限制
      "limit": 10,#極限爲每分鐘10個請求
      "remaining": 10,#在當前這一分鐘內,我們還可執行10個請求
      "reset": 1521442703#配額將重置的Unix時間或新紀元時間(1970年1月1日午夜後多少秒)
    },
    "graphql": {
      "limit": 0,
      "remaining": 0,
      "reset": 1521446243
    }
  },
  "rate": {
    "limit": 60,
    "remaining": 60,
    "reset": 1521446243
  }
}

使用Pygal可視化倉庫

有了一些有趣的數據後,我們來進行可視化,呈現GitHub上Python項目的受歡迎程度。我們將創建一個交互式條形圖:條形的高度表示項目獲得了多少顆星。單擊條形將帶你進入項目在GitHub上的主頁。下面是首次嘗試這樣做:

import requests
import pygal
from pygal.style import LightColorizedStyle as LCS,LightenStyle as LS
#執行API調用並存儲響應
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'

r = requests.get(url)
print("Status code:",r.status_code)
#將API響應存儲在一個變量中
response_dict = r.json()
print("Total repositories:",response_dict['total_count'])#指出GitHub包含多少個Python倉庫
#探索有關倉庫的信息
repo_dicts=response_dict['items']#response_dict字典存儲在列表中,列表裏每個字典都包含有關一個Python倉庫的信息
names,stars = [],[]
for repo_dict in repo_dicts:
	names.append(repo_dict['name'])
	stars.append(repo_dict['stargazers_count'])

#可視化
my_style = LS('#333366',base_style=LCS)
chart = pygal.Bar(style=my_style,x_label_rotation=45,show_legend=False)#創建條形圖,讓標籤繞x軸旋轉45度(x_label_rotation=45 ),隱藏圖例(show_legend=False )
chart.title = 'Most-Starred Python Projects on GitHub'#指定標題
chart.x_labels=names#橫座標標籤
chart.add('',stars)#添加數據,標籤設置成空字符串
chart.render_to_file('python_repos.svg')

改進Pygal圖表

進行多個方面的定製,因此先來稍微調整代碼的結構,創建一個配置對象,在其中包含要傳遞給Bar() 的所有定製:

--snip--
#可視化
my_style = LS('#333366',base_style=LCS)
my_config = pygal.Config()#創建Pygal類Config實例,通過修改my_config定製圖表外觀
my_config.x_label_rotation = 45#讓標籤繞x軸旋轉45度(x_label_rotation=45 )
my_config.show_legend = False#隱藏圖例(show_legend=False )
my_config.title_font_size = 24#圖表標題
my_config.lable_font_size =14#副標籤(X軸項目名及Y軸大部分數字)
my_config.major_label_font_size = 18#主標籤(Y軸5000整數倍的刻度)
my_config.truncate_label =15#將較長的項目名縮短爲15個字符
my_config.show_y_guides = False#隱藏圖表中的水平線
my_config.width = 1000#自定義寬度

chart = pygal.Bar(my_config,style=my_style)#通過my_config傳遞所有配置設置
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels=names
chart.add('',stars)
chart.render_to_file('python_repos.svg')

添加自定義工具提示

在Pygal中,將鼠標指向條形將顯示它表示的信息,這通常稱爲工具提示 。在這個示例中,當前顯示的是項目獲得了多少個星。下面來創建一個自定義工具提示,以同時顯示項目的描述。來看一個簡單的示例,它可視化前三個項目,並給每個項目對應的條形都指定自定義標籤。爲此,我們向add() 傳遞一個字典列表,而不是值列表:

bar_descriptions.py

import pygal
from pygal.style import LightColorizedStyle as LCS,LightenStyle as LS

my_style = LS('#333366',base_style = LCS)
chart = pygal.Bar(style=my_style,x_label_rotation =45,show_legend=False)

chart.title ='Python Projects'
chart.x_labels = ['httpie','django','flask']
plot_dicts = [
	{'value': 16101, 'label': 'Description of httpie.'},
	{'value': 15028, 'label': 'Description of django.'},
	{'value': 14798, 'label': 'Description of flask.'},
	]

chart.add('', plot_dicts)
chart.render_to_file('bar_descriptions.svg')

        定義了一個名爲plot_dicts的列表,其中包含三個字典,分別針對項目HTTPie、Django和Flask。每個字典都包含兩個鍵:'value' 和'label' 。Pygal根據與鍵'value' 相關聯的數字來確定條形的高度,並使用與'label' 相關聯的字符串給條形創建工具提示。第一個字典將創建一個條形,用於表示一個獲得了16 101顆星、工具提示爲Description of httpie的項目。方法add() 接受一個字符串和一個列表。這裏調用add() 時,我們傳入了一個由表示條形的字典組成的列表(plot_dicts )。結果顯示了一個工具提示:除默認工具提示(獲得的星數)外,Pygal還顯示了我們傳入的自定義提示。


--snip--
#探索有關倉庫的信息
repo_dicts=response_dict['items']#response_dict字典存儲在列表中,列表裏每個字典都包含有關一個Python倉庫的信息

names,plot_dicts = [],[]
for repo_dict in repo_dicts:
	names.append(repo_dict['name'])
	plot_dict ={
		'value':repo_dict['stargazers_count'],
		'label':str(repo_dict['description']),
		}
	plot_dicts.append(plot_dict)

#可視化
my_style = LS('#333366',base_style=LCS)
--snip--

chart.add('',plot_dicts)
chart.render_to_file('python_repos.svg')

在圖表中添加可單擊的鏈接

--snip--
        plot_dict ={
		'value':repo_dict['stargazers_count'],
		'label':str(repo_dict['description']),
		'xlink':repo_dict['html_url'],
		}
--snip--

Pygal根據與鍵'xlink' 相關聯的URL將每個條形都轉換爲活躍的鏈接。單擊圖表中的任何條形時,都將在瀏覽器中打開一個新的標籤頁,並在其中顯示相應項目的GitHub頁面。至此,你對API獲取的數據進行了可視化,它是交互性的,包含豐富的信息!

Hacker News API
在Hacker News網站,用戶分享編程和技術方面的文章,並就這些文章展開積極的討論。Hacker News的API讓你能夠訪問有關該網站所有文章和評論的信息,且不要求你通過註冊獲得密鑰。執行一個API調用,返回Hacker News上當前熱門文章的ID,再查看每篇排名靠前的文章:
import requests
from operator import itemgetter
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS


#執行API調用並存儲響應
url = 'https://hacker-news.firebaseio.com/v0/topstories.json'
r = requests.get(url)
#打印請求狀態(200表示成功)
print("Status code:",r.status_code)

#處理有關每篇文章的信息
#將包含ID信息的響應文本轉換爲列表
submission_ids = r.json()
#創建空列表存儲文章信息(字典)
submission_dicts = []

#通過ID遍歷前30篇文章,並執行API調用
for submission_id in submission_ids[:3]:
	#對於每篇文章都執行一個API調用
	url = ('https://hacker-news.firebaseio.com/v0/item/' +
		str(submission_id) + '.json')
	submission_r = requests.get(url)
	print(submission_r.status_code)
	response_dict = submission_r.json()

	submission_dict = {
		'title': response_dict['title'],#標題
		'link': 'http://news.ycombinator.com/item?id=' + 
			str(submission_id),#討論頁面鏈接
		#不確定某個鍵是否包含在字典中時,使用方法dict.get()
		#它在指定的鍵存在時返回與之相關聯的值
		#並在指定的鍵不存在時返回你指定的值(這裏是0)
		'comments': response_dict.get('descendants', 0)#評論數
		}
	submission_dicts.append(submission_dict)
#根據comments降序排列
submission_dicts = sorted(submission_dicts, key = itemgetter('comments'), 
	reverse = True)
for submission_dict in submission_dicts:
	print("\nTitle:",submission_dict['title'])
	print("Discussion link:",submission_dict['link'])
	print("Comments:",submission_dict['comments'])

titles,plot_dicts = [],[]
for submission_dict in submission_dicts:
	titles.append(submission_dict['title'])
	plot_dicts = {
		'value':submission_dict['comments'],
		'label':submission_dict['title'],
		'xlink':submission_dict['link'],
		}
	plot_dicts.append(plot_dict)

my_style = LS('#333366',base_style = LCS)
my_style.title_font_size = 24
my_style.label_font_size = 14
my_style.major_lable_font_size = 18

my_config = pygal.Config()
my_config.x_label_rotation = 45
my_config.show_lenged = False
my_config.truncate_label = 15 #將較長的項目名縮短爲15個字符
my_config.show_y_guides = False #隱藏圖表中的水平線
my_config.width = 1000
my_config.y_title = 'Number of Comments'

chart = pygal.Bar(my_config, style = my_style)
chart.title = 'Most Active Discussions on Hacker News'
chart.x_labels = titles
chart.add('',plot_dicts)
chart.render_to_file('hn_discussions.svg')

發佈了35 篇原創文章 · 獲贊 21 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章