CoderCastrov logo
CoderCastrov
Академия

Отслеживание цитирования в Google Scholar с использованием SerpAPI

Отслеживание цитирования в Google Scholar с использованием SerpAPI
просмотров
7 мин чтение
#Академия

Вы хотите собирать данные с профилей Google Scholar без необходимости решать CAPTCHA и нарушать условия использования? Это можно легко сделать (бесплатно!) с помощью Serpapi. Да, действительно бесплатно, без необходимости добавления платежного метода! Вам просто нужно создать учетную запись для записи вызовов API, и вы будете ограничены 100 вызовами в месяц, но для наших целей этого достаточно.

SerpAPI

Недавно у меня возникла идея создать простой автоматизированный скрипт для сбора данных с моего профиля в Google Scholar и определения, изменилось ли общее количество цитирований, а затем уведомить меня по электронной почте о новом количестве цитирований. Ранее я изучал возможность сбора данных с Google Scholar, но меня отпугнули сложности, связанные с потенциальным нарушением условий использования и необходимостью решения CAPTCHA. И вот я нашел решение в этом простом в использовании API. Сначала вам нужно создать учетную запись на их веб-сайте https://serpapi.com/. После создания учетной записи они предлагают уникальную "площадку", где вы можете изучить их встроенные возможности парсинга и визуализировать код на заднем плане (на нескольких языках, включая Python), когда вы используете их API.

После создания бесплатной учетной записи вы можете перейти на панель инструментов и заметите, что есть API для множества поисковых систем Google. Нас, конечно же, интересует Google Scholar. Внизу левой панели инструментов вы увидите ссылку на "площадку". Этот пользовательский интерфейс позволяет вам исследовать несколько функций поиска в API Google Scholar. В данной статье нас интересует функция "Автор". Теперь вам нужно найти конкретного автора для поиска и получить его уникальный идентификатор, находящийся в URL его профиля в Google Scholar. Например, мой собственный идентификатор можно извлечь из URL моего профиля: https://scholar.google.com/citations?user=NKw-aEsAAAAJ&hl=en, где идентификатор - это символы между user= и =en, или NKw-aEsAAAAJ&hl. Это будет вставлено в строку поиска в площадке SerpAPI, как показано ниже.

Интерфейс площадки SerpAPI

SerpAPI удобно генерирует HTML-представление профиля ученого слева и JSON-вывод, который является результатом вызова API, который мы только что выполнили, справа. Более того, они генерируют фрагменты кода, которые можно реализовать, нажав выпадающий список "Экспорт в код" в правом верхнем углу площадки. Обратите внимание, что ваш уникальный ключ API будет виден при нажатии на эту кнопку.



Извлечение данных

Теперь, когда мы ознакомились с некоторыми функциями веб-приложения, мы можем приступить к реализации API в нашем собственном коде для извлечения нужных данных из поиска по автору. Сначала давайте загрузим необходимые библиотеки Python для запуска нашего кода. Мы можем сделать это, выполнив команду "pip install google-search-results". Все остальные библиотеки должны быть встроены в вашу установку Python. Теперь, когда у нас есть доступ к библиотеке SerpAPI Python, давайте посмотрим, как выглядит код SerpAPI, который мы сгенерировали на предыдущем шаге.

#!/usr/bin/env python3
import os
from serpapi import GoogleSearch
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from datetime import datetime

params = {
  "api_key": "1234",
  "engine": "google_scholar_author",
  "hl": "en",
  "author_id": "NKw-aEsAAAAJ&hl"
}

search = GoogleSearch(params)
results = search.get_dict()

Вы можете видеть минимальный код, необходимый для выполнения вызова API. В целях безопасности я вставил фиктивный api_key, но это поле будет автоматически заполняться вашим персональным ключом, когда вы сгенерируете фрагмент кода для себя в веб-приложении SerpAPI. Затем мы выполняем поиск после передачи нашего словаря params в наш класс GoogleSearch и возвращаем результат в виде словаря, изображенного ниже.

