Date Категория comp Теги R / API

Введение

Развитие информационных технологий приводит к появлению новых видов научных публикаций, новых сред и форм общения между учеными. Все больше составляющих этого общения переводится в цифровую форму, что приводит к стремительному росту объемов сопутствующих данных, но, с другой стороны, дает новые возможности для их сбора и обработки.

Так, с помощью библиографического веб-сервиса Mendeley можно извлекать информацию о размещенных в нем документах: аннотацию, список ключевых слов, а также число ознакомившихся с этим документом ученых, их должности, места работы, страны проживания и т. п. Учитывая, что на сервисе хранятся сотни миллионов документов, эти данные могут оказаться полезными как для использования в науковедческих целях, так и для прикладных научных исследований.

Данные Mendeley позволяют оценить общее число публикаций в заданном научном направлении, динамику изменения этого числа во времени, выявить наиболее читаемые публикации и их аудиторию по странам. Эти и многие другие вопросы относятся к наукометрии — науки, пытающейся оценить степень развития и влияния различных научных дисциплин.

Наличие в данных аннотации и ключевых слов позволяет автоматизировать процесс тематической классификации документов. Это дает возможность отслеживать направления развития той или иной отрасли науки, облегчить выявление перспективных тем для исследований. Поиск близких или дополняющих по тематике работ научных коллективов может оказаться полезным для налаживания международного сотрудничества.

Естественно, что работа с данными Mendeley будет ставить перед исследователями и новые вопросы. Так, ясно, что оценка состояния работ в той или иной области науки, полученная по данным Mendeley, скорее всего окажется смещенной (например, из-за неучета ряда публикаций). Но чтобы оценить это смещение и ответить на другие вопросы нужно сначала научиться собирать хранящуюся в Mendeley информацию.

Наш работа будет состоять из следующих этапов:

  1. Рассмотрим, что из себя представляет веб-сервис Mendeley и каким образом он позволяет сторонним программам извлекать из него данные.
  2. Разработаем приложение, собирающее данные из Mendeley.
  3. Покажем, как модифицируя это приложение решать практические задачи: собрать информацию об общем числе публикаций в заданной отрасли науки, выявить наиболее популярные публикации и страны, где они востребованы и т. п.

Код примеров можно скачать здесь.

Автоматизация сбора данных из Mendeley и других подобных сервисов позволит значительно скорее перейти к следующему этапу работ — к анализу полученных данных — делу, на наш взгляд, значительно более интересному.

1. Веб-сервис Mendeley и элементы Mendeley API

В любом научном исследовании важное место занимает работа с литературой. Ученые ведут картотеки в которых для каждой прочитанной статьи или книги заводится электронная карточка. В карточку заносят библиографическое описание источника (авторы, название, год издания и т. п.) и его аннотацию (о чем здесь написано? чем это может быть полезно?).

Программа для ведения картотеки называется "менеджер ссылок" (reference manager). Она состоит из базы данных, куда заносится информация о публикациях, и системы генерации выбранных ссылок в форматах и стилях, требуемых научными журналами. Менеджеры ссылок существенно упрощают работу над научной статьей — с их помощью список литературы создается автоматически. Однако саму карточку, как и в докомпьютерную эру, приходится заполнять вручную.

Упростить эту часть работы позволяет веб-сервис Mendeley. В нем к функциям менеджера ссылок добавлены возможности социальной сети. Если хотя бы один из более чем 6 млн. участников сети Mendeley заполнил карточку на интересующую вас публикацию, вы получите ее в свое распоряжение и самому ничего заполнять не придется.

Для работы с платформой необходимо создать учетную запись на сайте Mendeley и установить на своем компьютере одноименную программу-клиент. Использование Mendeley — бесплатное.

В настоящее время основными направлениями работы Mendeley являются:

  • Reference Management — управление библиографической информацией (ссылками), размещение текстов публикаций;
  • Research Network — научная социальная сеть с возможностями создания профилей пользователей, объединения их в группы и комментирования;
  • Datasets — хранение наборов данных, на которых основаны исследования, возможность поделится этими наборами с другими;
  • Careers — поиск работы для ученых.

Помимо управления библиотекой, Mendeley позволяет отслеживать, сколько человек прочитали ту или иную публикацию, из каких они стран, какие должности занимают и другие характеристика читательской аудитории. Информация о читательской аудитории, полученная из Mendeley, используются крупнейшим в мире индексом цитирования Scopus (ссылка "Mendeley Activity" в описании публикации) и ведущими мировыми сервисами альтметрики, такими как ImpactStory, Plum Analytics и Altmetric.com. Сбор этих данных можно автоматизировать самостоятельно, создав приложение, использующее Mendeley API.

API (интерфейс программирования приложений) позволяет пользовательскому приложению делать запросы к ресурсам Mendeley и получать в ответ данные. API Mendeley:

  • разработано с соответствии с принципами REST, то есть содержит команды управления информационными ресурсами при помощи человекопонятных URL;
  • возвращает данные в формате JSON, который легко читать как компьютеру, так и человеку. Функции для обработки данных в JSON существуют во многих языках программирования;
  • использует для авторизации запросов протокол OAuth 2.0.

Для разработки приложения, взаимодействующего с API Mendeley, мы будем использовать язык программирования R. Этот язык создан статистиками и предназначен для статистического анализа данных. Поэтому задачи сбора и анализа данных в R реализуются наиболее прямолинейно, что позволяет быстрее добиться результата, не отвлекаясь на тонкости программирования. Создание приложений существенно облегчает среда разработки RStudio.

Привлекательной стороной R является наличие у него многочисленных пакетов, расширяющих возможности языка. В настоящее время таких пакетов насчитывается уже более 10000.

Пакет (package) в R представляет собой набор функций, данных и скомпилированного кода, предназначенный для решения какой-то определенной задачи. Для установки пакета можно выполнить в командном окне R:

install.packages("имяПакета")

или воспользоваться графическим интерфейсов RStudio: команды для работы с пакетами сгруппированы в меню Tools.

Чтобы использовать возможности пакета, его нужно загрузить в память:

library(имяПакета)

1.1 Протокол HTTP

HTTP — протокол передачи гипертекста (Hypertext Transfer Protocol) — представляет собой правила обмена данными между потребителем информации (клиентом) и поставщиком информации (сервером).

1.1.1 Запрос

HTTP-запрос (request) состоит из трех частей: начальной строки запроса, раздела заголовков (header) и тела запроса (content).

Начальная строка запроса имеет вид:

Метод URL HTTP/Версия

Метод — это операция, которая выполняется над информационным ресурсом, заданным своим URL. Строка HTTP/Версия указывает протокол передачи данных и версию его стандарта.

Рассмотрим запрос GET, предназначенный для получения от сервера информации, хранящейся по указанному URL:

GET https://www.mendeley.com HTTP/1.1

URL представляет собой адрес главной страницы сервиса Mendeley, текст которой и должен быть получен в результате выполнения запроса. Строка HTTP/1.1 указывает, что запрос составлен в соответствии со стандартом HTTP версии 1.1.

После начальной строки запроса идут строки заголовков, имеющие следующий формат:

Заголовок: значение

Существует множество заданных стандартом HTTP заголовков. Некоторые из них используются только в запросах, другие только в ответах, третьи могут включаться в любое сообщение между клиентом и сервером.

Например, заголовок

Content-type: text/html

означает, что клиент запрашивает (или получает) содержимое в виде текстового документа с разметкой HTML, то есть веб-страницу

Заголовок User-Agent задает кодовое обозначение браузера-клиента. Так

User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:47.0) Gecko/20100101 Firefox/47.0

означает, запрос сделан браузером Mozilla Firefox 47.0, работающим под ОС Linux (или другим клиентом, выдающим себя за этот браузер).

