API Hacker News
Чтобы познакомиться с использованием вызовов API для других сайтов, мы обратимся к сайту Hacker News (http://news.ycombinator.com/). На этом сайте пользователи делятся друг с другом статьями, посвященными программированию и технологиям, а также активно обсуждают эти статьи. API сайта Hacker News предоставляет доступ ко всем статьям и комментариям на сайте, а для его использования не требуется регистрация с получением ключа.
Следующий вызов возвращает информацию о текущей самой популярной статье (на момент написания книги):
https://hacker-news.firebaseio.com/v0/item/9884165.json
Ответ представляет собой словарь с информацией о статье с идентификатором 9884165:
{
(1) . .'url': 'http://www.bbc.co.uk/news/science-environment-33524589',
. .'type': 'story',
(2) . .'title': 'New Horizons: Nasa spacecraft speeds past Pluto',
(3) . .'descendants': 141,
. .'score': 230,
. .'time': 1436875181,
. .'text': '',
. .'by': 'nns',
. .'id': 9884165,
(4) . .'kids': [9884723, 9885099, 9884789, 9885604, 9885844]
}
Словарь содержит ряд ключей, которые могут нам пригодиться, — например, 'url' (1) и 'title' (2). Ключ 'descendants' содержит количество комментариев, полученных статьей (3). Ключ 'kids' предоставляет идентификаторы всех дочерних комментариев, сделанных непосредственно в ответ на эту статью (4). У каждого из этих комментариев могут быть свои дочерние комментарии, так что количество потомков у статьи может быть больше количества дочерних комментариев.
Создадим вызов API для получения идентификаторов статей, наиболее популярных на Hacker News, а затем рассмотрим каждую из этих статей:
hn_submissions.py
import requests
from operator import itemgetter
# Создание вызова API и сохранение ответа.
(1) url = 'https://hacker-news.firebaseio.com/v0/topstories.json'
r = requests.get(url)
print("Status code:", r.status_code)
# Обработка информации о каждой статье.
(2)submission_ids = r.json()
(3)submission_dicts = []
for submission_id in submission_ids[:30]:
. .# Создание отдельного вызова API для каждой статьи.
(4) . .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()
. .
(5) . .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(" Title:", submission_dict['title'])
. .print("Discussion link:", submission_dict['link'])
. .print("Comments:", submission_dict['comments'])
Сначала программа создает вызов API и выводит статус ответа (1) . Этот вызов API возвращает список идентификаторов 500 самых популярных статей на Hacker News на момент выдачи вызова. Текст ответа преобразуется в список Python (2), который сохраняется в переменной submission_ids. Идентификаторы будут использованы для построения набора словарей, каждый из которых содержит информацию об одной из текущих статей.
В точке (3) создается пустой список с именем submission_dicts для хранения словарей. Далее программа перебирает идентификаторы 30 самых популярных статей и выдает новый вызов API для каждой статьи, генерируя URL с текущим значением submission_id (4). Также выводится статус каждого запроса, чтобы мы могли проверить, успешно ли он был обработан.
В точке (5) создается словарь для текущей обрабатываемой статьи, в котором сохраняется заголовок статьи и ссылка на страницу с ее обсуждением. В точке ? сохраняется количество комментариев в словаре. Если статья еще не имеет комментариев, ключ 'descendants' отсутствует. Если вы не уверены, существует ли ключ в словаре, используйте метод dict.get(), который возвращает значение, связанное с ключом (если он существует), или значение, заданное вами (если ключ не существует), — 0 в данном примере. Наконец, словарь submission_dict присоединяется к списку submission_dicts.
Статьи Hacker News ранжируются по общей системе, основанной на нескольких факторах: сколько раз за статью голосовали, сколько комментариев она получила и давно ли была опубликована. Требуется отсортировать список словарей по количеству комментариев. Для этого мы используем функцию itemgetter() ? из модуля operator. Мы передаем этой функции ключ 'comments', а она извлекает значение, связанное с данным ключом, из каждого словаря в списке. Функция sorted() затем использует это значение для сортировки списка. Мы сортируем список в обратном порядке, чтобы публикации с наибольшим количеством комментариев оказались на первом месте.
После того как список будет отсортирован, мы перебираем элементы ? и выводим для каждой из самых популярных статей три атрибута: заголовок, ссылку на страницу обсуждения и текущее количество комментариев:
Status code: 200
200
200
200
..
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
...
Аналогичный процесс применяется для обращения и анализа информации из любого API. С такими данными вы сможете построить визуализацию, показывающую, какие публикации вызывали наиболее активные обсуждения в последнее время.
Упражнения
17-1. Другие языки: измените вызов API в программе python_repos.py так, чтобы на диаграмме отображались самые популярные проекты на других языках. Попробуйте такие языки, как JavaScript, Ruby, C, Java, Perl, Haskell и Go.
17-2. Активные обсуждения: на основании данных из hn_submissions.py постройте столбцовую диаграмму самых активных обсуждений, проходящих на Hacker News. Высота каждого столбца должна соответствовать количеству комментариев к каждой статье. Метка столбца должна включать заголовок статьи, а сам столбец должен служить ссылкой на страницу обсуждения этой публикации.
17-3. Тестирование python_repos.py: в python_repos.py для проверки успешности вызова API выводится значение status_code. Напишите программу test_python_repos.py, которая использует модуль unittest для проверки того, что значение status_code равно 200. Придумайте другие условия, которые могут проверяться при тестировании, — например, что количество возвращаемых элементов совпадает с ожидаемым, а общее количество репозиториев превышает некоторый порог.