PythonでGoogle検索スクレイピング、BeautifulSoupの使い方

 


画像の拡大

この記事では、PythonでGoogle検索結果をスクレイピングして、特定のサイトの検索キーワードに対する検索順位の抽出を行います。また、カンタンにスクレイピングを可能とするBeautifulSoupの使い方を説明します。PythonでWebスクレイピングをはじめたい方はぜひご参考になさってみてください。

▼ Pythonを使うのがはじめてという方は、こちらの書籍で基本的な使い方を学んでおくと良いでしょう。

▼ こちらの本は、Beautiful Soup4のクローリングをはじめ、pandasやmatplot、OpenPyXLなどを使ってデータ解析までを解説したスクレイピングの書籍となります。分かりやすくてオススメです!

スクレイピングとは

スクレイピングとは、英語のscrapingで「こすること」「削ること」の意味があります。Webでスクレイピングといった場合は、Webサイトの状態をかき集め(クローリング)、その中から必要なデータを抽出(スクレイピング)することになります。

Pythonでは、Webスクレイピングをカンタンに行えるようにしてくれるツールのひとつに、BeautifulSoupというライブラリがあります。BeautifulSoupを使ってWebスクレイピングを行うには、次の流れで作業していきます。

  1. urllibでスクレイピングしたいサイトのHTMLをダウンロードする
  2. BeautifulsoupでHTMLをパースしてオブジェクト化する
  3. Beautifulsoupで目的のデータを抽出する

それでは、さっそくBeautifulSoupをインストールし、BeautifulSoupのカンタンな使い方を説明していきます。

BeautifulSoupのインストール

まずは、BeautifulSoupをpipでインストールします。この記事では、Python3を使用しますのでpip3でインストールしました。BeautifulSoup最新版はbeautifulsoup4ですので、次のようにしてインストールします。

$ pip3 install beautifulsoup4

サイトタイトルを抽出してみよう

まずは大雑把なイメージをつかむために、適当なサイトをスクレイピングして、titleタグの文字を抽出してみましょう。

import urllib.request
from bs4 import BeautifulSoup


url = "https://101010.fun/posts/world-ios-android-share-2021.html"
req = urllib.request.Request(url)

with urllib.request.urlopen(req) as res:
    html = res.read()
    soup = BeautifulSoup(html, 'html.parser')
    title = soup.find('title').get_text()
    print(title)

BeautifulSoupを使うことで、このように驚くほどカンタンにtitleタグの文字を抽出できました。それでは、BeautifulSoupの使い方をもう少し詳しくみていきましょう。

BeautifulSoupの使い方

BeautifulSoupの使い方を説明します。

HTMLをオブジェクト化(パースパースツリー)

HTMLデータをダウンロードしたら、HTMLテキストをsoup = BeautifulSoup(html, 'html.parser')でパースパースツリーを作成しオブジェクト化します。

特定のタグを見つける

たとえば、パースパースツリーの中からaタグを検索したい場合は、soup.find_all('a')のようにします。もし、aタグが見つかれば、返り値としてその結果が配列で返されます。

次のプログラムは、Google検索結果のようにaタグの子要素にh3タグが入っている例です。

for a_tag in soup.find_all('a'):
    h3_tag = a_tag.select("h3")

    if len(h3_tag) > 0:
        ...

CSSクラスでアクセスする

BeautifulSoupでは、次のようにCSSクラスを指定して検索することも可能です。

soup.find_all("a", class_="hoge")

パースパースツリーを変更する

BeautifulSoupでは、パースパースツリーの変更もできます。

soup = BeautifulSoup("<a>Hoge</a>")
soup.a.append("Fuga")

aタグのテキストはHogeFugaとなります。

▼ BeautifulSoupについてより詳しく知りたい方は、こちらのドキュメントをご参考になさってみてください。

▼ また、pandasやOpenPyXL、twintなどを使ったスクレイピング関連の記事も書いています。あわせてご参考になさってみてください。

Google検索結果をスクレイピング

それでは、BeautifulSoupを使ってGoogle検索結果をスクレイピングしてみましょう。次の手順でプログラムを組んで、検索キーワードに対する指定サイトの検索順位を抽出してみます。

  1. urllibで検索結果のHTMLをダウンロード
  2. HTMLをBeautifulSoupでパースツリー化
  3. 特定のURLが検索結果に含まれているかチェックしり
  4. 検索結果に見つからなければ最大5ページまで手順を繰り返す

以上の仕様で作ってみたプログラムがこちらとなります。

Pythonプログラム

# Created by Toshihiko Arai.
# https://101010.fun/programming/python-beautifulsoup-googlerank.html

import urllib.request
from urllib.parse import quote
from bs4 import BeautifulSoup
import time

keyword = 'ios android シェア'
target = 'https://101010.fun/posts/world-ios-android-share-part1.html'
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36"

def get_search_html(keyword, page):
    start = "&start=" + str(page * 10) # 次ページstart=10
    url = 'https://www.google.com/search?q=' + quote(keyword) + start 
    
    headers = {'User-Agent': user_agent}
    req = urllib.request.Request(url, headers=headers)

    with urllib.request.urlopen(req) as res:
        body = res.read()
        return body


def get_page_rank(soup, page):
    res_rank = 1

    for a_tag in soup.find_all('a'):
        h3_tag = a_tag.select("h3")

        if len(h3_tag) > 0:
            if a_tag.get('href').startswith(target) == True:
                # print(h3_tag[0].get_text())
                # print(a_tag.get('href'))
                return res_rank + page * 10

            res_rank += 1
    return -1

rank = -1
max_page = 5

for page in range(max_page):
    html = get_search_html(keyword, page)
    soup = BeautifulSoup(html, 'html.parser')

    title_text = soup.find('title').get_text()
    print(title_text)
    rank = get_page_rank(soup, page)

    page += 1
    if rank != -1:
        break

    time.sleep(3) # アクセス制限対策
    
if rank != -1:
    print("順位: {}位".format(rank))
else:
    print("見つかりませんでした")

もし、検索結果に対象ページが含まれていれば、次のようなに検索順位が標準出力されるでしょう。

ios android シェア - Google 検索
順位: 2位

プログラム中の検索キーワードや対象ページのURLを変更して、いろいろ試してみてください。このプログラムをさらに改造すれば、Rank TrackerのうようなSEOツールが作れるでしょう。そのためには、検索キーワードを別ファイルで管理したり、実行結果をエクセルへ書き出したりすれば良いかと思います。ぜひご活用ください。

記事に関するご質問などがあれば、
@tosisico または お問い合わせ までご連絡ください。
スクレイピングにオススメの書籍

▼ Beautiful Soup4を使ったWebクローリングをはじめ、表データをpandasやOpenPyXL、matplotでデータ解析、グラフ表示などのスクレイピングのやり方が分かりやすく説明されています。図解が多いのでPython初心者の方でも読み進められる内容となってます。

関連記事