はじめに
SearchConsoleだと1000件までしかデータがとれないけど、API経由なら5000件まで取れるそうなので、RubyからAPI経由で取得しようとしました。公式のRubyでのサンプルがなかったので、メモしておきます。
参考
こちらをベースに作りました。とても助かりました。
Rails サーバから Google Analytics API で情報を取得する手順 ーー google-api-ruby-client, OAuth
アカウント準備
- Google Developers Console にアクセス
- プロジェクトを作成
- APIと認証 > 認証情報 > 認証情報を追加 > サービスアカウント
P12を指定。パスフレーズが表示されて証明書ファイルがダウンロードされます。 - APIを有効にする
インストール
OAuthでAPI接続するためのライブラリをインストール
gem 'google-api-client'
gem 'signet'
実装
require 'google/api_client'
# サーチコンソールからデータを取得するクラス
class SearchConsoleTool
def initialize(application_name: "SearchConsoleTool", application_version: '1.0.0')
@client = Google::APIClient.new(
application_name: application_name,
application_version: application_version
)
end
# 秘密鍵の認証
# @param keyfile Google認証情報のP12ファイルのパス
# @param passphrase Googleサービスアカウントのパスワード
def signing_key(keyfile, passphrase)
return if @signing_key
@signing_key = Google::APIClient::KeyUtils.load_from_pkcs12(keyfile, passphrase)
end
# OAuth認証
# @param mail_address Googleサービスアカウントのメールアドレス
# @param keyfile Google認証情報のP12ファイルのパス
# @param passphrase Googleサービスアカウントのパスワード
def authorize!(mail_address, keyfile, passphrase)
@client.authorization = Signet::OAuth2::Client.new(
token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
audience: 'https://accounts.google.com/o/oauth2/token',
scope: 'https://www.googleapis.com/auth/webmasters.readonly',
issuer: mail_address,
signing_key: signing_key(keyfile,passphrase)
)
@client.authorization.fetch_access_token!
end
# SearchConsole APIの取得
def api
@api ||= @client.discovered_api('webmasters', 'v3')
end
# クエリ実行
# @param site_url 対象サイトのURL
# @param start_date 集計開始日
# @param end_date 集計終了日
# @return [Array] URLごとのデータ {"keys": URL, "clicks": クリック数, "impressions": 表示数, "position": 平均掲載順位}
def query(site_url, start_date= Date.today, end_date= Date.today)
result = @client.execute(
api_method: api.searchanalytics.query,
parameters: {
"siteUrl": site_url,
},
body_object:{
"startDate": start_date.strftime("%Y-%m-%d"),
"endDate": end_date.strftime("%Y-%m-%d"),
"dimensions":[
"page"
],
"rowLimit": 5000
}
)
return JSON.parse(result.response.body)["rows"]
end
end
5000件とれるのはいいけど、page制御がサポートされていないようで、その先はとれないorz。
全URLに対して調べたい場合は、URLのリストを作って1件ずつ調べるしかないかな。。ちなみに1日のAPI使用制限は1,000,000回
実行
site_url = "https://your-site"
mail_address = 'your-address@developer.gserviceaccount.com'
keyfile = "your-file.p12"
passphrase = 'notasecret'
tool = SearchConsoleTool.new
tool.authorize!(mail_address,keyfile,passphrase)
result = tool.query(site_url, Date.today-5, Date.today-5)
JSONで結果が出力されます
クエリパラメータについて
queryメソッド内でしようしているbody_objectに設定できるパラメータについて。
SearchConsoleで行うようなフィルターが設定できます。
公式ドキュメント
パラメータ名 | データ型 | 説明 |
---|---|---|
startDate | String | 開始日時。"YYYY-mm-ddの形式" |
endDate | String | 終了日時。"YYYY-mm-ddの形式" |
dimensions | Array | 検索範囲。"country"(国),"device"(デバイス),"page"(ページ),"query"(クエリ)を指定する |
searchType | String | 検索種類。"web","image","video"から指定。デフォルトは"web" |
dimensionFilterGroups | Array | filtersとgroupTypeを掛け合わせる。filtersには検索条件を入れ、groupTypeは"and"を入れて結合条件にする |
dimensionFilterGroups[].groupType | String | "and"を指定するのみ |
dimensionFilterGroups[].filters[] | Array | dimension, operator, expressionを掛け合わせて検索条件を表現する。(例)"query" "equals" "おすすめ" |
dimensionFilterGroups[].filters[].dimension | String | "country"(国),"device"(デバイス),"page"(ページ),"query"(クエリ)のいずれかを指定する |
dimensionFilterGroups[].filters[].operator | String | "contains"(含む),"equals"(一致),"notContains"(含まない),"notEquals"(不一致)をのいずれかを指定する |
dimensionFilterGroups[].filters[].expression | String | 値を指定する |
はまった点
あまり関係ないけど、RVMを使用してたらSSLの設定ができてなくてエラーがでた
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
オプションをつけてrubyをインストールしなおしたらうまくいった
rvm install 2.2.0 --disable-binary