GoogleのサジェストAPIとは?Pythonのrequestsを使って取得する方法

Googleサジェスト機能

Googleの検索画面で何かキーワードを入力する際に、下の方に予測結果が出てきます。

例: キーワードとして「ジブリ」と入力

候補:ジブリパーク、ジブリ美術館 など

この候補を利用して効率よく検索機能を使用していることは多いのではないでしょうか?
実は、この結果は簡単に取得することが可能です。

まずはものは試しで以下のURLをブラウザに入力してみてください。
https://www.google.com/complete/search?ie=utf-8&oe=utf-8&q=hello&output=toolbar

q=hellohelloを変更すると、そのキーワードに応じた結果が取得できます。

# 「パンダ」をキーワードにした場合
<toplevel>
<CompleteSuggestion>
<suggestion data="パンダ"/>
</CompleteSuggestion>
<CompleteSuggestion>
<suggestion data="パンダイラスト"/>
</CompleteSuggestion>
...
</toplevel>

ここで表示されている <suggestion data="XXX"> の XXX に該当する部分が検索欄に表示されています。

以降では、この機能を利用して検索結果をPythonで取得する方法についてまとめます。

PythonでGoogleサジェストの結果を取得

responceの取得

ファイル名はなんでも良いですが、ひとまず「getautocomplete.py」を作成し、以下を記述してください。

import requests

class GetAutoComplete:
    """Google検索における予測検索結果を取得する
    """

    def __init__(self):
        self.url = "http://www.google.com/complete/search"
        self.output = "toolbar"
  • self.url:基本的に変わらない部分
  • self.output:XML形式で取得することを示す

これだけではただの骨組みで何も面白くないですね。

作成したクラスにひとつメソッドを追加してみましょう。

    def get_responce(self, query):
        """Google サジェストAPIのレスポンスを取得する。

        Args:
            query (str): 検索時のキーワード

        Returns:
            str: レスポンス結果
        """

        responce = requests.get(
            self.url,
            params={
                "q": query, 
                "ie": "utf-8",
                "oe": "utf-8",
                "output": self.output
                },
        )
        return responce
  • requests:HTTPライブラリ
    • requests.get:GETリクエスト
    • params:パラメータを指定(URLで「&」で結合している部分に該当)
  • 戻り値のresponceにはxml形式のデータ(ブラウザ上で表示されていたデータ)が格納される。

ここまでで、ブラウザで表示したデータを取得することはできました。XML形式のままでも良いのですが、不要な部分を省いて「検索候補のみを抽出」する処理を考えてみましょう。

XMLから必要なデータを抽出

何かとPythonには既存の便利なライブラリが用意されているので、今回もそれにあやかります。

先ほど作成したソースコードの冒頭に

import xml.etree.ElementTree as ET

を追加してください。

そして、先ほど取得したXMLのデータから検索結果のみを取得してリスト(配列)に格納するメソッドを追加してください。

    def responce_to_xml(self, responce):
        """xml形式から候補結果を抽出する

        Args:
            responce (str): xml形式のレスポンス

        Returns:
            list: 候補のみを取得したリスト
        """
        res_xml: ET.Element = ET.fromstring(responce.text)
        keyword_nodes = res_xml.findall("CompleteSuggestion/suggestion")
        suggest_keywords = list(map(lambda x: x.attrib["data"], keyword_nodes))
        return suggest_keywords
  • 10行目:文字列データからXML形式にパース
  • 11行目:検索条件に該当する場所を抽出(data="パンダ"を抽出)
  • 12行目:data部分を取得し、リストに格納する

これで必要な機能は完成しました。

ソースコード

最後に、ここまでの処理をまとめたソースコードを載せます。

import requests
import xml.etree.ElementTree as ET

class GetAutoComplete:
    """Google検索における予測検索結果を取得する

    Note:
        参考URL:
            https://so-zou.jp/web-app/tech/web-api/google/suggest/

    Todo: 
        * 検索結果がキーワードと同じ場合の処理(重複している場合)
        * レスポンス取得結果の扱い( `get_responce` の戻り値)について要検討

    """

    def __init__(self):
        self.url = "http://www.google.com/complete/search"
        self.output = "toolbar"

    def get_responce(self, query):
        """Google サジェストAPIのレスポンスを取得する。

        Args:
            query (str): 検索時のキーワード

        Returns:
            str: レスポンス結果
        """

        responce = requests.get(
            self.url,
            params={
                "q": query, 
                "ie": "utf-8",
                "oe": "utf-8",
                "output": self.output
                },
        )
        return responce

    def responce_to_xml(self, responce):
        """xml形式から候補結果を抽出する

        Args:
            responce (str): xml形式のレスポンス

        Returns:
            list: 候補のみを取得したリスト
        """
        res_xml: ET.Element = ET.fromstring(responce.text)
        keyword_nodes = res_xml.findall("CompleteSuggestion/suggestion")
        suggest_keywords = list(map(lambda x: x.attrib["data"], keyword_nodes))
        return suggest_keywords

if __name__ == '__main__':
    query = "python"
    gs = GetAutoComplete()
    responce = gs.get_responce(query + " ")
    suggest_keywords = gs.responce_to_xml(responce)
    print(suggest_keywords)

query = "python"の部分に検索したいキーワードを指定することで、Googleサジェスト機能に表示される検索候補の上位10項目が格納されたリストが作成されます。

コメント