2020年9月26日星期六

017 Python编程 從入門到實踐, 第二部分 專案2 資料視覺化 第 17 章 使用API

申明本站飛宇網 https://feiyetopro.blogspot.com/自網路收集整理之書籍文章影音僅供預覽交流學習研究,其[書籍、文章、影音]情節內容, 評論屬其個人行為, 與本網站無關。版權歸原作者和出版社所有,請在下載 24 小時內刪除,不得用作商業用途;如果您喜歡其作品,請支持訂閱購買[正版]謝謝!

 


17 章 使用API

在本章中,你將學習如何編寫一個獨立的程式,並對其獲取的資料進行視覺化。這個程式將使用Web應用程式設計介面 API)自動請求網站的特定資訊而不是整個網頁,再對這些資訊進行視覺化。由於這樣編寫的程式始終使用最新的資料來生成視覺化,因此即便資料瞬息萬變,它呈現的資訊也都是最新的。

17.1 使用Web API

Web API是網站的一部分,用於與使用非常具體的URL請求特定資訊的程式交互。這種請求稱為API調用。請求的資料將以易於處理的格式(如JSONCSV)返回。依賴于外部資料來源的大多數應用程式都依賴於API調用,如集成社交媒體網站的應用程式。

17.1.1 GitGitHub

本章的視覺化將基於來自GitHub的資訊,這是一個讓程式師能夠協作開發專案的網站。我們將使用GitHubAPI來請求有關該網站中Python專案的資訊,然後使用Pygal生成互動式視覺化,以呈現這些項目的受歡迎程度。

GitHubhttps://github.com/ )的名字源自GitGit是一個分散式版本控制系統,讓程式師團隊能夠協作開發專案。Git幫助大家管理為專案所做的工作,避免一個人所做的修改影響其他人所做的修改。你在專案中實現新功能時,Git將跟蹤你對每個檔所做的修改。確定代碼可行後,你提交所做的修改,而Git將記錄專案最新的狀態。如果你犯了錯,想撤銷所做的修改,可輕鬆地返回以前的任何可行狀態(要更深入地瞭解如何使用Git進行版本控制,請參閱附錄D)。GitHub上的專案都存儲在倉庫中,後者包含與專案相關聯的一切:代碼、專案參與者的資訊、問題或bug報告等。

對於喜歡的專案,GitHub用戶可給它加星(star)以表示支持,用戶還可跟蹤他可能想使用的項目。在本章中,我們將編寫一個程式,它自動下載GitHub上星級最高的Python專案的資訊,並對這些資訊進行視覺化。

17.1.2 使用API調用請求資料

GitHubAPI讓你能夠通過API調用來請求各種資訊。要知道API調用是什麼樣的,請在流覽器的位址欄中輸入如下位址並按回車鍵:

 

https://api.github.com/search/repositories?q=language:python&sort=stars

 

 

 

 

 

 

 

 

