Help us understand the problem. What is going on with this article?

AdWords APIでキーワードプランナーの検索ボリューム・CPC・競合性を取得する

※ 2020/08/03 Google Ads API版の記事を公開しましたので、よろしければどうぞ。
Google Ads APIでキーワードプランナーの検索ボリューム・CPC・競合性を取得する

はじめに

広告出稿の参考とするために、ターゲットキーワードとその関連キーワードの検索ボリューム・CPC・競合性を必要とする要件があり、GoogleキーワードプランナーのデータをAdwords APIを使って取得してみました。

AdWords APIの公式サイトはこちら
Google AdWords API

キーワードプランナーのデータを取得するまで

以下の流れで説明します。

  1. AdWords APIを利用するための準備
  2. Google Ads Client Libraries(Python)のインストール
  3. OAuth2 認証の設定
  4. APIで検索ボリューム・CPC・競合性の取得

1. AdWords APIを利用するための準備

AdWords APIは無料で利用できますが、利用にあたってはMCCアカウントと開発者トークンの申請/承認手続きが必要です。
公式サイトはこちら
最初のAPI呼び出しを実行する | AdWords API

具体的な申請方法などはこちらのサイトが参考になりました。
キーワードプランナーもログインせずに自由自在! AdWords API の申請と使い方

※開発者トークンの承認に1週間程度かかるので、そのまま待ちます。

2. Google Ads Client Libraries(Python)のインストール

※既にインストール済みであればこの項は不要です。

今回はGoogleが提供しているAPIクライアントライブラリ(Python)を使って取得してみます。
こちらを参考にインストールしておきます。
Google API Client Libraries > Python
具体的には下記コマンドで入ります(pip)

$ pip install googleads

※ 本記事で検証しているgoogleadsのバージョンは13.0.0です。

3. OAuth2 認証の設定

以下の流れで設定します。

a. Google Developers Console の認証情報のページでクライアントIDとクライアントシークレットを取得します。
下記ページの「OAuth2 認証を設定する」を参考に...
最初のAPI呼び出しを実行する | AdWords API

b. aで取得したクライアントIDとクライアントシークレットを使ってリフレッシュトークンを取得します。
下記ページの「OAuth2 リフレッシュトークンを取得してクライアントを設定する」と
最初のAPI呼び出しを実行する | AdWords API
こちらの「Step 2 - Setting up the client library」を参考に...
API access using own credentials (installed application flow) | GitHub

c. aで取得したクライアントIDとクライアントシークレットとbで取得したリフレッシュトークンをgoogleads.yamlに設定します。
下記ページの「OAuth2 リフレッシュトークンを取得してクライアントを設定する」を参考に...
最初のAPI呼び出しを実行する | AdWords API

4. APIで検索ボリューム・CPC・競合性の取得

以下がサンプルコードです(Python3)

get_keyword_ideas.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from googleads import adwords

PAGE_SIZE = 100

def get_ads_selector(request_type, requested_attribute_types, queries):
    ads_selector = {'ideaType': 'KEYWORD', 'requestType': request_type}
    ads_selector['requestedAttributeTypes'] = requested_attribute_types
    ads_selector['paging'] = {'startIndex': '0', 'numberResults': str(PAGE_SIZE)}
    ads_selector['searchParameters'] = [{
        'xsi_type': 'RelatedToQuerySearchParameter',
        'queries': queries
    }]
    ads_selector['searchParameters'].append({
        'xsi_type': 'LanguageSearchParameter',
        'languages': [{'id': '1005'}]
    })
    ads_selector['searchParameters'].append({
        'xsi_type': 'NetworkSearchParameter',
        'networkSetting': {
            'targetGoogleSearch': True,
            'targetSearchNetwork': False,
            'targetContentNetwork': False,
            'targetPartnerSearchNetwork': False
        }
    })
    return ads_selector

