シェルスクリプト × Web API

シェルスクリプトでWeb API的なものを使うメモ。
たぶんWeb API的なものをつかってデータをがーっともらってくる場合、シェルスクリプトが一番手軽です。
ほんの数行でかけます*1

たとえば、CiNii API(RDF)を通じてNCIDを使って資料タイトルを取り出す。

1件だけなら1行*2

curl "http://ci.nii.ac.jp/ncid/AA12227144.rdf"  | xpath '//rdf:RDF/rdf:Description/dc:title[1]/text()'

curlでデータ取得してxpathxml解析。

看護・保健科学研究

いいですね。

100件とか1000件とかある場合。while文で。

 AA12227144
 AA11354292
 AN00023058
 AN10507651

NCIDを別ファイル(ncid.txt)で用意しておいて、

while read id
do
	DATA=$(curl "http://ci.nii.ac.jp/ncid/${id}.rdf")
	TITLE=$(echo ${DATA} | xpath '//rdf:RDF/rdf:Description/dc:title[1]/text()')
	echo ${id}'\t'${TITLE} >> ncid_result.txt
done < ncid.txt

で回します。

AA12227144	看護・保健科学研究
AA11354292	千葉看護学会会誌 = Journal of Chiba Academy of Nursing Science
AN00023058	榮養學雑誌	
AN10507651	日本精神科看護学会誌

無事データとれてます。

他にもたとえば、dc:languageあたりもとりたいよ、という場合、

LANGUAGE=$(echo ${DATA} | xpath '//rdf:RDF/rdf:Description/dc:language/text()')

で追加していけばおっけーです。
NCIDのマッチングが失敗した場合、別途失敗したNCIDをncid_false.txtに書き込む処理をif文で組み込んでみます。

while read id
do
	DATA=$(curl "http://ci.nii.ac.jp/ncid/${id}.rdf")
	FLAG=$(echo ${DATA} | grep 'DOCTYPE html')
	if [ "${FLAG}" == "" ]
		then
			TITLE=$(echo ${DATA} | xpath '//rdf:RDF/rdf:Description/dc:title[1]/text()')
			LANGUAGE=$(echo ${DATA} | xpath '//rdf:RDF/rdf:Description/dc:language/text()')
			DATE=$(echo ${DATA} | xpath '//rdf:RDF/rdf:Description/dc:date/text()')
			OWNERCOUNT=$(echo ${DATA} | xpath '//rdf:RDF/rdf:Description/cinii:ownerCount/text()')
			echo ${id}'\t'${TITLE}'\t'${LANGUAGE}'\t'${DATE}'\t'${OWNERCOUNT} >> ncid_result.txt
		else
			echo ${id} >> ncid_false.txt
	fi
	sleep 1
done < ncid.txt
AA12227144	看護・保健科学研究	jpneng	2001	5
AA11354292	千葉看護学会会誌 = Journal of Chiba Academy of Nursing Science	jpn	1996	49
AN00023058	榮養學雑誌		jpn	1941	406
AN10507651	日本精神科看護学会誌		jpn	1990	82

実はCiNiiでRDF取得する場合、失敗したときの値はxmlで返ってきません。「html」で表示されるため失敗時の条件判断は「grep 'DOCTYPE html'」で判定、という感じにしてあります。

*1:とはいえ、利用の前にちゃんとWeb API的なものの利用規約のご確認をお願いします。

*2:1件だけデータ取得、なんてシチュエーションなさそうですが