スクレイピング
Webスクレイピングとは、Webサイトの内容を機械的に取得してくるプログラムのことです。要はネットサーフィンを自動化するプログラミングです。
プログラミング初心者にとってスクレイピングは目に見えて結果がわかる最高の練習になります。しかし、スクレイピングは「サイトのタイトルを取得してくる」などから「自動でログインしてフォームに入力してボタンを押す」まで幅広く応用することができます。よって初めから難しい事をやろうとしては必ず挫折してしまいます。またpythonという言語だけでもスクレイピングをやろうとした時に何通りものやり方が存在します。
今回は、数あるpythonのスクレイピング方法の中から、初心者が簡単に出来るかつ今後ずっと使える最強の方法についてご紹介したいと思います。
練習
ここではスクレイピングの技術を
- サイトアクセス
- 要素抽出
という2つに分けて考えていきます。それぞれの技術は密接に関わり合っていますが、これらの考えがごちゃごちゃになるとわからなくなるので、基本的には別のことをやっていると思っていてください。
サイトアクセス
まずはサイトにアクセスしてその情報を取ってくるための一番簡単な方法についてご紹介します。ここではrequestsというPythonモジュールを使用します。これさえあれば、普段ブラウザからurlにアクセスする要領でソースコードからサイトのhtmlデータを取得することができます。
まずはライブラリをpipからインストールします。
pip install requests
実際にwebサイトのhtmlを取得してみましょう。
import requests
url = 'https://example.com/'
response = requests.get(url)
print(response.text)
これでサイトのhtmlを全てテキスト形式で取得することができました。
https://note.nkmk.me/python-requests-usage/
要素抽出
続いて要素抽出のやり方についてご紹介します。先ほどのrequestsモジュールを使えばサイトのhtmlデータは取得することができます。しかし例えばサイトのタイトルを取得しようとした時に文字列として取得したデータから検索するのではせっかくhtmlという構造をしている意味がありません。getTitle的な関数で一発取得できるのが望ましいです。
そこで今回はpyQueryというライブラリをご紹介します。これを使えばhtmlのクラスやタグ情報で簡単に要素を検索することができます。
同様にライブラリをインストールします。
pip install pyquery
続いて先ほどrequestsで取得してきたhtmlからpyQueryでデータを抽出していきます。
import requests
from pyquery import PyQuery as pq
url = 'https://example.com/'
response = requests.get(url)
// レスポンスを変数に格納する
html = response.text
// PyQueryのオブジェクトに変換する
query = pq(html, parser='html')
ここで作ったqueryオブジェクトのメソッドを呼び出すことで任意のデータの抽出ができます。
// クラス名から要素を抽出
print(query(".some-class").text())
// タグから要素を抽出
print(query("h1").text())
// aタグのlinkを抽出
print(query("a").attr('href'))
// 複数該当する場合にN番目の要素を抽出
print(query("p").eq(N))
https://www.google.com/amp/python.zombie-hunting-club.com/entry/2017/11/07/225538%3Famp%3D1
最後に
RequestsとPyQueryの2つのライブラリを使いこなせるようになれば、スクレイピングにおける大体のことは実現できます。まずは簡単な例でイメージを掴みながら練習していくのがいいと思います。
最後になりますが、スクレイピングは自動でサイトにアクセスする行為なので、for文の中にsleep処理を入れたりして相手のサイトに過度な負荷を与えないようにするための配慮が必要になります。robots.txtというファイルが用意されているサイトをスクレイピングする際にはその内容に従って行いましょう。スクレイピング禁止でないサイトであってもあまりにも負荷をかけるアクセスが行われると、同一IPアドレスからのアクセスが制限される可能性がありますのでご注意ください。