def get_ads_results(ads_selector):
    ads_list = []
    page = {}
    try:
        page = targeting_idea_service.get(ads_selector)
    except Exception as e:
        print(e)

    if 'entries' in page:
        for result in page['entries']:
            attributes = {}
            for attribute in result['data']:
                attributes[attribute['key']] = getattr(attribute['value'], 'value', '0')
            if isinstance(attributes['AVERAGE_CPC'], str):
                average_cpc = int(attributes['AVERAGE_CPC'])
            elif attributes['AVERAGE_CPC'] is None:
                average_cpc = 0
            else:
                average_cpc = int(attributes['AVERAGE_CPC']['microAmount'])//1000000
            if attributes['COMPETITION'] is None:
                competition = 0.0
            else:
                competition = attributes['COMPETITION']
            if attributes['SEARCH_VOLUME'] is not None and int(attributes['SEARCH_VOLUME']) > 0:
                record = {
                    'keyword': attributes['KEYWORD_TEXT'],
                    'search_volume': attributes['SEARCH_VOLUME'],
                    'average_cpc': average_cpc,
                    'competition': competition
                }
                ads_list.append(record)
    else:
        print('Adwords API: No related keywords were found.')
    return ads_list

def main(target_keywords):
    ads_selector = get_ads_selector('IDEAS', ['KEYWORD_TEXT', 'SEARCH_VOLUME', 'AVERAGE_CPC', 'COMPETITION'], target_keywords)
    ads_list = get_ads_results(ads_selector)

    targetidea_list = []
    cnt = 0
    for row in ads_list:
        cnt += 1
        str_search_volume = str(int(row['search_volume']))
        str_average_cpc   = str(int(row['average_cpc']))
        float_competition = float(row['competition'])
        str_competition = '%.3f' % float_competition
        if float_competition >= 0.67:
            str_competition_rank = '高'
        elif float_competition >= 0.43:
            str_competition_rank = '中'
        else:
            str_competition_rank = '低'
        record = {
            'no': cnt,
            'keyword': row['keyword'],
            'search_volume': str_search_volume,
            'average_cpc': str_average_cpc,
            'competition': str_competition,
            'competition_rank': str_competition_rank
        }
        targetidea_list.append(record)

    print(targetidea_list)

if __name__ == '__main__':
    ads_client = adwords.AdWordsClient.LoadFromStorage()
    targeting_idea_service = ads_client.GetService('TargetingIdeaService', version='v201806')

    target_keywords = ['ダイエット']
    main(target_keywords)

※ ここでは「ダイエット」というキーワードでキーワードプランナーのデータを取得しています。
googleads.yamlはホームディレクトリに配置している想定です。場所を指定する場合はadwords.AdWordsClient.LoadFromStorage()の引数にパスを指定します。
※ APIでは、AVERAGE_CPC(平均CPC)は単位がmicroのため、1000000で割っています。
※ APIでは、COMPETITION(競合性)は小数点表記のため、キーワードプランナーの表示に合わせてランク文字列(高|中|低)も生成しています。

APIのバージョンアップについて

本記事で検証しているTargetingIdeaServiceのバージョンはv201806です。
AdWords APIはリリーステンポが速く、本番運用で利用するためには数ヶ月以内に新しいバージョンに移行する必要があります。
詳しくはこちら
サポート終了と廃止のスケジュール | AdWords API

※最新のバージョンを使用するためには、クライアントライブラリ(googleads)も同時にバージョンアップする必要があります。

参考にしたサイト

最初のAPI呼び出しを実行する | AdWords API
キーワードプランナーもログインせずに自由自在! AdWords API の申請と使い方
googleads/googleads-python-lib | GitHub
PythonでGoogleAdwordsAPIを使って検索ボリュームを出してみた

おわりに

Google API群の中でもAdWords APIは比較的使うまでの手続きが複雑でかなり手間取りました...
特に実装しようとしているツールの仕様ドキュメントを提出するのが億劫になりますが、
ここを突破すればデータの取得自体は非常に簡単で、かつデータの価値も高そうなのでいろいろと試してみたいと思います。

zak_y
詳しいことはわからないが、動くと楽しい
valuesccg
「インターネット行動ログ分析サービス」など、デジタルマーケティング領域での新たな価値創造を通し、各企業の成長支援を行っています。エンジニア募集中。
https://www.valuesccg.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした