演習・データ処理とスクレイピング
curlでデータを取得
curl http://code-genius.com/textbook/new-linux/linux_1001_data_convert.html > sample.html
titleを抽出
まずは、titleを抽出する方法について確認しましょう。
titleタグのある行を抽出
-E で正規表現を利用できます。
grep -E '<title>.+</title>' sample.html
titleタグ部分のみを抽出
oはonly-matchingオプションです。
grep -Eo '<title>.+</title>' sample.html
該当箇所をsedで変換
sedは行単位で編集を行うエディタ(ストリームエディタ)です。
sed -E 's|正規表現|変換後の文字列|'
とすることで、正規表現にマッチする箇所を変換後の文字列に変換することが可能です。
grep -Eo '<title>.+</title>' sample.html | sed -E 's|<title>.*</title>|abc|'
該当箇所をsedで変換(キャプチャを使用)
grep -Eo '<title>(.+)</title>' sample.html | sed -E 's|<title>(.*)</title>|\1|'
キャプチャ(後方参照)について
キャプチャとは、正規表現でマッチングした箇所の文字列を利用する機能です。キャプチャ箇所が複数ある場合、バックスラッシュのあとに何番目のキャプチャであるかを指定することが可能です。
aタグのリンク先を抽出
続いて、同じ要領でaタグのリンク先のみを抽出してみます。
aタグ部分のみを抽出
-PはPOSIXと呼ばれるPerl準拠の正規表現を利用できるオプションです。
grep -Po '<a.*?>' sample.html
href部分のみを抽出
抽出したaタグから、さらにリンク部分のみを取り出します。
grep -Po '<a.*?>' sample.html | grep -Po 'href=".*?"'
内部リンクを除外
httpから始まる部分のみを取り出すことで内部リンクを除外します。
grep -Po '<a.*?>' sample.html | grep -Po 'href="http.*?"'
リンク部分のみを抽出
sedを利用して、リンク先urlのみを取得します。
grep -Po '<a.*?>' sample.html | grep -Po 'href="http.*?"' | sed -E 's/href="(.*?)"/\1/'
重複を排除
sortしてからuniqコマンドで重複を排除します。
grep -Po '<a.*?>' sample.html | grep -Po 'href="http.*?"' | sed -E 's/href="(.*?)"/\1/' | sort | uniq
リンク先をファイルに保存
リダイレクトを利用してファイルに保存します。
grep -Po '<a.*?>' sample.html | grep -Po 'href="http.*?"' | sed -E 's/href="(.*?)"/\1/' | sort | uniq > links.txt
シェルスクリプトにする
上記の処理をシェルスクリプトにすると以下となります。
scraping.sh
if [ $# -eq 2 ] ; then
grep -Po '<a.*?>' $1 | grep -Po 'href="http.*?"' | sed -E 's/href="(.*?)"/\1/' | sort | uniq > $2
else
echo "usage: scraping.sh [url] [file]"
fi
各リンク先に対して同様の処理を行う(参考)
ここから先については解説のみとします。
pagesディレクトリに全ての外部リンク先をダウンロード
リンク先リストを利用して、全ての外部リンク先をダウンロードします。 q
mkdir pages
wget --random-wait -i links.txt -P ./pages/
pagesディレクトリ内のすべてのファイルについて、リンク先を抽出し、all_links.txtに追記する
グロブを利用することで全てのファイルを指定することができます。echoで確認できます。
echo ./pages/*
全てのファイルに対して先ほどの処理を行い、追記していきます。
grep -Po '<a.*?>' ./pages/* | grep -Po 'href="http.*?"' | sed -E 's/href="(.*?)"/\1/' | sort | uniq >> all_links.txt