スクレイピングで下付き文字も抽出したい
前書き
皆さんこんにちは、positroniumです。NISTのデータベース(https://cccbdb.nist.gov/pglist.asp)からC2v対称性を持つ分子だけを取り出したい季節ですね。
これは化学式によくありがちな、下付き文字や上付き文字をスクレイピングで扱うときの備忘録です。
結論
CSSのタグを理解している人であれば、下付き文字は<sub></sub>、上付き文字は<sup></sup>で指定されていることが分かると思います。要はbeautifulsoupなどでパースした後に、それらのタグをunwrapを使って削除してあげれば普通の文字と同じように扱うことができます。
やりたいこと
・NISTの点群のデータベースからC2v対称の分子だけを抽出して出力したい。
ソースコード
スクレイピングにはrequests、beautifulsoup4を使う。
import requests
from bs4 import BeautifulSoup
url = 'https://cccbdb.nist.gov/pglist.asp' # NISTのデータベース
request = requests.get(url)
soup = BeautifulSoup(request.text, "html_parser") #お好みのパーサーでok
次に、下付き文字(subscript)と上付き文字(superscript)のタグを除去する。
soup.find('sub').unwrap() #下付き文字の除去
soup.find('sup').unwrap() #上付き文字の除去
あとはpandasのdataframeに変換してエクセルに出力する。
import pandas as pd
df=pd.read_html(str(soup), header=0)[3] #NISTのサイトの中で点群の表は4番目
df.drop(df.loc[df['Point Group'] != 'C2v'].index, inplace=True) #C2v以外の分子は除く
df.to_excel('C2vList-NIST.xlsx', index=False, sheet_name='NIST')
#ここからはオプション
df.drop(columns=df.columns[3:], inplace=True) #後半の列を除去
df=df[~df['Name'].str.contains(' cation')] #カチオンの除去
df=df[~df['Name'].str.contains(' anion')] #アニオンの除去
df=df[~df['Name'].str.contains(' radical')] #ラジカルの除去
df=df[~df['Species'].str.contains('D')] #重水素の除去
df=df[~df['Species'].str.contains('\+')] #陽イオンの除去
df=df[~df['Species'].str.contains('\-')] #陰イオンの除去
これでこんな感じのエクセルファイルができるはず。
Point Group | Species | Name |
C2v | BH2 | boron dihydride |
C2v | BH3 | boron trihydride |
C2v | BH4 | borohydride |
C2v | CH2 | Methylene |
C2v | H2O | Water |
C2v | AlH2 | aluminum dihydride |
C2v | SiH2 | silicon dihydride |