Всем привет! В этом посте я хочу рассказать про некоторые возможности автоматизации задач, с которыми сталкивается программист-исследователь.
В моей работе часто возникает потребность изучать научные статьи. Это помогает быть в курсе событий, а также исследовать новые методы и области.
Бывает очень полезно фиксировать прочитанную информацию, чтобы не приходилось постоянно возвращаться к одному и тому же материалу, чтобы что-то найти. Обычно я веду заметки, но переносить туда ссылки на статьи, скачивать их, создавать таблицы бывает муторно. Огромную работу проделали создатели гитхаб репозиториев-агрегаторов статей по определённым темам. Например, статьи про клоны кода или статьи про фаззинг. Эти репозитории заставили меня задуматься над автоматизацией создания таких списков статей. В результате я определила последовательность действий, которую я выполняю при исследовании новой темы:
-
Шаг 1. Поиск статей в известных источниках (например, Semantic Scholar или arxiv)
-
Шаг 2. Чтение аннотаций к статьям, по которым часто можно понять, подходят ли они по тематике.
-
Шаг 3. Выделение важных объектов из статей: к ним можно отнести ссылки на гитхаб, графики, картинки (чтобы можно было, например, сослаться на результаты статьи в своей презентации, не испортив качество объекта при вставке) , а также год написания и журнал для понимания уровня статьи и актуальности.
-
Шаг 4. Подробное изучение выбранных статей.
Сбор информации для первых трёх шагов можно автоматизировать. Остановимся подробнее на них.
Поиск статей
Semantic Scholar и arxiv имеют специальное API для поиска статей по запросу. С помощью него можно узнать базовую информацию про статьи и скачать их при наличии открытого доступа.
Например, исходя из документации для arxiv, для поиска статей по запросу потребуется написать подобный код:
import arxiv # Construct the default API client. client = arxiv.Client() # Search for the 10 most recent articles matching the keyword "quantum." search = arxiv.Search( query = "quantum", max_results = 10, sort_by = arxiv.SortCriterion.SubmittedDate ) results = client.results(search)
Для найденных статей можно получить аннотацию, авторов, год публикации, ссылку на скачивание в случае открытого доступа и т.д:
papers = [ { "title": result.title, "authors": ", ".join([author.name for author in result.authors]), "journal": result.journal_ref, "year": result.published.year, "abstract": result.summary, "openAccessPdf": {"url": result.pdf_url}, "paperId": result.entry_id.split("/")[-1], # last part of url after slash } for result in results ]
Статьи можно скачать с помощью следующего кода:
results = client.results(search) paper_to_download = next(results) paper_to_download.download_pdf(dirpath=".", filename="some-article.pdf")
Для Semantic Scholar примеры использования API есть в репозитории.
Аналогичный по содержанию код для Semantic Scholar API может выглядеть следующим образом:
import requests import json from datetime import datetime x_api_key = "your-api-key" # you can get it from official site class SemanticScholarClient: def __init__(self): self.base_url = "https://api.semanticscholar.org/graph/v1" def search(self, query, max_results=10, sort_by="relevance"): endpoint = f"{self.base_url}/paper/search" params = { "query": query, "limit": max_results, "fields": "paperId,title,isOpenAccess,openAccessPdf,abstract,year,authors,citationCount,url,venue", "sort": sort_by } headers = { "X-API-KEY": x_api_key } response = requests.get(endpoint, params=params, headers=headers) response.raise_for_status() return response.json()['data'] class SemanticScholarSearch: def __init__(self, query, max_results=10, sort_by="relevance"): self.query = query self.max_results = max_results self.sort_by = sort_by # Usage client = SemanticScholarClient() # Search for the 10 most recent articles matching the keyword "quantum." search = SemanticScholarSearch( query="quantum", max_results=10, sort_by="publicationDate:desc" # Sort by publication date, descending ) results = client.search(search.query, search.max_results, search.sort_by) papers = [ { "title": result['title'], "authors": ", ".join([author['name'] for author in result['authors']]), "journal": result.get('venue', ''), "year": result['year'], "abstract": result.get('abstract', ''), "openAccessPdf": {"url": result.get('openAccessPdf', {}).get('url', '')} if result.get('openAccessPdf', {}) else None, "paperId": result['paperId'], } for result in results if result ] # Download papers for paper in papers: if paper['openAccessPdf']: print(f"Title: {paper['title']}") response = requests.get(paper['openAccessPdf']['url']) response.raise_for_status() filepath = f"{paper['title']}.pdf" with open(filepath, 'wb') as f: f.write(response.content)
Выделение объектов
Для автоматизации выделения объектов из статьи можно использовать библиотеку pdfplumber. В написании кода с использованием этой библиотеки очень помогла статья. С помощью парсинга элементов в PDF и регулярных выражений можно извлекать существующие в статье ссылки на гитхаб:
import pdfplumber import re def extract_text_from_pdf(pdf): text = "" for page in pdf.pages: text += page.extract_text() + "\n" return text.strip() pdf = pdfplumber.open("some-article.pdf") text_from_pdf = extract_text_from_pdf(pdf) github_regex = r"https?://(?:www\.)?github\.com/[\w-]+/[\w.-]+[\w-]" github_links = re.findall(github_regex, text_from_pdf)
Для извлечения картинок подходит библиотека PyMuPDF. Вот подробный гайд про использование библиотеки. Для сохранения картинок из статьи можно написать следующий код:
import fitz doc = fitz.Document("some-article.pdf") for i in tqdm(range(len(doc)), desc="pages"): cnt = 0 # counter to divide images on one page for img in tqdm(doc.get_page_images(i), desc="page_images"): xref = img[0] image = doc.extract_image(xref) pix = fitz.Pixmap(doc, xref) pix.save("img_%s_%s.png" % (i, cnt)) cnt += 1
Не во всех случаях указанным методом удаётся извлечь все изображения из статей, поэтому в этой задаче есть огромное пространство для размышлений и идей по улучшению метода.
Перечисленные этапы реализованы в репозитории Researcher-Helper. На данный момент в нём поддерживается поиск по Semantic Scholar и arxiv. В результате он позволяет сгенерировать по запросу таблицу со статьями в формате html. Буду рада обратной связи, идеям по улучшению и советам в реализации описанных этапов!
ссылка на оригинал статьи https://habr.com/ru/articles/846704/
Добавить комментарий