目的: 論文のPubMedID(PMID)を指定して、その参考文献一覧のPMIDのリストを取得したい。
レビュー論文を読んでいると、引用文献の各原著論文を確認するにあたり、それらのPDFファイルをすべて取得したい場合がある。PubMedのページで引用文献の一覧をリンク付きで表示できるのだが、PMID一覧で表示するオプションがない(PubMedでの検索結果をPMIDで表示するオプションはある)。いちいちリンクをたどるのは面倒なので、引用文献のPMID一覧を取得できれば、EndNoteなどの文献管理ソフトで引用文献のPDFファイルを自動で取得することが簡単にできる。
解決法:対象論文のPubMedページをスクレイピングしてPMID一覧を取得する。
Step 0. 準備
Pythonでは、以下のライブラリをインストールしておく。
・bs4
・requests
・numpy
Beautiful Soupの詳細は以下を参照。
Requestsの詳細はこちら。
Rでは、以下のパッケージが必要
・rvest
・tidyverse
rvestの詳細は以下を参照。
tidyverseの詳細はこちら。
必要に応じてプロキシの設定をしておく。
Step 1. スクレイピング
ここでは文献PMID:36960167の引用文献のPMID一覧をダウンロードする場合を考える。
Pythonバージョン
import re
import requests
from bs4 import BeautifulSoup
import numpy as np
pmid = '36960167' #your_target_PMID
print("Getting reference PMIDs in the paper PMID:" + pmid)
url = 'https://pubmed.ncbi.nlm.nih.gov/' + pmid + '/references/'
response = requests.get(url)
# If your envirnment uses proxy, "verify=False" is required.
# response = requests.get(url, verify=False)
response.encoding = response.apparent_encoding
bs = BeautifulSoup(response.text, 'html.parser')
# Extract <a>tag containing "PubMed" as a content
pubmed_tag_list = []
for i in bs.find_all("a"):
if re.search('PubMed', i.text):
pubmed_tag_list.append(i)
# Extract PMIDs as integer
pmid_number_list = []
for i in pubmed_tag_list:
pmid = i.get('href').strip('/')
pmid_number_list.append(int(pmid))
np.savetxt("pmid_number_list.csv", pmid_number_list, delimiter =",", fmt="%.0f")
print("Reference PMIDs in the paper PMID:" + pmid + " were saved!")
Proxy環境によっては、requests.get()
にSSL認証を無視するためのverify=False
の設定が必要となる。
For文を使わずにpandaのDataFrameを使ってPMIDの抽出を行いたかったのだが、Beautiful Soupオブジェクトの構造解析が面倒くさかったので、パス。
Pythonのデフォルトのライブラリを使って保存するとファイルのopen/closeが面倒くさいので、検索結果を整数に変換してnumpyでCSVファイルとして保存した。
Rバージョン
library(rvest)
library(tidyverse)
pmid = 36960167 #your_target_PMID
print(paste("Getting reference PMIDs in the paper PMID:",pmid))
url = paste('https://pubmed.ncbi.nlm.nih.gov/', pmid, '/references/', sep="")
html <- read_html(url)
ref_link_text <- html %>% html_elements("a") %>% html_text(trim = TRUE)
ref_link <- html %>% html_elements("a") %>% html_attr("data-ga-action")
ref_df <- data.frame(ref_link_text, ref_link)
result_df <- ref_df %>% filter(ref_link_text == "PubMed") %>% select(ref_link)
write.table(result_df, "pmid_number_list_r.csv", row.names = F, col.names = F, sep = ",")
print(paste("Reference PMIDs in the paper PMID:",pmid, "were saved!"))
行名と列名を出力したくなかったので、write.csv
ではなくwrite.table
を使用している。
注意: 当然、PMIDがない文献は取ってこれないので、その場合はマニュアルで。