Каждая строка заголовка заканчивается символом перевода строки (\n), а два обязательных символа новой строки \n\n являются маркером окончания заголовков запроса. Если тело запроса отсутствует, что вполне допустимо, то \n\n является маркером окончания всего запроса. Без такого маркера сервер не будет обрабатывать запрос.

Таким образом, полностью наш запрос будет иметь вид:

GET https://www.mendeley.com HTTP/1.1\n
\n\n

Можно было бы указать тип возвращаемого содержимого (заголовок Content-type), но это не обязательно.

Выполним рассмотренный запрос при помощи R. ДЛя этого понадобится установить и загрузить в память пакета httr. Запрос GET выполняется одноименной функцией этого пакета:

library(httr)
res <- GET("https://www.mendeley.com")
class(res) # возвращает класс переменной
[1] "response

В списке res сохраняется ответ (response) полученный от сервера.

1.1.2 Ответ

Начальная строка ответа (response) имеет следующую структуру:

HTTP/Версия Код состояния Пояснение

Версия — это версия протокола HTTP.

Код состояния (status code) — три цифры, которые определяют результат выполнения запроса. Пояснение к нему представляет собой текст, предназначенный для упрощения чтения ответа человеком.

Например:

HTTP/1.1 200 OK

означает, что ответ доставлен в соответствии с протоколом HTTP версии 1.1. Запрос выполнен успешно, о чём говорит код состояния 200 и пояснение к нему — OK.

В настоящее время выделено пять классов кодов состояния:

  • 1xx: Informational (Информационные). Информационные коды состояния, сообщают клиенту, что сервер находится в процессе обработки запроса;
  • 2xx: Success (Успешно). Например: 200 OK — означает успешный запрос ресурса. Если клиентом были запрошены какие-либо данные, то они находятся в заголовке и/или теле сообщения;
  • 3xx: Redirection (Переадресация). Коды класса 3xx сообщают клиенту, что для успешного выполнения операции необходимо сделать другой запрос (как правило, по другому URL);
  • 4xx: Client Error (Ошибка клиента). Предназначен для указания ошибок со стороны клиента. При использовании любого из методов HTTP, кроме HEAD, сервер должен вернуть в теле сообщения гипертекстовое пояснение для пользователя. Например: 404 Not Found означает, что сервер понял запрос, но не нашёл соответствующего ресурса по указанному URL.
  • 5xx: Server Error (Ошибка сервера).

В нашем примере:

res$status_code
[1] 200

— все в порядке, веб-страница получена.

После начальной строки идут заголовки (headers) и тело ответа (content).

Информацию о заголовках ответа возвращает функция headers:

headers(res)
$`cache-control`
[1] "max-age=600, public"

$`content-encoding`
[1] "gzip"

$`content-language`
[1] "en"

$`content-type`
[1] "text/html; charset=UTF-8"

$date
[1] "Wed, 26 Jul 2017 14:37:11 GMT"

$etag
[1] "W/\"1501079786\""

$expires
[1] "Sun, 19 Nov 1978 05:00:00 GMT"

$`last-modified`
[1] "Wed, 26 Jul 2017 14:36:26 GMT"

$server
[1] "nginx"

$vary
[1] "Cookie"

$`x-content-type-options`
[1] "nosniff"

$`x-frame-options`
[1] "SAMEORIGIN"

$`x-ua-compatible`
[1] "IE=edge"

$`content-length`
[1] "14410"

$connection
[1] "keep-alive"

attr(,"class")
[1] "insensitive" "list"

Содержимое страницы находится в теле ответа и возвращается функцией content:

page <- content(res, as = "text", encoding = "UTF-8") 

Параметр as указывает тип выдачи, в данном случае — текстовый (есть ещё raw — в виде набора байт), а encoding — кодировку текста. Результат выполнения функции сохраняется в переменной page.

1.1.3 Передача параметров в запросе

Клиент может передавать параметры выполнения запроса в URL целевого ресурса. Для этого в конце URL после символа ? помещаются пары вида параметр=значение. Например:

GET https://api.mendeley.com/catalog?doi=10.1103/PhysRevA.20.1521 HTTP/1.1

означает запрос к каталогу документов с помощью Mendeley API https://api.mendeley.com/catalog. При этом уточняется, что необходимо вернуть единственный документ с заданным DOI: ?doi=10.1103/PhysRevA.20.1521.

Если передать нужно несколько параметров, то пары параметр=значение разделяются символом &:

GET https://api.mendeley.com/catalog?doi=10.1103/PhysRevA.20.1521&view=all HTTP/1.1

— выдается полная информация (view=all) о документе с заданным DOI.

Отправить GET-запрос с параметрами при помощи GET() можно двумя способами:

1) добавить параметры к URL самостоятельно

res1 <- GET("https://www.google.com/search?&q=RStudio&btnG=Search")

2) объединить параметры и их значения в список, предоставив пакету httr создать на этой основе URL

res2 <- GET("https://www.google.com/search", 
            query = list(q="RStudio", btnG="Search"))

1.2 REST

REST (Representational state transfer) — это набор принципов разработки веб-приложений, который, по сути, превращают обычные запросы HTTP в язык управления информационными ресурсами.

В основе REST лежит понятие коллекции информационных ресурсов. Эти ресурсы определяются своим URL, который обычно является человепонятным. Каждый URL на сервере представляет собой коллекцию ресурсов или единичный ресурс.

Допустим, что URL сервера — https://api.mendeley.com (этот URL является базовым для всех запросов к API Mendeley). Тогда:

  • доступ к коллекции ресурсов files (файлам) выглядит как запрос по URL https://api.mendeley.com/files/. Результатом выполнения запроса будет список (файлов);
  • единичный ресурс доступен по URL вроде https://api.mendeley.com/files/id, где обращаются к файлу с заданным id.

Для управления ресурсами существует набор операций, которые реализованы при помощи стандартных методов HTTP. Например:

  • GET — чтение ресурса;
  • PUT — запись/изменение ресурса;
  • POST — создание нового ресурса;
  • DELETE — удаление ресурса.

Ресурсы представляют собой объекты данных различных форматов — обычно JSON или XML.

Веб-сервис, основанный на принципах REST называется RESTful, то есть "соответствующий принципам REST". Mendeley API, таким образом, является RESTful API.

Используя принципы REST, каждый информационный ресурс можно идентифицировать по его URL. Основные виды ресурсов Mendeley API:

  • /document — документы, созданные пользователями Mendeley, и приписанные к библиотекам пользователей (libraries) или группам (groups). Документы включают в себя метаданные (описания) статей, книг, отчетов и прочих публикаций. Документы могут создаваться, редактироваться или удаляться; с ними связываются медиа-файлы (например, текст оригинальной статьи); они могут аннотироваться и комментироваться пользователями; их можно приписать к группе/папке или удалить оттуда.
  • /catalog — документы из каталога, собранного совместными усилиями пользователей Mendeley.
  • /files — прикрепленные файлы, связанные с документами.
  • /groups — группы, организованными пользователями, чтобы делиться документами и идеями.
  • /annotations — отметки и комментарии, сделанные пользователями в файлах и документов при помощи аннотаций

1.3 JSON

JSON (JavaScript Object Notation, представление объектов JavaScript) — текстовый формат, предназначенный для хранения и обмена структурированными данными. Формат является независимым от языка программирования (хотя и появился в рамках JavaScript) и может использоваться практически с любым из них.