這個調用返回GitHub當前託管了多少個Python專案,還有有關最受歡迎的Python倉庫的資訊。下面來仔細研究這個調用。第一部分(https://api.github.com/ )將請求發送到GitHub網站中回應API調用的部分;接下來的一部分(search/repositories )讓API搜索GitHub上的所有倉庫。

repositories 後面的問號指出我們要傳遞一個實參。q 表示查詢,而等號讓我們能夠開始指定查詢(q= )。通過使用language:python ,我們指出只想獲取主要語言為Python的倉庫的資訊。最後一部分(&sort=stars )指定將項目按其獲得的星級進行排序。

下面顯示了回應的前幾行。從回應可知,該URL並不適合人工輸入。

 

{

  "total_count": 713062,

  "incomplete_results": false,

  "items": [

    {

      "id": 3544424,

      "name": "httpie",

      "full_name": "jkbrzt/httpie",

      --snip--

 

 

 

 

 

 

 

 

從第二行輸出可知,編寫本書時,GitHub總共有713 062Python項目。"incomplete_results" 的值為false ,據此我們知道請求是成功的(它並非不完整的)。倘若GitHub無法全面處理該API,它返回的這個值將為true 。接下來的清單中顯示了返回的"items" ,其中包含GitHub上最受歡迎的Python專案的詳細資訊。

17.1.3 安裝requests

requests包讓Python程式能夠輕鬆地向網站請求信,息以及檢查返回的回應。要安裝requests,請執行類似於下麵的命令:

 

$ pip install --user requests

 

 

 

 

 

 

 

 

如果你還沒有使用過pip,請參閱12.2.1節(根據系統的設置,你可能需要使用這個命令的稍微不同的版本)。

17.1.4 處理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)

print("Status code:", r.status_code)

 

  # API響應存儲在一個變數中

response_dict = r.json()

 

  # 處理結果

  print(response_dict.keys())

 

 

 

 

 

 

 

 

處,我們導入了模組requests 。在處,我們存儲API調用的URL,然後使用requests 來執行調用(見)。我們調用get() 並將URL傳遞給它,再將響應物件存儲在變數r 中。響應物件包含一個名為status_code 的屬性,它讓我們知道請求是否成功了(狀態碼200表示請求成功)。在處,我們列印status_code ,核實調用是否成功了。

這個API返回JSON格式的資訊,因此我們使用方法json() 將這些資訊轉換為一個Python字典(見)。我們將轉換得到的字典存儲在response_dict 中。

最後,我們列印response_dict 中的鍵。輸出如下:

 

Status code: 200

dict_keys(['items', 'total_count', 'incomplete_results'])

 

 

 

 

 

 

 

 

狀態碼為200,因此我們知道請求成功了。回應字典只包含三個鍵:'items' 'total_count' 'incomplete_results' 

注意  像這樣簡單的調用應該會返回完整的結果集,因此完全可以忽略與'incomplete_results' 相關聯的值。但執行更複雜的API調用時,程式應檢查這個值。

17.1.5 處理回應字典

API調用返回的資訊存儲到字典中後,就可以處理這個字典中的資料了。下面來生成一些概述這些資訊的輸出。這是一種不錯的方式,可確認收到了期望的資訊,進而可以開始研究感興趣的資訊:

python_repos.py

 

  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'])

 

  # 探索有關倉庫的資訊

repo_dicts = response_dict['items']

  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)

 

 

 

 

 

 

 

 

處,我們列印了與'total_count' 相關聯的值,它指出了GitHub總共包含多少個Python倉庫。

'items' 相關聯的值是一個清單,其中包含很多字典,而每個字典都包含有關一個Python倉庫的資訊。在處,我們將這個字典清單存儲在repo_dicts 中。接下來,我們列印repo_dicts 的長度,以獲悉我們獲得了多少個倉庫的資訊。

為更深入地瞭解返回的有關每個倉庫的資訊,我們提取了repo_dicts 中的第一個字典,並將其存儲在repo_dict 中(見)。接下來,我們列印這個字典包含的鍵數,看看其中有多少資訊(見)。在處,我們列印這個字典的所有鍵,看看其中包含哪些資訊。

輸出讓我們對實際包含的資料有了更清晰的認識:

 

  Status code: 200

  Total repositories: 713062

  Repositories returned: 30

 

Keys: 68

  archive_url

  assignees_url

  blobs_url

  --snip--

  url

  watchers

  watchers_count

 

 

 

 

 

 

 

 

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

下面來提取repo_dict 中與一些鍵相關聯的值:

python_repos.py

 

  --snip--

  # 研究有關倉庫的資訊

  repo_dicts = response_dict['items']

  print("Repositories returned:", len(repo_dicts))

 

  # 研究第一個倉庫

  repo_dict = repo_dicts[0]

 

  print("\nSelected information about first repository:")

print('Name:', repo_dict['name'])

print('Owner:', repo_dict['owner']['login'])

print('Stars:', repo_dict['stargazers_count'])

  print('Repository:', repo_dict['html_url'])

print('Created:', repo_dict['created_at'])

print('Updated:', repo_dict['updated_at'])

  print('Description:', repo_dict['description'])

 

 

 

 

 

 

 

 

在這裡,我們列印了表示第一個倉庫的字典中與很多鍵相關聯的值。在處,我們列印了項目的名稱。專案所有者是用一個字典表示的,因此在處,我們使用鍵owner 來訪問表示所有者的字典,再使用鍵key 來獲取所有者的登錄名。在處,我們列印項目獲得了多少個星的評級,以及項目在GitHub倉庫的URL。接下來,我們顯示專案的創建時間(見)和最後一次更新的時間(見)。最後,我們列印倉庫的描述。輸出類似於下面這樣:

 

Status code: 200

Total repositories: 713065

Repositories returned: 30

 

Selected information about first repository:

Name: httpie

Owner: jkbrzt

Stars: 16101

Repository: https://github.com/jkbrzt/httpie

Created: 2012-02-25T12:39:13Z

Updated: 2015-07-13T14:56:41Z

Description: CLI HTTP client; user-friendly cURL replacement featuring intuitive UI, JSON support, syntax highlighting, wget-like downloads, extensions, etc.

 

 

 

 

 

 

 

 

從上述輸出可知,編寫本書時,GitHub上星級最高的Python項目為HTTPie,其所有者為用戶jkbrzt,有16 000多個GitHub用戶給這個項目加星。我們可以看到這個項目的倉庫的URL,其創建時間為20122月,且最近更新了。最後,描述指出HTTPie用於説明從終端執行HTTP調用(CLI命令列介面 的縮寫)。

17.1.6 概述最受歡迎的倉庫

對這些資料進行視覺化時,我們需要涵蓋多個倉庫。下面就來編寫一個迴圈,列印API調用返回的每個倉庫的特定資訊,以便能夠在視覺化中包含所有這些資訊:

python_repos.py

 

  --snip--

  # 研究有關倉庫的資訊

  repo_dicts = response_dict['items']

  print("Repositories returned:", len(repo_dicts))

 

print("\nSelected information about each 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'])

 

 

 

 

 

 

 

 

處,我們列印了一條說明性消息。在處,我們遍歷repo_dicts 中的所有字典。在這個迴圈中,我們列印每個項目的名稱、所有者、星級、在GitHub上的URL以及描述:

 

Status code: 200

Total repositories: 713067

Repositories returned: 30

 

Selected information about each repository:

 

Name: httpie

Owner: jkbrzt

Stars: 16101

Repository: https://github.com/jkbrzt/httpie

Description: CLI HTTP client; user-friendly cURL replacement featuring intuitive UI, JSON support, syntax highlighting, wget-like downloads, extensions, etc.

 

Name: django

Owner: django

Stars: 15028

Repository: https://github.com/django/django

Description: The Web framework for perfectionists with deadlines.

--snip--

 

Name: powerline

Owner: powerline

Stars: 4315

Repository: https://github.com/powerline/powerline

Description: Powerline is a statusline plugin for vim, and provides statuslines and prompts for several other applications, including zsh, bash, tmux, IPython, Awesome and Qtile.

 

 

 

 

 

 

 

 

上述輸出中有一些有趣的項目,可能值得再看一眼。但不要在這上面花費太多時間,因為我們即將創建的視覺化可讓你更容易地看清結果。

17.1.7 監視API的速率限制

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

 

  {

    "resources": {

      "core": {

        "limit": 60,

        "remaining": 58,

        "reset": 1426082320

      },

     "search": {

       "limit": 10,

       "remaining": 8,

       "reset": 1426078803

      }

    },

    "rate": {

      "limit": 60,

      "remaining": 58,

      "reset": 1426082320

    }

  }

 

 

 

 

 

 

 

 

我們關心的資訊是搜索API的速率限制(見)。從處可知,極限為每分鐘10個請求,而在當前這一分鐘內,我們還可執行8個請求(見)。reset 值指的是配額將重置的Unix時間或新紀元時間 197011日午夜後多少秒)(見)。用完配額後,你將收到一條簡單的響應,由此知道已到達API極限。到達極限後,你必須等待配額重置。

注意  很多API都要求你註冊獲得API金鑰後才能執行API調用。編寫本書時,GitHub沒有這樣的要求,但獲得API金鑰後,配額將高得多。

17.2 使用Pygal視覺化倉庫

有了一些有趣的資料後,我們來進行視覺化,呈現GitHubPython項目的受歡迎程度。我們將創建一個互動式橫條圖:條形的高度表示專案獲得了多少顆星。按一下條形將帶你進入項目在GitHub上的主頁。下面是首次嘗試這樣做:

python_repos.py

 

  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=star'

  r = requests.get(URL)

  print("Status code:", r.status_code)

 

  # API響應存儲在一個變數中

  response_dict = r.json()

  print("Total repositories:", response_dict['total_count'])

 

  # 研究有關倉庫的資訊

  repo_dicts = response_dict['items']

 

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)

  chart.title = 'Most-Starred Python Projects on GitHub'

  chart.x_labels = names

 

chart.add('', stars)

  chart.render_to_file('python_repos.svg')

 

 

 

 

 

 

 

 

我們首先導入了pygal 以及要應用於圖表的Pygal樣式。接下來,列印API調用回應的狀態以及找到的倉庫總數,以便獲悉API調用是否出現了問題。我們不再列印返回的有關專案的資訊,因為將通過視覺化來呈現這些資訊。

處,我們創建了兩個空清單,用於存儲將包含在圖表中的資訊。我們需要每個專案的名稱,用於給條形加上標籤,我們還需要知道專案獲得了多少個星,用於確定條形的高度。在迴圈中,我們將項目的名稱和獲得的星數附加到這些列表的末尾

接下來,我們使用LightenStyle 類(別名LS )定義了一種樣式,並將其基色設置為深藍色(見)。我們還傳遞了實參base_style ,以使用LightColorizedStyle 類(別名LCS )。然後,我們使用Bar() 創建一個簡單的橫條圖,並向它傳遞了my_style (見)。我們還傳遞了另外兩個樣式實參:讓標籤繞x 軸旋轉45度(x_label_rotation=45 ),並隱藏了圖例(show_legend=False ),因為我們只在圖表中繪製一個資料數列。接下來,我們給圖表指定了標題,並將屬性x_labels 設置為清單names 

由於我們不需要給這個資料數列添加標籤,因此在處添加資料時,將標籤設置成了空字串。生成的圖表如圖17-1所示。從中可知,前幾個項目的受歡迎程度比其他項目高得多,但所有這些專案在Python生態系統中都很重要。


17-1 GitHub上受歡迎程度最高的Python項目

17.2.1 改進Pygal圖表

下面來改進這個圖表的樣式。我們將進行多個方面的定制,因此先來稍微調整代碼的結構,創建一個配置物件,在其中包含要傳遞給Bar() 的所有定制:

python_repos.py

 

  --snip--

 

  # 視覺化

  my_style = LS('#333366', base_style=LCS)

 

my_config = pygal.Config()

my_config.x_label_rotation = 45

  my_config.show_legend = False

my_config.title_font_size = 24

  my_config.label_font_size = 14

  my_config.major_label_font_size = 18

my_config.truncate_label = 15

my_config.show_y_guides = False

my_config.width = 1000

 

chart = pygal.Bar(my_config, style=my_style)

  chart.title = 'Most-Starred Python Projects on GitHub'

  chart.x_labels = names

 

  chart.add('', stars)

  chart.render_to_file('python_repos.svg')

 

 

 

 

 

 

 

 

處,我們創建了一個PygalConfig 的實例,並將其命名為my_config 。通過修改my_config 的屬性,可定制圖表的外觀。在處,我們設置了兩個屬性——x_label_rotation show_legend ,它們原來是在創建Bar 實例時以關鍵字實參的方式傳遞的。在處,我們設置了圖表標題、副標籤和主標籤的字體大小。在這個圖表中,副標籤是 x 軸上的項目名以及 y 軸上的大部分數位。主標籤是 y 軸上為5000整數倍的刻度;這些標籤應更大,以與副標籤區分開來。在處,我們使用truncate_label 將較長的項目名縮短為15個字元(如果你將滑鼠指向螢幕上被截短的專案名,將顯示完整的專案名)。接下來,我們將show_y_guides 設置為False ,以隱藏圖表中的水平線(見)。最後,在處設置了自訂寬度,讓圖表更充分地利用流覽器中的可用空間。

處創建Bar 實例時,我們將my_config 作為第一個實參,從而通過一個實參傳遞了所有的配置設置。我們可以通過my_config 做任意數量的樣式和配置修改,而處的代碼行將保持不變。圖17-2顯示了重新設置樣式後的圖表。


17-2 改進了圖表的樣式

17.2.2 添加自訂工具提示

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 的列表,其中包含三個字典,分別針對專案HTTPieDjangoFlask。每個字典都包含兩個鍵:'value' 'label' Pygal根據與鍵'value' 相關聯的數字來確定條形的高度,並使用與'label' 相關聯的字串給條形創建工具提示。例如,處的第一個字典將創建一個條形,用於表示一個獲得了16 101顆星、工具提示為Description of httpie的項目。

方法add() 接受一個字串和一個清單。這裡調用add() 時,我們傳入了一個由表示條形的字典組成的清單(plot_dicts )(見)。17-3顯示了一個工具提示:除默認工具提示(獲得的星數)外,Pygal還顯示了我們傳入的自訂提示。


17-3 每個條形都有自訂的工具提示標籤

17.2.3 根據資料繪圖

為根據資料繪圖,我們將自動生成plot_dicts ,其中包含API調用返回的30個專案的資訊。

完成這種工作的代碼如下:

python_repos.py

 

  --snip--

  # 研究有關倉庫的資訊

  repo_dicts = response_dict['items']

  print("Number of items:", len(repo_dicts))

 

names, plot_dicts = [], []

  for repo_dict in repo_dicts:

      names.append(repo_dict['name'])

 

     plot_dict = {

          'value': repo_dict['stargazers_count'],

          'label': 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')

 

 

 

 

 

 

 

 

處,我們創建了兩個空列表names plot_dicts 。為生成x 軸上的標籤,我們依然需要清單names 

在迴圈內部,對於每個項目,我們都創建了字典plot_dict (見)。在這個字典中,我們使用鍵'value' 存儲了星數,並使用鍵'label' 存儲了專案描述。接下來,我們將字典plot_dict 附加到plot_dicts 末尾(見)。在處,我們將列表plot_dicts 傳遞給了add() 。圖17-4顯示了生成的圖表。


17-4 將滑鼠指向條形將顯示專案的描述

17.2.4 在圖表中添加可按一下的連結

Pygal還允許你將圖表中的每個條形用作網站的連結。為此,只需添加一行代碼,在為每個專案創建的字典中,添加一個鍵為'xlink' 的鍵值對:

python_repos.py

 

--snip--

names, plot_dicts = [], []

for repo_dict in repo_dicts:

    names.append(repo_dict['name'])

 

    plot_dict = {

        'value': repo_dict['stargazers_count'],

        'label': repo_dict['description'],

        'xlink': repo_dict['html_url'],

        }

    plot_dicts.append(plot_dict)

--snip--

 

 

 

 

 

 

 

 

Pygal根據與鍵'xlink' 相關聯的URL將每個條形都轉換為活躍的連結。按一下圖表中的任何條形時,都將在流覽器中打開一個新的標籤頁,並在其中顯示相應專案的GitHub頁面。至此,你對API獲取的資料進行了視覺化,它是交互性的,包含豐富的資訊!

17.3 Hacker News API

為探索如何使用其他網站的API調用,我們來看看Hacker Newshttp://news.ycombinator.com/ )。在Hacker News網站,用戶分享程式設計和技術方面的文章,並就這些文章展開積極的討論。Hacker NewsAPI讓你能夠訪問有關該網站所有文章和評論的資訊,且不要求你通過註冊獲得金鑰。

下面的調用返回本書編寫時最熱門的文章的資訊:

 

https://hacker-news.firebaseio.com/v0/item/9884165.json

 

 

 

 

 

 

 

 

響應是一個字典,包含ID9884165的文章的資訊:

 

  {

     'url': 'http://www.bbc.co.uk/news/science-environment-33524589',

      'type': 'story',

     'title': 'New Horizons: Nasa spacecraft speeds past Pluto',

     'descendants': 141,

      'score': 230,

      'time': 1436875181,

      'text': '',

      'by': 'nns',

      'id': 9884165,

     'kids': [9884723, 9885099, 9884789, 9885604, 9885844]

  }

 

 

 

 

 

 

 

 

這個字典包含很多鍵,如'url' (見)和'title' (見)。與'descendants' 相關聯的值是文章被評論的次數(見)。與'kids' 相關聯的值包含對文章所做的所有評論的ID(見)。每個評論自己也可能有kid,因此文章的後代(descendant)數量可能比其kid數量多。

下面來執行一個API調用,返回Hacker News上當前熱門文章的ID,再查看每篇排名靠前的文章:

hn_submissions.py

 

  import requests

 

  from operator import itemgetter

 

  # 執行API調用並存儲回應

url = 'https://hacker-news.firebaseio.com/v0/topstories.json'

  r = requests.get(url)

  print("Status code:", r.status_code)

 

  # 處理有關每篇文章的資訊

submission_ids = r.json()

submission_dicts = []

  for submission_id in submission_ids[:30]:

      # 對於每篇文章,都執行一個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),

         'comments': response_dict.get('descendants', 0)

          }

      submission_dicts.append(submission_dict)

 

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'])

 

 

 

 

 

 

 

 

首先,我們執行了一個API調用,並列印了響應的狀態(見)。這個API調用返回一個列表,其中包含Hacker News上當前最熱門的500篇文章的ID。接下來,我們將響應文本轉換為一個Python清單(見),並將其存儲在submission_ids 中。我們將使用這些ID來創建一系列字典,其中每個字典都存儲了一篇文章的資訊。

處,我們創建了一個名為submission_dicts 的空清單,用於存儲前面所說的字典。接下來,我們遍歷前30篇文章的ID。對於每篇文章,我們都執行一個API調用,其中的URL包含submission_id 的當前值(見)。我們列印每次請求的狀態,以便知道請求是否成功了。

處,我們為當前處理的文章創建一個字典,並在其中存儲文章的標題以及到其討論頁面的連結。在處,我們在這個字典中存儲了評論數。如果文章還沒有評論,回應字典中將沒有鍵'descendants' 。不確定某個鍵是否包含在字典中時,可使用方法dict.get() ,它在指定的鍵存在時返回與之相關聯的值,並在指定的鍵不存在時返回你指定的值(這裡是0)。最後,我們將submission_dict 附加到submission_dicts 末尾。

Hacker News上的文章是根據總體得分排名的,而總體得分取決於很多因素,其中包含被推薦的次數、評論數以及發表的時間。我們要根據評論數對字典清單submission_dicts 進行排序,為此,使用了模組operator 中的函數itemgetter() (見)。我們向這個函數傳遞了鍵'comments' ,因此它將從這個清單的每個字典中提取與鍵'comments' 相關聯的值。這樣,函數sorted() 將根據這種值對清單進行排序。我們將列表按降冪排列,即評論最多的文章位於最前面。

對列表排序後,我們遍歷這個列表(見),對於每篇熱門文章,都列印其三項資訊:標題、到討論頁面的連結以及文章現有的評論數:

 

Status code: 200

200

200

200

--snip--

 

Title: Firefox deactivates Flash by default

Discussion link: http://news.ycombinator.com/item?id=9883246

Comments: 231

 

Title: New Horizons: Nasa spacecraft speeds past Pluto

Discussion link: http://news.ycombinator.com/item?id=9884165

Comments: 142

 

Title: Iran Nuclear Deal Is Reached With World Powers

Discussion link: http://news.ycombinator.com/item?id=9884005

Comments: 141

 

Title: Match Group Buys PlentyOfFish for $575M

Discussion link: http://news.ycombinator.com/item?id=9884417

Comments: 75

 

Title: Our Nexus 4 devices are about to explode

Discussion link: http://news.ycombinator.com/item?id=9885625

Comments: 14

 

--snip--

 

 

 

 

 

 

 

 

使用任何API來訪問和分析資訊時,流程都與此類似。有了這些資料後,你就可以進行視覺化,指出最近哪些文章引發了最激烈的討論。

動手試一試

17-1 其他語言 :修改python_repos.py中的API調用,使其在生成的圖表中顯示使用其他語言編寫的最受歡迎的項目。請嘗試語言JavaScriptRubyCJavaPerlHaskellGo等。

17-2 最活躍的討論 :使用hn_submissions.py中的資料,創建一個橫條圖,顯示Hacker News上當前最活躍的討論。條形的高度應對應于文章得到的評論數量,條形的標籤應包含文章的標題,而每個條形應是到該文章討論頁面的連結。

17-3 測試python_repos.py :在python_repos.py中,列印status_code 的值,以核實API調用是否成功了。請編寫一個名為test_python_repos.py的程式,它使用單元測試來斷言status_code 的值為200。想想你還可做出哪些斷言,如返回的條目數符合預期,倉庫總數超過特定的值等。

17.4 小結

在本章中,你學習了:如何使用API來編寫獨立的程式,它們自動採集所需的資料並對其進行視覺化;使用GitHub API來探索GitHub上星級最高的Python項目,還大致地瞭解了Hacker News API;如何使用requests包來自動執行GitHub API調用,以及如何處理調用的結果。我們還簡要地介紹了一些Pygal設置,使用它們可進一步定制生成的圖表的外觀。

在本書的最後一個項目中,我們將使用Django來創建一個Web應用程式。 

0 留言:

發佈留言