Beautifulsoupでアメリカ国立医学図書館検索サイトから論文タイトルと概要を抽出してみる。

この記事ではWindows10にインストールしたAnacondaでPython3.6、Beautifulsoup を使用しています。
※Ubuntuでも同様の環境を作って実行済みですのでPython3.6さえあれば同様のことができると思います。


#本記事でやったこと
・PubmedのホームページをAPIを使用してスクレイピングし、論文タイトル、アブストラクトを取得する。
・取得したタイトルをファイル名にし、テキストに概要を書き込み保存する。

#PubmedAPIを使用しスクレイピングより論文IDを取得
まずは以下のコードでスクレイピング用ライブラリのBeautifulsoupとWebサイトにアクセスするためのUrllibをインポートします。

```python:PubMed.py
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import urllib.request
```

PubmedAPIの仕組みはまず検索キーワードを下記ID検索用URL（以降baseURL)にセットすると論文IDが返ってきます。（呼び出す論文IDの最大数はデフォルトで20件です。パラメータを変えればもっと取ってこれます。）例えばcancerを検索すると下記のような結果が返ってきます。
URL:http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=cancer

IDを論文検索用URL(以降serchURL）にセットすると論文の内容を取得できます。（形式はXML）例えば下記のように結果が返ってきます。
https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=30172246

APIの仕様については下記をご参照ください。
https://www.ncbi.nlm.nih.gov/books/NBK25499/

ID検索用URL:http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=

論文検索用URL：https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=

```python:PubMed.py
keyword = "cancer"#検索キーワードとして今回はcancerを設定してみます。
baseURL = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term="
serchURL = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id="

```

ID検索用URLをセットしてIDをまとめて取ってくる処理と論文検索用URLをセットして論文を取ってくる処理を作成します。

```python:PubMed.py
#論文IDを取得する
def get_id(url):
    result = urllib.request.urlopen(url)
    return result

def get_summary(url):
    result = urllib.request.urlopen(url)
    return result"
```

メインの処理で、上記で定義したkeywordとbaseURLを足してIDを取ってきて取得したIDの分だけserchURLをインスタンス作成したBeautifulSopeにセットして論文を取得します。
取得した論文をBeautifulSoupで文字列指定で論文内容を取得し、テキスト形式で保存します。
今回指定する文字列は、title、abstractです。

```python:PubMed.py
def main():
    #ID取得用のURLを作成
    url_id = baseURL + keyword
    #ID取得用検索処理を実行 
    result = get_id(url_id)
    #Beautifulsopeで検索された結果を取り込む 
    soup = BeautifulSoup(result, 'html.parser')
    #idのタグで囲われているIDをすべて取得する。
    ids = soup.find_all("id")
    #取得したIDの個数分繰り返して論文を取得する。
    for id in ids:
        #検索用URLにIDをセットして論文を取得する。
        serch_url_id=serchURL + id.text + "&retmode=xml"
        sumresult = get_summary(serch_url_id)
        #Beautifulsopeで論文検索結果を取得
        summury_soup = BeautifulSoup(sumresult, 'html.parser')
        #titleとabstractの部分だけ取り出す。
        title = summury_soup.find("title")
        abstract = summury_soup.find("abstract")
        #たまにabstractがない奴がいるのでなくてもそのまま続ける。（多分論文の書き方が他と異なるもの）
        if abstract is None: continue
        #検索されて保存された内容を画面に出して確認する。
        print("ID："+id.text,"タイトル:",title.text)
        hedder = "ID："+id.text+"タイトル:"+title.text
        print("概要"+abstract.text)
        #UTF-8形式でテキストを保存する。
        f = open(title.text + '.txt','w',encoding='UTF-8')
        f.write(hedder)
        f.write(abstract.text)
        f.close()
if __name__ == "__main__":
    main()
```

実行結果は下記のようにうまく取得できました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284597/f95289fc-880f-42d7-2492-b68d6bcdc6ae.png)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/284597/45177c18-825b-3f66-0b25-82254a8e4331.png)

#終わりに
本記事では論文サイトからAPIを使用して論文を取得し、Beautifulsoupを用いてほしい情報だけ取り出してテキストで自端末に保存しました。
データは取得できるようになりましたので、保存した論文から単語を抽出して人工知能に学習させてみたいと思います。