Данные в JSON состоят из строк, для оформления которых существует несколько правил:

  • Строка JSON содержит либо набор пар ключ: значение (объект), либо упорядоченный набор значений (массив).
  • Массив заключается в квадратные скобки ([, ]) и содержит разделенный запятой список значений.
  • Объект заключается в фигурные скобки ({, }) и содержит разделенный запятой список пар ключ: значение.
  • Пара ключ: значение состоит из имени ключа, помещенного в двойные кавычки, за которым следует двоеточие (:) и значение поля.
  • Значение в массиве или объекте может быть:
    • числом (целым или с плавающей точкой);
    • строкой (в двойных кавычках);
    • логическим значением (TRUE или FALSE);
    • другим массивом (заключенным в квадратные скобки);
    • другим объектом (заключенным в квадратные скобки);
    • значением NULL.

Ключом может быть только строка (зависящая от регистра).

Пример текста в JSON:

{
   "firstName": "Santa",
   "lastName": "Claus",
   "address": {
       "streetAddress": "Tähtikuja, 1",
       "city": "Rovaniemi",
       "postcode": "96930",
       "state": "Finland"
   },
   "phoneNumbers": [
       "+358 16 3562096",
       "+358 16 3562097"
   ]
}

Те же данные на языке XML:

<person>
  <firstName>Santa</firstName>
  <lastName>Claus</lastName>
  <address>
    <streetAddress>Tähtikuja, 1</streetAddress>
    <city>Rovaniemi</city>
    <postcode>96930</postcode>
    <state>Finland</state>
  </address>
  <phoneNumbers>
    <phoneNumber>+358 16 3562096</phoneNumber>
    <phoneNumber>+358 16 3562097</phoneNumber>
  </phoneNumbers>
</person>

JSON имеет следующие достоинства:

  • тексты на нем легко читаются как человеком, так и компьютером;
  • его легко преобразовать в структуру данных для большинства языков программирования (числа, строки, логические переменные, массивы и т.д.);
  • он более компактен по сравнению с XML и другими текстовыми форматами данных.

Чаще всего JSON используется для пересылки данных от сервера к браузеру.

Для работы с данными JSON в языке R будем использовать пакет jsonlite. Основные функции пакета:

  • fromJSON — импорт данных JSON в R;
  • toJSON — экспорт данных в JSON.

Импорт данных возможен как из локальных файлов, так и из удаленных ресурсов, заданных своим URL.

1.4 OAuth 2.0

Допустим, мы создали приложение, собирающее данные о друзьях пользователей социальной сети. Этому приложению необходим доступ к учетным записям пользователей. При этом все права ему не нужны — достаточно лишь доступа на чтение к списку друзей. Чтобы предоставить приложению такой ограниченный доступ к учетным записям, не передавая при этом логины и пароли пользователей, разработан открытый протокол авторизации OAuth. Текущую версию протокола 2.0 поддерживают крупнейшие социальные сети: Facebook, Twitter, ВКонтакте и многие популярные веб-сервисы, в том числе? Mendeley.

Чтобы обеспечить приложению доступ к веб-сервису, API которого поддерживает OAuth 2.0, нам понадобится:

  1. зайти на страницу сервиса, адресованную разработчикам приложений, и зарегистрировать там свое приложение;
  2. указать при регистрации, какие права и на какой вид данных нужны приложению;
  3. получить от сервиса специальный ключ (токен) для доступа к данным (access token) или несколько таких ключей.

Технически, работа с веб-сервисом будет строиться на отправке ему GET-запросов. К каждому запросу добавляется полученный токен, указывающий сервису, какие права доступа имеет данное приложение. Ответ сервиса, как правило, возвращает данные в формате JSON. Таким образом, нам понадобятся пакеты для работы с HTTP-запросами и с JSON — httr и jsonlite.

2. Разработка приложения

Создадим простейшее приложение, способное запросить и получить данные о документе, хранящемся в коллекции Mendeley. Для этого нужно:

  1. создать учетную запись (аккаунт) пользователя Mendeley;
  2. зарегистрировать свое приложение на портале разработчиков Mendeley;
  3. получить ключ доступа (access token);
  4. использовать функции API для выполнения поиска и сбора данных о документе.

Разберем эти шаги более подробно.

2.1 Создание учетной записи пользователя

Чтобы получить доступ к Mendeley API, необходимо зарегистрироваться в Mendeley. Для этого нужно открыть страницу www.mendeley.com/join/ в веб-браузере и следовать указанным там инструкциям.

Форма регистрации в Mendeley

Форма регистрации в Mendeley

Регистрация и работа с API Mendeley осуществляется бесплатно.

2.2 Регистрация приложения

Регистрация приложения нужна затем, чтобы наше будущее приложение получило необходимые ему права доступа к API, то есть прошло авторизацию. Для регистрации приложения откройте страницу My Applications на портале разработчиков Mendeley.

Страница "My Applications" на портале разработчиков Mendeley

Страница "My Applications" на портале разработчиков Mendeley

Нажмите кнопку Register и укажите в открывшемся окне с формой логин (e-mail) и пароль вашей учетной записи в Mendeley.

Вход в учетную запись на портале разработчиков Mendeley

Вход в учетную запись на портале разработчиков Mendeley

Заполните форму регистрации приложения (app) и сохраните полученные application ID и secret. Последний, в случае утери, придется генерировать повторно с помощью кнопки Generate Secret на странице My Applications.

Форма регистрации приложения Mendeley

Форма регистрации приложения Mendeley

В поле Redirect URL записывается адрес веб-страницы, которая будет показана пользователю сразу после того, как приложение пройдет авторизацию. Поскольку мы создаем приложение без веб-интерфейса, то в этом поле можно записать любой URL, например, www.text.com — роли это не играет.

2.3 Получение ключа доступа

Для авторизации запросов к API Mendeley использует ключи доступа (access token) OAuth. Ключ представляет собой длинную строку символов. Срок службы ключа ограничен и как только он завершится, необходимо будет генерировать новый ключ. Обычно запрос на генерацию ключа делается из самого приложения, но мы пока получим ключ вручную.

  1. Откройте в браузере страницу Show Me Access Tokens в браузере.
  2. Кликните по ссылке Log in with Mendeley.
  3. Укажите ваш e-mail (он служит логином) и пароль от учетной записи в Mendeley.
  4. Если аутентификация прошла успешно, вы увидете страницу с ключем доступа. Скопируйте этот ключ (Access token).

Ключи доступа к API Mendeley

Ключи доступа к API Mendeley

Если срок службы ключа истек, нажмите кнопку Obtain new token using the refresh token на странице Show Me Access Tokens чтобы сгенерировать новый ключ. В настоящее время срок службы ключей доступа составляет около 1 часа.

Реализация запроса ключа непосредственно из приложения описана в п. 2.6.

2.4 Команда API для запроса документа

Теперь, когда у нас появился ключ доступа, мы можем использовать API чтобы получить метаданные любого из миллионов документов, хранящихся в каталоге Mendeley. В качестве примера, рассмотрим поиск документа по его Digital Object Identifier (DOI). DOI представляет собой уникальную ссылку, идентифицирующую цифровой документ независимо от адреса сайта опубликовавшей этот документ организации.

Получим метаданные документа "Laser cooling of atoms", имеющего DOI 10.1103/PhysRevA.20.1521. Команда, с помощью которой мы получим эти метаданные, выглядит так:

GET https://api.mendeley.com/catalog?doi=10.1103/PhysRevA.20.1521 HTTP/1.1
Authorization: Bearer <TOKEN>

Эту команду можно разбить на следующие элементы:

  • https://api.mendeley.com/catalog?doi=10.1103/PhysRevA.20.1521 — URL Mendeley API, к которому посылается запрос. Структуру этого URL мы уже рассматривали: он представляет собой запрос с каталогу Mendeley на получение объекта с заданным DOI.
  • Authorization: Bearer <TOKEN> — заголовок, содержащий ключ доступа. Наличие такого заголовка необходимо для работы протокола OAuth 2.0.

