PubMedのRSSを使って、論文チェックから業績管理まで

ZoteroにRSSフィードを登録 文献検索

PubMedのRSSを使うと、思った以上にいろんなことができる。最新論文をRSSリーダーでチェックするのはもちろん、Zoteroにそのまま文献登録したり、自分の業績管理まで応用できたりする。うまく活用すれば、情報収集も管理もぐっとラクになる。


スポンサーリンク

1. RSSとは?

RSS(Really Simple Syndication)は、ウェブサイトの更新情報を自動で届けてくれる仕組み。ブログなんかで新着記事をフォローするのによく使われる、どちらかといえば一昔前に流行ったサービス。

PubMedの検索結果にもこのRSSが使えるので、「こんな条件の新着論文が出たら教えてね」という設定ができる。これを利用すると、いちいち検索しなくても、自動で情報が届くようになるのは本当に便利。


2. PubMedでRSSフィードを作る方法

たとえば、「最近30日間に発表された睡眠に関する論文」が気になるときは、以下のような設定ができる。

手順:

  1. PubMedにアクセス:https://pubmed.ncbi.nlm.nih.gov/
  2. 検索ボックスに以下を入力:sleep[MeSH Terms] AND ("last 30 days"[PDat])
  3. 検索結果ページの右上にある「Create RSS」をクリック
  4. フィードの名前をつけて「Create RSS」を押す
  5. 表示されたRSSフィードのURLをコピー

これで、新しい睡眠関連論文が出るたびに教えてくれるフィードが完成。

PubMedでRSSフィードを作成

3. RSSリーダーで新着論文を読む

RSSフィードは、専用のリーダーに登録して読むととても快適。PubMedの検索結果をニュース感覚でチェックできるようになる。

おすすめのRSSリーダー:

Feedlyに登録する場合:

  1. Feedlyにログイン(無料プランでOK)
  2. 左側の「+」マークからRSSフィードのURLを入力
  3. フォルダーに追加して登録完了
FeedlyでRSSフィードを登録

Inoreaderも同様に、URLを貼り付けるだけで登録できる。


4. ZoteroでRSSを使って文献を自動登録

Zoteroは文献管理ツールとして定番だけど、実はRSSフィードも扱える。PubMedの新着論文をZoteroに自動で流し込むような使い方ができる。

手順:

  1. Zoteroを開く
  2. メニューバーの「ファイル」→「新しいライブラリ」→「新しいフィード」→「URLから」
  3. PubMedで作ったRSSフィードのURLを入力
ZoteroにRSSフィードを登録

これで、新しい論文が自動でZoteroの「フィード」上に表示されるようになる。登録された論文データをクリックすると、右からむに「”マイ・ライブラリ”に追加する」というボタンが現れるので、そこから自身のライブラリに登録可能。(登録しないと、一定期間で自動的にフィードから消えていく。)


5. Notionで業績データベースを自動更新(GASで実現)

ちょっと上級者向けにはなるけど、Google Apps Script(GASの公式サイトはこちら)を使えば、PubMedのRSSから情報を取り出してNotionに自動で記録することもできる。