{'search_metadata': {'id': '6484c8ad797ac6f7829666e9',
  'status': 'Success',
  'json_endpoint': 'https://serpapi.com/searches/e64f3a011f93c677/6484c8ad797ac6f7829666e9.json',
  'created_at': '2023-06-10 19:02:05 UTC',
  'processed_at': '2023-06-10 19:02:05 UTC',
  'google_scholar_author_url': 'https://scholar.google.com/citations?user=NKw-aEsAAAAJ&hl&hl=en',
  'raw_html_file': 'https://serpapi.com/searches/e64f3a011f93c677/6484c8ad797ac6f7829666e9.html',
  'total_time_taken': 0.92},
 'search_parameters': {'engine': 'google_scholar_author',
  'author_id': 'NKw-aEsAAAAJ&hl',
  'hl': 'en'},
 'author': {'name': 'Ryan Cali',
  'affiliations': 'University of Southern California',
  'email': 'Verified email at loni.usc.edu',
  'website': 'https://ryanjcali.com/',
  'interests': [{'title': 'Neuroimaging',
    'link': 'https://scholar.google.com/citations?view_op=search_authors&hl=en&mauthors=label:neuroimaging',
    'serpapi_link': 'https://serpapi.com/search.json?engine=google_scholar_profiles&hl=en&mauthors=label%3Aneuroimaging'},
   {'title': 'Computer Vision',
    'link': 'https://scholar.google.com/citations?view_op=search_authors&hl=en&mauthors=label:computer_vision',
    'serpapi_link': 'https://serpapi.com/search.json?engine=google_scholar_profiles&hl=en&mauthors=label%3Acomputer_vision'},
   {'title': 'Neuroinformatics',
    'link': 'https://scholar.google.com/citations?view_op=search_authors&hl=en&mauthors=label:neuroinformatics',
    'serpapi_link': 'https://serpapi.com/search.json?engine=google_scholar_profiles&hl=en&mauthors=label%3Aneuroinformatics'},
   {'title': 'Deep Learning',
    'link': 'https://scholar.google.com/citations?view_op=search_authors&hl=en&mauthors=label:deep_learning',
    'serpapi_link': 'https://serpapi.com/search.json?engine=google_scholar_profiles&hl=en&mauthors=label%3Adeep_learning'}],
  'thumbnail': 'https://scholar.googleusercontent.com/citations?view_op=view_photo&user=NKw-aEsAAAAJ&citpid=3'},
 'articles': [{'title': 'Traffic-related particulate matter affects behavior, inflammation, and neural integrity in a developmental rodent model',
   'link': 'https://scholar.google.com/citations?view_op=view_citation&hl=en&user=NKw-aEsAAAAJ&citation_for_view=NKw-aEsAAAAJ:u-x6o8ySG0sC',
   'citation_id': 'NKw-aEsAAAAJ:u-x6o8ySG0sC',
   'authors': 'BC Nephew, A Nemeth, N Hudda, G Beamer, P Mann, J Petitto, R Cali, ...',
   'publication': 'Environmental research 183, 109242, 2020',
   'cited_by': {'value': 51,
    'link': 'https://scholar.google.com/scholar?oi=bibs&hl=en&cites=5789389595483332396',
    'serpapi_link': 'https://serpapi.com/search.json?cites=5789389595483332396&engine=google_scholar&hl=en',
    'cites_id': '5789389595483332396'},
  {'title': 'The Influence of Brain MRI Defacing Algorithms on Brain-Age Predictions via 3D Convolutional Neural Networks',
   'link': 'https://scholar.google.com/citations?view_op=view_citation&hl=en&user=NKw-aEsAAAAJ&citation_for_view=NKw-aEsAAAAJ:WF5omc3nYNoC',
   'citation_id': 'NKw-aEsAAAAJ:WF5omc3nYNoC',
   'authors': 'RJ Cali, R Bhatt, SI Thomopoulos, S Gadewar, IB Gari, T Chattopadhyay, ...',
   'publication': 'bioRxiv, 2023.04. 28.538724, 2023',
   'cited_by': {'value': None, 'link': 'https://scholar.google.com'},
   'year': '2023'}],
 'cited_by': {'table': [{'citations': {'all': 98, 'since_2018': 98}},
   {'h_index': {'all': 5, 'since_2018': 5}},
   {'i10_index': {'all': 4, 'since_2018': 4}}],
  'graph': [{'year': 2019, 'citations': 1},
   {'year': 2020, 'citations': 4},
   {'year': 2021, 'citations': 21},
   {'year': 2022, 'citations': 52},
   {'year': 2023, 'citations': 19}]},

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

# Индекс для доступа к ключу 'all' и возврат его значения
current_citation_count = results['cited_by']['table'][0]['citations']['all']

# Это должно вернуть 98, как вы можете видеть в вышеуказанном JSON в строке 'cited_by'


Получение обновления количества цитирований

Теперь нам нужно реализовать метод, который будет брать наше количество цитирований и вставлять его в сообщение электронной почты, которое мы можем отправлять себе с любой частотой. Я хотел получить дату и время для уведомлений по электронной почте, поэтому я просто импортировал библиотеку 'datetime' и сгенерировал читаемую для человека дату и время. Затем мне понадобился метод для отслеживания моего текущего количества цитирований и отправки электронного письма только в том случае, если это число изменилось. Есть несколько способов сделать это, но самым простым способом было создать текстовый файл на моей локальной системе, который находится на том же уровне, что и этот скрипт, и иметь скрипт ссылаться на него каждый раз при запуске для сравнения количества цитирований в вызове SerpAPI с существующим в текстовом файле. Это означает, что если мой текстовый файл содержит 97, а мой вызов API возвращает словарь, содержащий 98, как указано выше, будет отправлено электронное письмо, и текстовый файл будет обновлен до 98. Если нет разницы между двумя значениями, электронное письмо не будет отправлено.

# Получить текущую дату и время
now = datetime.now()

# Получить формат в виде месяца, дня, года
formatted_now = now.strftime("%m/%d/%Y")
# Получить день недели
day_of_week = now.strftime("%A")

# Вывести в формате вторник, название месяца, номер дня и год
human_date = (day_of_week + ", " + now.strftime("%B") + " " + now.strftime("%d") + ", " + now.strftime("%Y"))

last_citation_count_file = '/Users/ryancali/Code/projects/citation_count/last_citation_count.txt'
if os.path.exists(last_citation_count_file):
    with open(last_citation_count_file, 'r') as f:
        last_citation_count = int(f.read())
else:
    last_citation_count = None

# Создать функцию для отправки электронной почты
def send_email(subject, message, from_addr, to_addr, password):
    msg = MIMEMultipart()
    msg['From'] = from_addr
    msg['To'] = to_addr
    msg['Subject'] = subject

    body = message
    msg.attach(MIMEText(body, 'plain'))

    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()  # Защитить соединение
    server.login(from_addr, password)
    text = msg.as_string()
    server.sendmail(from_addr, to_addr, text)
    server.quit()

# Если количество цитирований увеличилось, отправить электронное письмо
if last_citation_count is None or current_citation_count > last_citation_count:
    from_addr = "myemail@gmail.com"
    to_addr = from_addr  # отправка письма самому себе
    password = "myapppassword" 
    subject = "На " + human_date + " ваше количество цитирований составляет: " + str(current_citation_count)
    message = "Ваше количество цитирований теперь: " + str(current_citation_count)
    send_email(subject, message, from_addr, to_addr, password)

    # сохранить новое количество цитирований
    with open(last_citation_count_file, 'w') as f:
        f.write(str(current_citation_count))

Примечание для пользователей Gmail:

Если вы используете Gmail, как и я, вам, скорее всего, понадобится пароль для приложения электронной почты, который можно создать, следуя инструкциям, указанным здесь: https://support.google.com/accounts/answer/185833?hl=ru

Планирование скрипта

Сначала, чтобы убедиться, что наш скрипт может быть выполнен, мы должны запустить 'chmod x+ /путь/к/нашему/script.py'. Для планирования я решил использовать Crontab, чтобы запланировать выполнение скрипта каждый день в 9 утра (формат Crontab: * 09 * * *), но вы также можете обернуть скрипт в другой скрипт на Python, который имеет свою собственную функцию планирования. Если вы используете Mac или Linux, вы можете просто открыть терминал и ввести 'crontab -e', чтобы создать файл с инструкциями для планирования. Если вы используете Windows, вы можете сделать то же самое с помощью планировщика задач. Для удобного форматирования Crontab вы можете использовать этот полезный сайт: https://crontab.guru. Ниже приведено содержимое моего файла Crontab. Обратите внимание, что я указываю полный путь к моему интерпретатору Python, а затем полный путь к скрипту.

0 9 * * * /Users/ryancali/opt/anaconda3/envs/ryan_env/bin/python /Users/ryancali/Code/projects/citation_count/citation_counter.py

Заключение

Email notification after running the script

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