В качестве ответа вы получите (мета)данные в формате JSON, которые будут выведены в консоль. Обычно Mendeley API возвращает название (title), авторов (authors), аннотацию (abstract), гиперссылку на документ и ряд других данных. Если в ответе появится сообщение об ошибке, связанной с истечением срока годности ключа (token expiry error), создайте новый ключ и отправьте запрос снова.

2.5 Реализация в R

Приступим к созданию приложения на R, выполняющего запрос на получение документа.

В первую очередь нам понадобится (установить и) загрузить пакеты: httr — для выполнения HTTP-запросов и jsonlite — для извлечения результатов в формате JSON.

library(httr)
library(jsonlite)

Теперь сформируем запрос к API на получение искомого документа. URL возьмем из запроса, тип информационного ресурса (catalog) зададим параметром path, искомый DOI укажем в списке параметров запроса query, а заголовки запроса добавим с помощью функции add_headers().

access_token <- "СТРОКА_ACCESS_TOKEN"

endpoint <- "https://api.mendeley.com"

response <- GET(endpoint, 
                path = "catalog", 
                query = list(doi = "10.1103/PhysRevA.20.1521"), 
                add_headers(
                  'Authorization' = paste("Bearer", access_token),
                  'Content-Type' = 'application/vnd.mendeley-document.1+json'
                  )
                )

Результаты запроса сохраняются в переменной response. Извлечем содержимое ответа сервера функцей content(), преобразуем его в строковый вид, а затем преобразуем информацию, полученную в формате JSON, с помощью fromJSON().

docs <- fromJSON(content(response, as = "text", encoding = "UTF-8"))
# Или так:
# docs <- fromJSON(rawToChar(content(doc_response)))

Данные о документе хранятся в таблице docs, из которой мы для примера добудем список авторов документа.

docs$authors
  first_name last_name scopus_author_id
1      D. J.  Wineland       7006041778
2   Wayne M.     Itano       7005352566

Теперь соберем все это вместе в готовое приложение.

library(httr)
library(jsonlite)

access_token <- "СТРОКА_ACCESS_TOKEN"

endpoint <- "https://api.mendeley.com"

response <- GET(endpoint, 
                path = "catalog", 
                query = list(doi = "10.1103/PhysRevA.20.1521"), 
                add_headers(
                  'Authorization' = paste("Bearer", access_token),
                  'Content-Type' = 'application/vnd.mendeley-document.1+json'
                  )
                )

docs <- fromJSON(content(response, as = "text", encoding = "UTF-8"))

docs$authors

2.6 Авторизация и аутентификация приложения

Пора научиться получать ключ доступа по запросу из приложения. Рассмотрим, какие виды приложений могут иметь доступ к API Mendeley и какой следует выбрать нам для продолжения работы.

2.6.1 Клиенты API

Для доступа к Mendeley API по протоколу OAuth 2.0 можно использовать три вида клиентов:

  • веб-приложение (web application): приложение, исполняемое на сервере веб-приложений;
  • браузерное веб-приложение (web browser application): приложение, работающее в веб-браузере на устройстве пользователя (реализуется, как правило, на JavaScript или Flash);
  • собственное приложение (native application): приложение, работающее на устройстве пользователя, которое может не иметь возможности для отображения веб-контента.

Для авторизации запросов к API Mendeley использует ключи доступа OAuth. Ключ представляет собой длинную последовательность символов, которая содержит учетные данные безопасности (security credentials). Каждый ключ имеет ограниченный срок действия, по истечении которого он должен быть заменен заново сгенерированным ключом. Приложение, взаимодействующее с API Mendeley, должно уметь выполнять следующий цикл операций с ключами доступа:

  1. получить новый ключ через поток авторизации (authorization flow);
  2. использовать ключ доступа для авторизации запросов к API;
  3. когда ключ перестает действовать, заменить его на новый.

Mendeley API через протокол OAuth 2.0 обеспечивает реализацию трех методов получения ключа доступа для авторизации. Эти методы называются потоками (flows). Каждый из потоков создает ключи, обеспечивающие различные возможности и характеристики доступа к API. Потоки авторизации соответствуют трем указанным выше типам клиентов: Authorization Code (веб-приложения), Implicit (браузерные веб-приложения) и Client Credentials (собственные приложения). Нас интересует только этот последний поток, так наше приложение предназначено лишь для сбора данных и не будет иметь веб-интерфейса. Соответственно, ключи доступа, полученные с помощью потока авторизации Client Credentials, дают возможность клиентскому приложению искать информацию о хранящихся в каталоге документах и получать эти документы, но не изменять или добавлять их.

Поток авторизации Client Credentials состоит из:

  1. запроса на получение ключа доступа у адреса для получения ключа API (API token endpoint);
  2. извлечения ключа из ответа сервера.

2.6.2 Запрос на получение ключа

Адрес для получения ключа доступа API: https://api.mendeley.com/oauth/token. Запрос на получение ключа должен представлять собой HTTPS-запрос, удовлетворяющий следующим условиям:

  • метод запроса — POST.
  • аутентификация выполняется при помощи HTTP Basic authentication.
  • тело запроса содержит единственный параметр и значение, называемое grant_type.

В методе POST параметры запроса передаются в теле запроса, а не в строке URL как в методе GET. Поэтому POST лучше подходит для передачи конфиденциальных данных.

Аутентификация при помощи HTTP Basic authentication должна содержать два параметра:

  • username — это значение application ID, полученное при регистрации вашего приложения.
  • password. Это значение представляет собой application secret, которое также было получено при регистрации приложения. При необходимости это значение можно обновить на странице My Applications.

Значения, посылаемые в теле запроса:

  • grant_type. Должно быть равно client_credentials. Это означает, что ваше приложение запрашивает ключ доступа для самого себя.
  • scope. Должно равняться all, то есть позволять операции со всеми ресурсами API.

Вот как будет выглядеть запрос на получение ключа:

client_id     <- 'MENDELEY_CLIENT_ID'
client_secret <- 'MENDELEY_CLIENT_SECRET'

access_token_rsp <- POST('https://api.mendeley.com/oauth/token',
                         authenticate(client_id, client_secret),
                         add_headers(
                           'Content-Type' = 'application/x-www-form-urlencoded'
                         ),
                         body = 'grant_type=client_credentials&scope=all'
)

Предварительно нужно загрузить в память пакеты httr и jsonlite. Функция POST, как нетрудно догадаться, реализует одноименный метод HTTP.

Для дальнейшей работы удобно вынести базовый URL (endpoint) Mendeley API в отдельную переменную, поскольку он будет повторяться при каждом запросе к API.

endpoint <- "https://api.mendeley.com"

access_token_rsp <- POST(endpoint,
                         path = 'oauth/token',
                         authenticate(client_id, client_secret),
                         add_headers(
                           'Content-Type' = 'application/x-www-form-urlencoded'
                         ),
                         body = 'grant_type=client_credentials&scope=all'
)

2.6.3 Извлечение ключа доступа из ответа

В случае успешного выполнения запроса, сервер возвратит данные в формате JSON, содержащие ключ доступа. Ваше приложение обработает документ JSON и извлечет из него ключ.

Пример ответа сервера:

{
    "access_token": "MSwxNMWRSemRhbTVVeWYwDA4NDMzY2LDsYWxsLCw0TWtrNEFBNFJoLMSw3NzOTAzZQYWdZeEEEwMzczNDM1",
    "token_type": "bearer",
    "expires_in": 3600,
    "refresh_token": null
}

