お久しぶりになりました。
相変わらず、ちょこまかといろいろやっております。
最近、UniProtからデータを引っこ抜くことが多いのですが、
UniProtからxmlでデータを取得した後、pythonのlxmlで目的の項目を抜き出す際に
ちょっとしたトラップがありました。
その際に詰まったことがありましたので、メモ代わりに記事にします。
- UniProtとは
- UniProt APIを用いてデータ取得
- xmlを用いてparseできない????
- uniprotのxml parseには名前空間の指定が必要
- 名前空間を指定してxmlをparseする
UniProtとは
UniProtとは The Universal Protein Resourceのことで、
タンパク質の配列とその機能についての情報が網羅的に収載されている、
巨大なデータベースです。
UniProt APIを用いてデータ取得
Pubmedと同様にUniProtにもAPIがあり、
クエリを投げることによって自動的に情報を取得できます。
今回はHPのexampleにもある以下のクエリを例に取りたいと思います。
https://www.uniprot.org/uniprot/P12345.xml
詳細は上のクエリを開いていただければ分かりますが、
FABP-1というタンパク質の情報のxmlデータとなります。
xmlを用いてparseできない????
xmlならpythonなどを用いて、ササッと目的の項目を取得となります。
試しに以下のコードを書いて、タンパク質のrecommendedNameを取得しようとすると、
なぜか空白のデータが帰ってきます。
#うまく行かない例です import requests from lxml import etree query = 'https://www.uniprot.org/uniprot/P12345.xml' response = requests.get(query) root = etree.fromstring(response.content) fullname = root.findall('.//recommendedName/fullName') fullname #[]空のデータが返ってきます。
uniprotのxml parseには名前空間の指定が必要
xmlのパースに余りなれていないため、
書き方が悪いのか??と思ってかなり頑張ったのですが、
いくらやっても空のリストしか返ってきませんでした。
色々と調べた結果、xmlには名前空間(namespace)が指定されている場合、
それをちゃんと指定してあげなければいけないようです。
xmlに名前空間が指定されているかどうかは、以下の部分を見ればわかります。
xmlns = のところに名前空間が書かれていますね。
また、lxmlのnsmapでも確認できます。
print(root.nsmap) #{None: 'http://uniprot.org/uniprot', #'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
名前空間を指定してxmlをparseする
さて、それでは名前空間を指定してparseしてみます。
xpathで行く場合は、
root.xpath('ここにxpathを指定', namespces = root.nsmap)
lxmlのfindを使う場合は、
root.find('ここにxpathを指定', root.nsmap)
です。
が、今回の様にnamespaceにNoneが入っている場合は、
lxmlのxpathはうまく行きませんので、
findの方を使いましょう。
import requests from lxml import etree query = 'https://www.uniprot.org/uniprot/P12345.xml' response = requests.get(query) root = etree.fromstring(response.content) fullname = root.find('.//recommendedName/fullName',root.nsmap) print(fullname.text) #'Aspartate aminotransferase, mitochondrial'
上手くparseできましたね。
今回は以上になります。