準備するもの

  • Notionアカウント
  • 以下のプロパティを持ったNotionデータベースのID
    (ここでは仮に NOTION_DBID
    • Title
    • URL
    • Date
    • Description
    • Authors
    • Journal
    • Volume
    • Issue
    • Pages
    • Year
    • DOI
    • PMID
    • Tag *自分の業績である”My paper”というタグづけをする
  • Notionデータベースに接続したインテグレーショントークン
    (ここでは仮に NOTION_INTEGRATION_TOKEN
  • 自身の業績をピックアップできる検索式で作成したPubMedのRSSフィード
    (ここでは仮に PubMed_RSSFeed
    • 例:(Author Name[Author]) AND (Institution Name[Affiliations]) のように検索式を工夫すると、自分の論文だけを拾える可能性がある

GASのサンプルコード

const NOTION_TOKEN = 'NOTION_INTEGRATION_TOKEN';
const NOTION_DATABASE_ID = 'NOTION_DBID';
const RSS_FEED_URL = 'PubMed_RSSFeed';
function fetchPubmedToNotion() {
  const xml = UrlFetchApp.fetch(RSS_FEED_URL).getContentText();
  const document = XmlService.parse(xml);
  const root = document.getRootElement();
  const channel = root.getChild('channel');
  const items = channel.getChildren('item');

  const dcNS = XmlService.getNamespace('dc', 'http://purl.org/dc/elements/1.1/');
  const contentNS = XmlService.getNamespace('content', 'http://purl.org/rss/1.0/modules/content/');

  items.forEach(item => {
    const title = item.getChildText('title');
    const link = item.getChildText('link');
    const description = item.getChildText('description');
    const pubDateStr = item.getChildText('pubDate');
    const pubDate = new Date(pubDateStr);

    const contentEncoded = item.getChild('encoded', contentNS)?.getText() || '';
    const creators = item.getChildren('creator', dcNS).map(el => el.getText());
    const authors = creators.join(', ');
    const journal = item.getChildText('source', dcNS);
    const yearMatch = contentEncoded.match(/\b(\d{4})\b/);
    const year = yearMatch ? yearMatch[1] : '';

    const volIssuePagesMatch = contentEncoded.match(/(\d+)\s*(?:\((\d+)\))?:([\d\-]+)/);
    const volume = volIssuePagesMatch ? volIssuePagesMatch[1] : '';
    const issue = volIssuePagesMatch ? volIssuePagesMatch[2] : '';
    const pages = volIssuePagesMatch ? volIssuePagesMatch[3] : '';

    const doiMatch = contentEncoded.match(/doi:\s*([\w./-]+)/i);
    const doi = doiMatch ? doiMatch[1] : '';

    const pmidMatch = contentEncoded.match(/PMID:<a.*?>(\d+)<\/a>/);
    const pmid = pmidMatch ? pmidMatch[1] : '';

    // 重複チェック:既存のPMIDがあるか確認
    if (pmid && checkDuplicatePMID(pmid)) {
      Logger.log(`Duplicate found: PMID ${pmid} already exists. Skipping...`);
      return;
    }

    const metadata = {
      authors, journal, volume, issue, pages, year, doi, pmid
    };

    postToNotion(title, link, pubDate, description, metadata);
  });
}

function checkDuplicatePMID(pmid) {
  const queryUrl = `https://api.notion.com/v1/databases/${NOTION_DATABASE_ID}/query`;

  const payload = {
    filter: {
      property: 'PMID',
      rich_text: {
        equals: pmid
      }
    }
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      'Authorization': `Bearer ${NOTION_TOKEN}`,
      'Notion-Version': '2022-06-28'
    },
    payload: JSON.stringify(payload)
  };

  const response = UrlFetchApp.fetch(queryUrl, options);
  const data = JSON.parse(response.getContentText());
  return data.results && data.results.length > 0;
}

function postToNotion(title, link, pubDate, description, metadata) {
  const url = 'https://api.notion.com/v1/pages';

  const payload = {
    parent: { database_id: NOTION_DATABASE_ID },
    properties: {
      'Title': {
        title: [{ text: { content: title } }]
      },
      'URL': {
        url: link
      },
      'Date': {
        date: { start: pubDate.toISOString() }
      },
      'Description': {
        rich_text: [{ text: { content: description } }]
      },
      'Authors': {
        rich_text: [{ text: { content: metadata.authors } }]
      },
      'Journal': {
        rich_text: [{ text: { content: metadata.journal } }]
      },
      'Volume': {
        number: metadata.volume ? parseInt(metadata.volume) : null
      },
      'Issue': {
        number: metadata.issue ? parseInt(metadata.issue) : null
      },
      'Pages': {
        rich_text: [{ text: { content: metadata.pages } }]
      },
      'Year': {
        number: metadata.year ? parseInt(metadata.year) : null
      },
      'DOI': {
        rich_text: [{ text: { content: metadata.doi } }]
      },
      'PMID': {
        rich_text: [{ text: { content: metadata.pmid } }]
      },
      'Tag': {
         select: { name: 'My Paper' }
      }
    }
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      'Authorization': `Bearer ${NOTION_TOKEN}`,
      'Notion-Version': '2022-06-28'
    },
    payload: JSON.stringify(payload)
  };

  UrlFetchApp.fetch(url, options);
}

このスクリプトを使って、定期的に実行するスケジュールを設定すれば、PubMedに新しく追加された論文情報が自動でNotionに記録されていく。研究者にとっては、ちょっとした業績管理システムの完成。


まとめ

PubMedのRSSは、論文チェックの効率化だけじゃなく、文献管理や業績記録の自動化にも使える優れもの。

  • RSSリーダーで最新論文をチェック
  • Zoteroに登録して文献管理を簡単に
  • GAS+Notionで自動的に業績管理

情報収集をもっとスマートにしたい人にとって、RSSはとても頼れる仕組み。ちょっと設定するだけで、日々の作業がぐっとラクになる。

タイトルとURLをコピーしました