Помимо ключа доступа, объект JSON содержит и другие свойства:

  • access_token. Значение ключа доступа OAuth.
  • token_type. Mendeley API предъявляет (bearer) ключи доступа, так что это значение всегда равно bearer.
  • expires_in. Оставшийся срок действия ключа, в секундах.
  • refresh_token. Это значение должно быть равно null, поскольку поток авторизации client credentials не предусматривает использования долгоживущих ключей доступа.

В R извлечение ключа состоит из двух шагов:

  1. из переменной access_token_rsp извлекается содержимое запроса;
  2. из содержимого (списка rsp_content) извлекается элемент access_token.
rsp_content <- content(access_token_rsp)
access_token <- rsp_content$access_token 

Вот как примерно выглядит список rsp_content для только что сгенерированного ключа:

List of 6
 $ access_token : chr "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
 $ token_type   : chr "bearer"
 $ expires_in   : int 3600
 $ refresh_token: NULL
 $ msso         : NULL
 $ scope        : chr "all"

2.6.4 Замена ключа

Специальных операций для этого в API не предусмотрено. Поэтому, когда срок действия ключа завершится, приложение должно просто запросить новый ключ.

2.6.5 Обработка ошибок

Ошибки аутентификации связаны с неправильными значениями или с отсутствием значений application ID или application secret и приводят к появлению сообщения об ошибке с кодом 401 Unauthorized. При этом в теле ответа сервера вместо JSON возвращается обычный текст.

Неверно указанные значения grant_type приводят к появлению ошибки HTTP 400 Bad Request. В теле ответа сообщаются подробности об ошибке в формате JSON:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 82

{"error":"invalid_grant","error_description":"Invalid access code"}

Отсутствие значения grant type возвращает код ошибки вида invalid_request, а указание в качестве grant type значения, отличного от client_credentials приводит к появлению ошибки вида unsupported_grant_type.

3. Работа с API

Рассмотрим основные команды API, используемые для сбора данных.

3.1 Запрос документа из каталога

Выполняется при помощи HTTP-запроса:

GET https://api.mendeley.com/catalog

Параметрами запроса являются идентификаторы документа. С одним из них — doi — мы уже сталкивались. Наиболее употребительные типы идентификаторов представлены в таблице.

Идентификаторы документов, поддерживаемые Mendeley
Идентификатор Описание
doi DOI (digital object identifier) — цифровой идентификатор объекта — стандарт обозначения представленной в Интернете информации об электронном документе. DOI содержит указатель местонахождения документа, который, в отличие от обычной ссылки, позволяет найти документ даже после смены его URL.
arxiv Идентификатор публикаций, размещенных на сайте arXiv.org — бесплатном архиве научных статей и препринтов по физике, математике, астрономии, информатике, статистике и биологии.
pmid Идентификатор текстовой базы данных публикаций из области медицины и биологии PubMed.
isbn Международный стандартный книжный номер (International Standard Book Number) — идентификатор, присваиваемый каждому коммерческому книжному изданию. Необходимый для распространения книги в торговых сетях и автоматизации работы с изданием.
issn Международный стандартный серийный номер (International Standard Serial Number) — идентификатор, присваиваемый всем периодическим изданиям.
scopus Идентификатор ресурса, размещенного в базе данных Scopus.

Еще одним параметром запроса является view. Он регулирует уровень подробности информации, возвращаемой о документе. Наиболее полную информацию можно получить, указав view=all.

Атрибуты документа, возвращаемые с помощью view, мы рассмотрим далее, при реализации поиска по каталогу.

Для получения полного списка доступных идентификаторов документа существует запрос identifier_types, который в R реализуется следующим образом:

id_rsp <- GET(endpoint,
              path = 'identifier_types',
              add_headers(
                          'Authorization' = paste("Bearer", access_token),
                          'Content-Type' = 'application/vnd.mendeley-document.1+json'
                         )
              ) 

ids <- fromJSON(rawToChar(content(id_rsp)))

Что дает в результате список из 9 идентификаторов:

    name                     description
1  arxiv                        arXiv ID
2    doi                             DOI
3   isbn                            ISBN
4   issn                            ISSN
5   pmid PubMed Unique Identifier (PMID)
6 scopus         Scopus identifier (EID)
7    pui                             PUI
8    pii                             PII
9    sgr         Scopus Group Identifier

3.2 Поиск в каталоге

Поиск документов по ключевым словам реализован в API Mendeley в двух вариантах: простого и расширенного поиска.

Простой поиск по ключевым словам реализуется при помощи HTTP-запроса:

GET https://api.mendeley.com/search/catalog
Параметры поиска по каталогу
Параметр Тип Описание
query строка Ключевые слова, которые содержатся в любом из полей документа, например, в названии, списке авторов и т.п. (обязательное).
view строка Запрос на получение дополнительных полей из найденных документов (названия полей см. ниже).

Запрос query представляет собой строку из ключевых слов, разделенных пробелами.

Язык поисковых запросов
Строка запроса позволяет найти публикации, содержащие
citation analysis слова citation или analysis
citation + analysis оба слова citation и analysis
ponies | "small horses" слово ponies или точная фраза small horses
ponies +-"small horses" слово ponies, но не точная фраза small horses

Результаты поиска не зависят от регистра ключевых слов, поэтому запросы "GIS" и "gis" дадут одинаковые результаты.

Найденные документы будут отсортированы в порядке убывания в них ключевых слов из запроса.

Расширенный поиск позволяет указать поля документов, в которых должны встречаться ключевые слова запроса. Необходимо задать по крайней мере одно из следующих полей: title (название), author (автор), source (издание) или abstract (аннотация). Если поиск ведется по нескольким полям, то будут найдены все документы, удовлетворяющие запросу хотя бы по одному из полей. Сортировка результатов — в порядке убывания совпадения.

Параметры расширенного поиска
Параметр Тип Описание
title строка Ищет совпадения ключевых слов в названии документа.
author строка Ищет совпадения с именами одного или более авторов.
source строка Название издания, в котором вышла публикация.
abstract строка Поиск в аннотации.
min_year integer Самый ранний год издания.
max_year integer Самый поздний год издания.
open_access boolean Укажите true, чтобы ограничить область поиска публикациями, находящимися в открытом доступе (по умолчанию open_access = false).
view строка Запрос на выдачу дополнительных полей документа.

Параметры min_year, max_year и open_access действуют как фильтры. Указав минимальный или максимальный год, можно исключить из результатов поиска документы у которых не указан год выхода публикации.

Расширенный поиск использует тот же URL, что и поиск простой.

Атрибуты документа делятся на основные (core) и дополнительные. Основные атрибуты возвращаются при любом результативном поисковом запросе. Для получения дополнительных атрибутов документа нужно задать определенное значение параметра view.

Для каждого найденного поиском документа возвращаются следующие атрибуты.

Основные атрибуты документа
Атрибут Тип Описание
id строка Идентификатор (UUID) документа. Этот идентификатор устанавливается сервером в момент создания документа и не может быть изменен впоследствии.
title строка Название документа.
type строка Тип документа. Поддерживаемые типы: journal, book, generic, book_section, conference_proceedings, working_paper, report, web_page, thesis, magazine_article, statute, patent, newspaper_article, computer_program, hearing, television_broadcast, encyclopedia_article, case, film, bill.
abstract строка (Аннотация) Краткое резюме документа.
source строка Издание, в котором публикация увидела свет.
year integer Год издания публикации.
authors массив Список авторов документа.
identifiers массив Список идентификаторов, имеющихся у документа. Поддерживаемые идентификаторы: arxiv, doi, isbn, issn, pmid (PubMed), scopus и ssrn.
keywords массив не более 50
link строка Ссылка на страницу документа на сайте Mendeley.

Следующие атрибуты будут доступны только при использовании во время поиска параметра view.

