概要
Googleでキーワード検索をするとき、検索結果を一つずつ見ることがあると思います。
サイトをクリックしては、戻るボタンをクリック、またサイトをクリックしては戻るボタンの繰り返し。
検索結果のリンクを右クリックし、[新しいタブで開く]を選ぶことで、上位のいくつかのリンクを新しいタブで開き、後からタブ移動で読めれば作業が効率できると思います。
そこで、コマンドラインから検索を行うと、自動的にブラウザを開き、上位の検索結果を新しいタブに開くようにするスクリプトを記述していきます。
プログラムの概要は以下のものです。
・検索キーワードをコマンドライン引数から取得する。
・検索結果ページを取得する。
・各検索結果についてブラウザのタブを開く。
コードでは以下のものです。
・sys.argvからコマンドラインを読み込む。
・requestsモジュールを用いて検索結果のページを取得する。
・検索結果からリンクを見つける。
・webbrowser.open()関数を呼び出し、Webブラウザを開く。
それでは、ファイルエディタウィンドウを開いて、任意の名前.pyのファイルを作成・保存してください。
必要なモジュールのインストール
今回のプログラムで利用するモジュールは、requestsモジュール、sysモジュール、webbrowserモジュール、bs4モジュールになります。
sysモジュールとwebbrowserモジュールは、Pythonの組み込み関数のため、インストール不要です。
requestsモジュールとbs4モジュールは、Python付属ではないため、インストールが必要となります。
コマンドプロンプトもしくはターミナルなどでインストールを実施してください。
pip install requests pip install beautifulsoup4
これで、必要なモジュールの準備完了です。
コマンドライン引数を取得後、検索ページをリクエストする
コーディングを開始する前に、検索結果ページのURLを調べておく必要があるわけです。
Google検索のあとでブラウザのバーを見ると、検索結果ページのURLは、以下にようになっています。
https://www.google.com/search?q=検索キーワード
requestsモジュールを用いて、このページをダウンロードでき、BeautifulSoupを用いれば、HTMLから検索結果のリンクを見つけることができます。
最後に、webbrowserモジュールを用いてリンクをブラウザのタブで開くわけです。
import requests, sys, webbrowser, bs4 print("Loading...") res = requests.get("https://google.com/search?q=" + " ".join(sys.argv[1:])) res.raise_for_status()
プログラムの起動時のコマンドライン引数に検索キーワードを指定します。
引数はsys.argvに文字列のリストとして格納されるわけです。
これをjoin()で結合して、requests.get()にGoogle検索のURLとして渡し、ダウンロード結果をresに格納します。
結果を全て取得する
次に、ダウンロードしたHTMLからBeautifulSoupを用いて検索結果のリンクを抽出します。
しかし、そうするためにはどんなセレクタを指定すれば良いのか。
全ての<a>タグを検索すると、HTML中の不必要なリンクまでたくさん拾ってしまいます。
ここで、ブラウザの開発者ツールを用いて検索結果ページを調べ、目的のリンクだけを取り出すセレクタを見つけましょう。
Google検索をしたら、ブラウザの開発者ツールを開いてページ上のリンク要素を調査します。
ただ、要素がどんなに複雑であっても構いません。
全ての検索結果リンクがもつパターンを見つければいいわけです。
ですが、この<a>要素にはページ上の検索結果でない<a>要素と簡単に区別できるものはありません。
<a>要素の周辺を探して見ると、 <h3 class=”r”>という要素があります。
HTMLソースの他の部分を確認すると、rクラスは検索結果リンクにだけ使われています。
目的の<a>要素を示す印として使えればいいわけです。
ダウンロードしたHTMLテキストからBeautifulSoupオブジェクトを作り、”.r a”というセレクタを利用して、CSSクラスがrである要素の中にある全ての<a>要素を見つけます。
以下のようにコードを追加していきます。
soup = bs4.BeautifulSoup(res.text, "lxml") link_elems = soup.select(".r a")
検索結果をWebブラウザで開く
最後に、Webブラウザのタブに検索結果を開きます。
以下のようにコードを追加していきます。
num_open = min(5, len(link_elems)) for i in range(num_open) webbrowser.open("https://google.com" + link_elems[i].get("href"))
ここでは、検索結果の上位5件をwebbrowserモジュールを使って新しいタブに開きます。
しかし、検索結果が5件に満たないこともあり得ます。
soup.select()は、セレクタ”.r a”にマッチした全ての要素のリストを返すので、このリストの長さか5件か少ない方の数をタブとして開きます。
Pythonの組み込み関数min()は、渡された整数や浮動小数点数の中から最小値を返します。
min()を使うことで、リストの中のリンクが5件未満かどうかを調べて、タブで開くリンク数をnum_openという変数に格納するわけです。
そして、range(num_open)を呼び出してforループを回します。
<br/
繰り返しごとに、webbrowser.open()を使ってブラウザの新しいタブを開きます。
なお、検索結果の<a>要素のhref属性の値には、先頭のhttps://google.comの部分が含まれていないので、補っているわけです。
ここまでで、プログラムは完成です。
#! python3 # lucky.py - Google検索結果をいくつか開く import requests, sys, webbrowser from bs4 import BeautifulSoup # Googleページをダウンロード中にテキスト表示 print("Loading...") res = requests.get("https://google.com/search?q=" + " ".join(sys.argv[1:])) res.raise_for_status() # 上位の検索結果のリンクを取得する soup = BeautifulSoup(res.text, "lxml") link_elems = soup.select(".r a") # 各結果をブラウザのタブで開く num_open = min(10, len(link_elems)) for i in range(num_open): webbrowser.open("https://google.com" + link_elems[i].get("href"))
ファイルを実行して、試してみてください。
類似プログラムへの応用
ブラウザのタブを利用して、いくつかのリンクを開いておいてあとで読むのに便利なわけです。
このように一度に複数のリンクを自動的に開くプログラムは、以下のような用途にも利用できると思います。
・Amazonなどの通販サイトを検索して全ての商品ページを開く
・ある商品の全てのレビューへのリンクを開く
・FlickerやImgurなどの写真サイトを検索して、写真へのリンクを開く
などなど、他にも使い方でいろんなことに応用できると思います。
皆さんもWebスクレイピングを利用してみてください。
また、今後もプログラミングに取り組み続けていく中で、実務に利用できる学びを身につけていかなければなりません。
実務に活かす際に学習として利用していたPython本が以下のものになります。
・PythonによるWebスクレイピング(オライリー出版)
・増補改訂Pythonによるスクレイピング&機械学習 開発テクニック(クジラ飛行机)
・Pythonクローリング&スクレイピング – データ収集・解析のための実践開発ガイド
機械学習や分析の分野に興味があり、pythonを学びたいと思っている方は是非こちらもどうぞ↓