Дополнительные атрибуты документа
Атрибут Тип Описание
month integer Месяц, в который документ был опубликован.
day integer День, в который документ был опубликован.
revision строка Номер, идентифицирующий документ (например, инвентарный номер отчета).
pages строка диапазон страниц, который документ занимает в издании, например "4-8".
volume строка том, содержащий документ. Например, “2” для 2-го тома журнала.
issue строка номер выпуска, содержащего документ. Например, “5” для статьи, помещенной в 5-м номере журнала.
websites массив Веб-сайты, на которых можно получить доступ к документу.
publisher строка Издатель документа (издательство).
city строка Город, в котором документ был опубликован.
edition массив номер издания публикации, в которой содержится документ. Например, “3” для 3-го издания книги.
institution строка Учреждение, в котором документ был опубликован.
series строка Название серийного издания, в рамках которого был опубликован документ. Например, название книжной серии.
chapter строка Номер главы.
editors массив Список редакторов документа. Как и список авторов, список редакторов представляет собой массив объектов типа person, которые включают в себя first_name (имя) и last_name (фамилию) (оба атрибута - строки).
file_attached boolean связан ли с документом медиа-файл?
reader_count integer Полное число пользователей Mendeley, которые хранят этот документ в своих библиотеках.
reader_count_by_academic_status object Число прочитавших документ пользователей, измеряемое по их академическому статусу (должности).
reader_count_by_discipline object Число пользователей по научным дисциплинам.
reader_count_by_country object Число пользователей в зависимости от страны.
group_count integer Число групп Mendeley, в которые был добавлен документ.

Параметр view позволяет управлять выбором дополнительных атрибутов документа.

Значения параметра `view`
Значение Описание
bib Возвращает основные поля документа, а также библиографические данные. Последние включают: pages, volume, issue, websites, month, publisher, day, city, edition, institution, series, chapter, revision и editors.
client Возвращает основные поля и значение file_attached.
stats Возвращает основные поля и статистические данные, включающие в себя: reader_count, reader_count_by_academic_status, reader_count_by_discipline, reader_by_country и group_count.
all Возвращает все поля.

3.3 Результаты запроса

По запросу к API может быть найдено огромное число публикаций. Чтобы снизить трафик данных, результаты запроса разбиваются на части — страницы. В ответе возвращается одна страница и ссылка на следующую страницу результатов. По умолчанию, каждая страница содержит 20 документов, а для поиска по каталогу (/search/catalog) — 10 документов.

Числом документов на странице можно управлять, изменяя параметр запроса limit. Максимальное число документов на странице равно 500 (для поисковых запросов к каталогу — 100). Превышение лимита вызывает ошибку "400 Bad Request error".

Поскольку одновременно можно получить доступ лишь к одной странице результатов, то в HTTP-заголовках ответа Link содержится URL для запроса очередной страницы. Например:

HTTP/1.1 200 OK
    Content-Type: application/vnd.mendeley-folder.1+json
    Link: <https://api.mendeley.com/folders?reverse=false&order=asc&marker=cbefa272-3734-4ea4-8b12-9effc6d948fc>; rel="next"
    Link: <https://api.mendeley.com/folders?reverse=true&order=asc>; rel="last"
    Mendeley-Count: 16
    Content-Length: 450

    ...

означает, что следующую страницу результатов (rel="next") пожно получить по адресу

https://api.mendeley.com/folders?reverse=false&order=asc&marker=cbefa272-3734-4ea4-8b12-9effc6d948fc

а последняя страница результатов запроса (rel="last") имеет URL

https://api.mendeley.com/folders?reverse=true&order=asc
Значения параметра `rel` в заголовках `Link`
Значения rel Описание
first URL для запроса первой страницы результатов. Отсутствует на первой странице результатов;
previous URL для запроса предыдущей страницы. Отсутствует на первой странице результатов;
next URL для запроса следующей страницы результатов. Отсутствует на последней странице;
last URL для запроса последней страницы. Отсутствует на последней странице результатов.

Заметим, что запросы к API, касающиеся списка научных дисциплин (disciplines), типов идентификаторов (identifier_types) и академических статусов (academic_statuses) не поддерживают разбиения на страницы. Запрос единичного документа из каталога (/catalog), естественно, также не разбивается на страницы.

Общее количество найденных документов хранится в заголовке Mendeley-Count. В примере таких документов 16.

Теперь у нас достаточно информации, чтобы рассмотреть пример поиска документа в каталоге по ключевым словам. Найдем документы, содержащие ключевое слово "gis" и разобьем результаты поисков на страницы по 100 документов на каждой.

headers <- add_headers(
                       'Authorization' = paste('Bearer', access_token),
                       'Content-Type' = 'application/vnd.mendeley-document.1+json'
                      )
my_query <- 'gis+agent+based+modeling'
lim      <- 100

rsp <- GET(endpoint,
           path = 'search/catalog', 
           query = list(query = my_query, limit = lim), 
           headers
           )

headers <- rsp$headers

Переменная headers хранит заголовки из ответа сервера:

List of 10
 $ content-encoding   : chr "gzip"
 $ content-type       : chr "application/vnd.mendeley-document.1+json"
 $ date               : chr "Tue, 10 Jan 2017 15:27:54 GMT"
 $ link               : chr "<https://api.mendeley.com/search/catalog?marker=00000000-0000-0064-0000-000000000000&query=gis&limit=100&reverse=false&order=asc>; rel=\"next\""
 $ mendeley-count     : chr "72293"
 $ vary               : chr "Accept-Encoding"
 $ vary               : chr "Accept-Encoding"
 $ x-mendeley-trace-id: chr "HEM83ctg3t4"
 $ transfer-encoding  : chr "chunked"
 $ connection         : chr "keep-alive"

Среди них есть строка mendeley-count (всего найдено 72293 документа) и ссылка link на следующую страницу результатов поиска.

Перемещение по страницам результатов поиска организуем в цикле:

# Общее число документов
all <- as.numeric( rsp$headers$`mendeley-count` ) 
# Сколько документов обработано
i <- lim
# Документы на странице
docs <- fromJSON(rawToChar(content(rsp)), simplifyDataFrame = F)

repeat {
  cat("Proceed", i, "from", all, "...\n")

  link <- rsp$headers$link
  rsp <- GET(str_match(link, '<(.+)>')[[2]], headers)
  tdocs <- fromJSON(rawToChar(content(rsp)), simplifyDataFrame = F)
  docs <- append(docs, tdocs)
  if (!str_detect(link, 'next')) break
  i <- i + lim
}

# Сохранение результатов
save(docs, file = "readership.RData")

Результаты поиска сохранены в бинарном файле readership.RData.

3.4 Список документов пользователя/группы

Запрос:

GET https://api.mendeley.com/documents

возвращает список документов заданного пользователя или группы.

В отличие от команд catalog и search/catalog, предназначенных только для чтения (списка) документов, команда documents предназначена для всесторонней работы с документами, в том числе и для их удаления.

Параметры команды `documents`
Параметр Тип Описание
view строка включает основные поля документа и задает отображение дополнительных полей.
profile_id строка идентификатор профиля, которому принадлежит документ, если только он не принадлежит какой-либо группе. Если не указан, то возвращается документ (текущего) пользователя.
group_id строка идентификатор группы, которой принадлежит документ. Если не указан, то возвращается документ (текущего) пользователя.
modified_since строка возвращает только документы, измененные после указанной даты. Дата должна быть задана в формате ISO 8601.
deleted_since строка возвращает только документы, удаленные после указанной даты. Дата должна быть задана в формате ISO 8601.
limit строка максимальное число документов на странице результатов. Если не задано, то по умолчанию равно 20. Максимальное значение - 500.
order строка способ сортировки
sort строка поле, по которому выполняется сортировка

Коллекции документов, возвращаемые /documents, могут быть отсортированы. Сортировка изменяет порядок вывода результатов и ее удобно применять к большим коллекциям документов. Ваше приложение может изменять порядок выдачи документов при помощи двух полей HTTP-запроса — sort и order. Чтобы вывести документы, названия которых отсортированы в порядке от A до Z, нужно сделать следующий запрос:

GET /documents?sort=title&order=asc
  • sort — поле, по которому сортируются документы. Для запросов /documents возможны следующие значения этого поля: title (название), created (дата создания) и last_modified (дата последнего изменения). Для запросов /trash возможны значения: document_id и deleted_at.
  • order — порядок расположения результатов. Значения asc (по возрастанию) располагает результаты от наименьшего значения к наибольшему. Значение desc располагает результаты в порядке убывания. Если порядок выдачи не указан, то результаты располагаются по возрастанию.
rsp <- GET(endpoint, 
           path = 'documents',
           query = list(sort = 'title', order = 'asc'), 
           headers
          )

3.5 Получение списка научных дисциплин

Запрос

GET https://api.mendeley.com/disciplines

возвращает в случае успеха (200 OK) список всех дисциплин и субдисциплин, на которые разделены документы в каталоге Mendeley.

sa_rsp <- GET(endpoint,
              path = 'subject_areas',
              headers
              )

3.6 Как получить оригинальную публикацию по данным из документа

Один из основных атрибутов документа — identifiers — возвращает список идентификаторов данного документа. Некоторые из этих идентификаторов, например, arxiv, указывают на адрес, по которому можно скачать оригинал публикации.

Среди дополнительных атрибутов документа для получения оригинальной публикации будут полезны:

  • websites — список веб-сайтов, на которых можно получить доступ к документу;
  • file_attached — возвращает логическое значение, указывающее приложен или нет к данному документу файл (возможно, оригинал публикации). Файлы, в свою очередь, имеют атрибут mime_type (тип содержимого). Так, mime_type = pdf указывает на то, что к документу приложен PDF-файл, возможно, с оригиналом публикации. С помощью mime_type можно также выбрать интересующий формат файла.

4. Исследование читательской аудитории

Данные о читательской аудитории публикации содержатся в (дополнительных) атрибутах документа:

  • reader_count — сколько человек прочитало статью;
  • reader_count_by_country — читатели из каких стран прочли статью;
  • reader_count_by_academic_status — какие должности занимают читатели данной статьи;
  • reader_count_by_discipline — представители каких научных дисциплин прочли статью.

Значения этих атрибутов возвращаются по запросам к API с параметром views=stats или views=all.

4.1 Какие публикации относятся к заданной теме

Чтобы оценить читательскую аудиторию целого научного направления необходимо выделить относящиеся к этому направлению публикации. Документы в Mendeley не содержат атрибутов, указывающих на принадлежность к тому или иному направлению (такие атрибуты есть в профилях пользователей системы).

Одним из способов решения этой проблемы может быть выделение изданий (журналов), относящихся к данному направлению. В качестве примера, рассмотрим публикации в области геоинформационных систем (ГИС). Чтобы выделить издания, посвященные этому направлению, нужна информация из авторитетных индексов научных публикаций: Web of Science или Scopus. Выбрав в них список журналов по ГИС можно затем искать публикации из этих журналов, размещенные в Mendeley.

Такой способ требует существенных дополнительных затрат. Технически, получить список изданий возможно (Scopus даже имеет собственный API). Проблема в том, что доступ к указанным индексам — платный. Другим недостатком является то, что таким образом мы выделим лишь часть публикаций, в основном книги и журналы, тогда как другие останутся не замеченными.

Еще одним вариантом выделения статей, относящихся к области ГИС, является использование ключевых слов, указанных самими авторами публикаций. Так, существует атрибут документа keywords, содержащий список ключевых слов. Выделив ядро публикаций для которых достоверно известно, что они относятся к ГИС (например, по ключевому слову "gis"), можно собрать из этих публикаций ключевые слова и, выбрав наиболее часто встречающиеся, составить таким образом список ключевых слов, характеризующих все направление ГИС. Для выбора ключевых слов помимо keywords можно использовать и другие атрибуты документа, в частности, Название публикации (title) и ее аннотацию (abstract).

Как видно, выбор ключевых слов, характеризующих научное направление, сам по себе является научной задачей. Нашей же задачей является автоматизация сбора данных. Поэтому оставим задачу выбора ключевых слов для будущих исследований и займемся оценкой читательской аудитории публикаций, которые гарантированно относятся к области ГИС. К таким публикациям мы отнесем все публикации, в которых содержится ключевое слово "gis".

4.2 Сравнение объемов коллекций документов на разных языках

Ясно, что большинство публикаций, относящихся к области ГИС, написано на английском языке. Однако насколько велико это большинство? Можно ли хотя бы в первом приближении ограничится рассмотрением публикаций на английском языке или необходимо сразу учитывать публикации на других языках?

К сожалению, информации о языке публикации в документах Mendeley не сохраняется. Поэтому мы выполнили поиск по ключевому слову "gis" и его переводам на другие языки: китайский и русский. Заметим, что сокращение "GIS" используется не только в английском, но и в других языках, в частности, в немецком. Поэтому фактически мы отвечаем на вопрос, можно ли ограничиться рассмотрением публикаций, содержащих ключевое слово "gis". При этом найденные публикации могут быть не только на английском языке.

Поиск переводов ключевых слов выполнялся при помощи Википедии. За основу бралась статью Geographic information system в англоязычной редакции Википедии. Из нее выбирали термин (ГИС) и искали перевод этого термина в статьях на других языках. Результаты проверялись обратным переводом терминов на английский язык при помощи переводчика Google.

Запросы на разных языках поместим в таблицу df. Таким образом можно хранить запросы, состоящие из нескольких ключевых слов. В цикле делается запрос поочередно на каждом из языков, после чего в df сохраняется количество найденных на этом языке документов.

queries <- c("gis", "英语", "гис")

# Запросы на разных языках
df <- data.frame(lang=c("en", "cn", "ru"), 
                 query=queries, 
                 num.of.docs=rep(0,length(queries)))

# Определение числа документов на каждом из языков
for (i in 1:nrow(df)) {
  rsp <- GET(endpoint,
             path = "search/catalog",
             query = list(query = queries[i]),
             headers)
  count <- headers(rsp)$`mendeley-count`
  if ( !is.null(count) ) {
    df$num.of.docs[[i]] <- as.integer(count)
  }
}

# Вычисление процента от общего числа документов
percent <- round( df$num.of.docs/sum(df$num.of.docs)*100, digits=2 )
# Вывод результатов в виде таблицы
cbind(df[,-2],percent)

Результаты представлены в таблице.

Язык Количество документов %
en 87601 96.04
cn 3588 3.93
ru 24 0.03

Таким образом видно, что в первом приближении можно ограничится результатами на английском и близких языках, так как даже результаты на китайском составляют менее 4% от общего числа найденных документов.

Мы предполагали, что ключевое слово "gis" всегда относится к геоинформационным системам. Решение вопроса так это или нет требует дальнейших исследований.

4.3 Сбор статистики читательской аудитории

Соберем полный список документов, посвященных ГИС и содержащих статистические данные по их читательской аудитории. Для этого воспользуемся поиском по каталогу документов Mendeley.

Начнем с формирования запроса к API для поиска по ключевым словам query и получения читательской статистики (Значение view равно stats).

my_query <- 'gis' # ключевые слова
lim <- 100     # число документов на странице выдачи

rsp <- GET(endpoint,
           path = 'search/catalog', 
           query = list(query = my_query, limit = lim, view = 'stats'), 
           headers
           )

Первый запрос позволяет определить общее число найденных документов (в заголовке mendeley-count). Найденные на странице результатов документы добавляются в список docs.

# Общее число документов
all <- as.numeric( rsp$headers$`mendeley-count` ) 
# Число необработанных документов
cur <- all
# Документы на странице
docs <- fromJSON(rawToChar(content(rsp)), simplifyDataFrame = F)

Затем в цикле выполняются запросы по остальным страницам результатов поиска. На каждом шаге цикла из результатов прошлого запроса выделяется URL очередной страницы (при этом используется функция str_match из библиотеки stringr) и делается запрос к ней. Результаты запроса также добавляются в docs. При этом уменьшается число необработанных документов cur. Цикл выполняется до тех пор, пока все документы не будут обработаны.

while (lim < cur) {
  cur <- cur-lim
  cat("Left", cur, "from", all, "...\n")
  rsp <- GET(str_match(rsp$headers$link, '<(.+)>')[[2]], headers)
  tdocs <- fromJSON(rawToChar(content(rsp)), simplifyVector=F)
  docs <- append(docs, tdocs)
}

Другой вариант обработки страниц результатов поиска показан в п. 3.5.

4.4 Популярность статей и объем читательской аудитории

Атрибут reader_count позволяет определить, какая из публикаций по ГИС самая популярная (по числу прочтений) и сколько всего раз пользователи Mendeley читали публикации, посвященные ГИС.

Составим таблицу наиболее популярных публикаций по числу просмотров.

Загрузим список найденных ранее документов. В памяти для него будет создана переменная docs (именно этот список мы сохраняли в файле).

load("readership.RData")

Извлечем из списка docs для каждого документа три поля: идентификатор документа в Mendeley (id), название документа (title) и статистику прочтений (reader_count). Преобразуем выделенную часть списка в таблицу и упорядочим ее по убыванию, чтобы вверху таблицы оказались наиболее популярные публикации.

# Получаем список просмотров статей пользователями Mendeley
count <- function(x) {
  list(id=x$id, title=x$title, reader_count=x$reader_count)
}
lcount <-lapply(docs, count) 

# Преобразуем список в таблицу
dfcount <- do.call(rbind.data.frame, lcount)
# и упорядочиваем ее по убыванию
dfcount <- dfcount[order(dfcount$reader_count,decreasing = T),]

В результате получим следующую таблицу.

title reader_count
Predictive habitat distribution models in ecology 7971
Object based image analysis for remote sensing 1460
A Practical guide to Geostatistical Mapping 1297
Integrating GIS-based environmental data into evolutionary biology 1295
Environmental niche equivalency versus conservatism: Quantitative approaches to niche evolution 1175
Local Indicators of Spatial Association???LISA 1145

Определим среднее число просмотров публикаций по ГИС.

# всего публикаций
length(docs)
# общее число прочтений
sum(dfcount$reader_count)
# среднее число прочтений публикации по ГИС (на английском)
round(sum(dfcount$reader_count)/length(docs))

В настоящее время оно равно 15.

4.5 В каких странах читают публикации по теме

Дополнительный атрибут документа reader_count_by_country возвращает список стран, пользователи из которых читали документ, и количество читателей документа для каждой из этих стран.

Составление таблицы стран, пользователи из которых читают публикации по ГИС, выполняется аналогично примеру из предыдущего пункта. Однако представлять результаты нагляднее на карте. Займемся составлением карты по данным о числе просмотров по странам.

Данные о числе просмотров (views) по странам (country) хранятся в таблице, которая имеет следующий вид:

         country views
1    Afghanistan     3
2        Algeria   102
3 American Samoa     4
4        Andorra     5
5         Angola     2
6     Antarctica     2

Для работы с картами используется пакет rworldmap, который нужно установить и загрузить.

Далее с помощью функции joinCountryData2Map данные пользователя в виде таблицы, содержащей названия или коды стран, присоединяются ко внутреннему представлению карты (внутри пакета rworldmap). Таким образом данные подготавливаются к отображению.

spdf <- joinCountryData2Map(cdf, joinCode="NAME", nameJoinColumn="country")
  • первый аргумент — таблица с пользовательскими данными (cdf);
  • joinCode определяет, как указываются страны (по названию - "NAME", по коду - "ISO2", "ISO3" и т. п.);
  • nameJoinColumn — имя колонки, содержащее названия (коды) стран.
  • mapResolution — разрешение карты, по умолчанию равно "coarse" (грубое).

Создадим графическое устройство для вывода карты. По терминологии R окна, в которых строятся графики, и файлы, в которых эти графики сохраняются, вместе называются графическими устройствами. Графическое устройство позволит нам, в частности, изменять размер карты.

mapDevice()

Названия графических устройств стандартные для R. Получить справку по доступным графическим устройствам можно при помощи команды:

?Devices

Отобразим теперь данные на карте функцией mapCountryData.

mapParams <- mapCountryData(spdf, nameColumnToPlot="views", 
                            catMethod="fixedWidth", 
                            mapTitle = "Map")
  • первый аргумент — spdf — объект с данными о странах, привязанными ко внутреннему представлению карты (SpatialPolygonsDataFrame), созданный с помощью joinCountryData2Map();
  • nameColumnToPlot — имя колонки, содержащей данные для отображения;
  • catMethod — метод категоризации данных. В нашем случае используется один из методов, предназначенный для отображения непрерывных числовых данных;
  • mapTitle — заголовок карты.

Другие полезные параметры mapCountryData():

  • colourPalette — название палитры цветов;
  • add (TRUE/FALSE) — логический параметр, определяющий добавлять или нет отображение к ранее существовавшей карте (по умолчанию add = FALSE).

Добавим легенду:

do.call( addMapLegend, c(mapParams, legendLabels="all") )

Функция identifyCountries выводит название страны и значение заданных атрибутов, когда пользователь кликает по карте. Ее удобно использовать, когда на карте изображено много стран, атрибуты которых при отображении накладываются друг на друга.

identifyCountries(spdf, nameCountryColumn="NAME", nameColumnToPlot="views")
# аргументы - см. labelCountries
  • nameCountryColumn — какая колонка будет отображаться в качестве метки страны (в нашем случае та, что имеет метку "NAME", то есть колонка "country");
  • nameColumnToPlot — имя колонки, значения из которой будут добавляться к названию страны. Мы будет отображать на карте название страны и число просмотров документов.

Если рассматривается сравнительно небольшой фрагмент карты, так что атрибуты стран при отображении не пересекается, то можно воспользоваться функцией labelCountries, которая постоянно отображает все заданные атрибуты.

В результате получилась следующая карта.

Карта читателей статей по ГИС

Карта читателей статей по ГИС

Заметим, что дополнительный атрибут документа country возвращает название страны, в которой документ был опубликован. Неясно, имеется ли в виду страна проживания человека, опубликовавшего данный документ в Mendeley или страна, где вышла исходная публикация. Эти данные также могут быть представлены на карте.

4.6 Другие сведения о читательской аудитории

Сбор остальной имеющейся информации о читательской аудитории выполняется аналогично рассмотренным выше примерам.

Так, атрибут reader_count_by_discipline позволяет определить, представители каких научных дисциплин чаще всего смотрят статьи по ГИС и выделить наиболее влиятельные публикации (в смысле их использования специалистами из других областей науки).

Атрибут reader_count_by_academic_status разделяет читательскую аудиторию по должностям (принятым в США и Европе). С его помощью можно, например, выяснить, какие публикации пользуются наибольшей популярностью у студентов и аспирантов. Заметим, что термин "academic status" не очень точен, поскольку в списке должностей представлены в числе прочих исследователи, не относящиеся к академической среде.



Комментарии

comments powered by Disqus