SEO対策において検索順位を定期的に確認することは重要ですが、手動でチェックするのは大変です。
この記事では、「VBA スクレイピング」を使い、Google Custom Search APIによる自動検索順位取得方法を紹介します。
さらに、学習目的のVBAとSeleniumによるスクレイピング手法も掲載していますが、こちらはGoogleの利用規約に抵触するため注意が必要です。
Google Custom Search APIを使った検索順位取得方法
Google Custom Search APIを利用するためには、以下の2つの情報が必要です。
- 「Custom Search API」というサービスを有効化し、「APIキー」を取得。
- 「Custom Search Engine(CSE)」で作成した検索エンジンを特定するための「検索エンジンID(cxパラメータ)」を取得。
Custom Search Engine(CSE)はカスタム検索エンジンを設定する場所で、検索の範囲やフィルターを設定するもので、言語の指定や国の指定などで範囲を決めることができます。
Custom Search APIは、CSEで作成した検索エンジンをプログラムから利用するためのインターフェースのことです。
APIキーの取得方法
このキーを取得するには、Google Cloud ConsoleでAPIを有効化し、キーを生成する必要があります。
APIキーの取得手順
1.Google Cloud Consoleにアクセス
Google Cloud Consoleにアクセスし、Googleアカウントでログインします。
プロジェクトを新規作成するか、既存のプロジェクトを選択します。
2.Custom Search APIの有効化
プロジェクトを選択した状態で、「APIとサービス」>「ライブラリ」に移動します。
「Custom Search API」を検索し、表示されたAPIを選択し、有効化します。
3.APIキーの生成
「APIとサービス」>「認証情報」に移動し、「認証情報を作成」ボタンをクリックします。
「APIキー」を選択すると、新しいAPIキーが生成されます。
このAPIキーをコピーし、後で使用できるように安全に保管しておきましょう。
検索エンジンIDの取得方法
検索エンジンID(cxパラメータ)は、Custom Search Engine(CSE)で作成した検索エンジンを特定するためのIDです。
このIDを取得するには、CSEの設定が必要です。
検索エンジンIDの取得手順
1.Custom Search Engine(CSE)にアクセス
Custom Search Engine(CSE)にアクセスし、Googleアカウントでログインします。
「最初の検索エンジンを作成してください。」をクリックします。
2.検索エンジンの設定
検索エンジン名を入力し、検索対象を「ウェブ全体を検索」を選択し、検索エンジンを作成します。
検索エンジン作成後「カスタマイズ」ボタンをクリックし、「基本」部分を参照します。
3.検索エンジンIDの確認
「検索エンジンID」という欄に、APIリクエストで利用するIDが表示されます。
このIDをコピーして、APIのリクエストで cx
パラメータとして使用します。
このページにて、検索範囲や言語設定の変更が可能です。
VBAで実装する検索順位の自動取得
Google Custom Search APIは簡単に導入できますが、以下の制限があります。
- API制限数:1日あたりのリクエスト数制限があり、超えると追加料金が発生します。
- 検索精度:特定のURLが結果に含まれないこともあるため、検索順位確認の精度が低い場合があります。
実際に私もこのAPIを試した際、手動で検索すると1位で表示されるサイトがJSONレスポンスに含まれないケースがあり、精度に限界があると感じました。
ExcelレイアウトとVBAコード(API利用による検索順位取得)
Excel自体のレイアウト
A列に順位検索するURLを指定し、B列に検索する語句をスペースで区切って入力します。
C列に列追加して、順位検索して自動的に順位を取得してきます。
※20以内に指定したURLがない場合は、「圏外」扱いとしています。
VBAコード(API利用版)
以下のコードで、VBAからGoogle Custom Search APIを利用した検索順位を取得できます。
不具合等あったら申し訳ありませんが、掲載したコード自体は、自由に改変してお使いください。
定数「GOOGLE_API_KEY
」にGoogle Cloud Consoleから取得した「APIキー」を設定し、
定数「GOOGLE_CX_ID
」にCustom Search Engine(CSE)から取得した「検索エンジンID」を設定します。
このコード自体は、以下のサイト様のソースを参考に改変させていただきました。ありがとうございました。
Option Explicit
Private Const GOOGLE_API_KEY As String = "取得したAPIキー"
Private Const GOOGLE_CX_ID As String = "取得した検索エンジンID"
Private Const GOOGLE_SEARCH_URL As String = "https://www.googleapis.com/customsearch/v1"
Sub RankChecker()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim wkRow As Long, lngRank As Long
Dim searchQuery As String
If ws.Range("D1").Value < Date Then
Call subSetHeadFormat(ws)
Call subSetDetailFormat(ws)
End If
For wkRow = 2 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If ws.Cells(wkRow, 3) <> "" Then
searchQuery = Trim(Replace(ws.Cells(wkRow, 3), " ", " "))
lngRank = GetSearchResultRank(searchQuery, ws.Cells(wkRow, 2).Value)
If lngRank > 0 Then
ws.Cells(wkRow, 4).Value = lngRank
Else
ws.Cells(wkRow, 4).Value = "圏外"
End If
End If
Next wkRow
MsgBox "取得完了"
End Sub
Function GetSearchResultRank(searchQuery As String, targetURL As String) As Long
Dim http As Object
Dim json As Object
Dim apiUrl As String
Dim item As Object
Dim i As Long, startIndex As Long
Dim rank As Long
rank = 0
startIndex = 1
Do While startIndex <= 10
apiUrl = GOOGLE_SEARCH_URL & "?q=" & Application.WorksheetFunction.EncodeURL(searchQuery) _
& "&cx=" & GOOGLE_CX_ID & "&key=" & GOOGLE_API_KEY & "&lr=lang_ja&num=10&start=" & startIndex
Debug.Print "APIリクエストURL: " & apiUrl
Set http = CreateObject("MSXML2.ServerXMLHTTP.6.0")
http.Open "GET", apiUrl, False
http.Send
If http.Status <> 200 Then
MsgBox "エラーのため取得できませんでした: " & http.statusText, vbExclamation
Exit Function
End If
On Error Resume Next
Set json = JsonConverter.ParseJson(http.responseText)
On Error GoTo 0
If Not json Is Nothing And json.Exists("items") Then
For Each item In json("items")
i = i + 1
If item("link") = targetURL Then
rank = startIndex + i - 1
GetSearchResultRank = rank
Exit Function
End If
Next item
Else
Exit Do
End If
startIndex = startIndex + 10
i = 0
Loop
GetSearchResultRank = 0
End Function
Private Sub subSetHeadFormat(ByVal ws As Worksheet)
With ws
.Columns("D").Insert
.Columns("D").ColumnWidth = 4.8
.Range("D1").Clear
.Range("D1").NumberFormatLocal = "m/d"
.Range("D1").HorizontalAlignment = xlCenter
.Range("D1").Value = Now()
.Range("D1").Interior.Color = RGB(32, 55, 100)
.Range("D1").Font.Color = RGB(255, 255, 255)
.Range("D1").Font.Bold = True
.Columns("D").EntireColumn.AutoFit
End With
End Sub
Private Sub subSetDetailFormat(ByVal ws As Worksheet)
Dim tgRng As Range, myRng As Range
Dim strAdr1 As String, strAdr2 As String
With ws
Set tgRng = .Range("A1").CurrentRegion
Set tgRng = Intersect(tgRng, tgRng.Offset(1, 3))
End With
tgRng.FormatConditions.Delete
For Each myRng In tgRng
strAdr1 = myRng.Address(True, True)
strAdr2 = myRng.Offset(, 1).Address(True, True)
With myRng.FormatConditions.AddIconSetCondition
.IconSet = ws.Parent.IconSets(xl3TrafficLights1)
.IconCriteria(1).Icon = xlIconGreenUpArrow
With .IconCriteria(2)
.Type = xlConditionValueFormula
.Value = "=IF(" & strAdr2 & " = """", " & strAdr1 & ", IF(AND(NOT(ISNUMBER(" & strAdr2 & ")), ISNUMBER(" & strAdr1 & ")), " & strAdr1 & " + 1, " & strAdr2 & "))"
.Operator = 7
.Icon = xlIconNoCellIcon
End With
With .IconCriteria(3)
.Type = xlConditionValueFormula
.Value = "=IF(AND(NOT(ISNUMBER(" & strAdr2 & ")), ISNUMBER(" & strAdr1 & ")), " & strAdr1 & " + 1, IF(" & strAdr2 & " = """", " & strAdr1 & ", " & strAdr2 & "))"
.Operator = 5
.Icon = xlIconRedDownArrow
End With
End With
With myRng.FormatConditions.Add(Type:=xlExpression, Formula1:="=ISTEXT(" & myRng.Address(False, False) & ")")
.Interior.Color = vbYellow
End With
Next
End Sub
Googleの利用規約に注意したスクレイピング活用法
上記コードを利用しても、結果に特定のURLが含まれないなどの精度不足が確認されました。
また、APIの実行制限があるため、日常的な利用には費用がかかります。
そのため、実務用途には他のツールの利用が適しているでしょう。
学習用コード例:VBAとSeleniumを使ったスクレイピング
学習目的で、VBAとSeleniumBasicを用いたスクレイピングの方法も紹介します。
なお、Googleの利用規約でスクレイピングは禁止されているため、実際の運用には適しません。
SeleniumBasicのインストール方法
SeleniumBasicの設定は、以下のサイト様が分かりやすかったので、参考にさせていただきました。
- SeleniumBasic GitHubページからインストーラをダウンロードし、PCにインストールします。
- 必要に応じてChromeDriverをSeleniumBasicのインストールフォルダに配置し、Chromeブラウザ操作を可能にします。
- VBAの[ツール] – [参照設定]にて「Selenium Type Library」をチェックします。
ExcelレイアウトとVBAコード(Seleniumによるスクレイピング学習用)
Excelのレイアウトは、既述のVBAコード(API利用による検索順位取得)と同様です。
以下のコードで、VBAからSeleniumを使用して検索順位を取得できます。
ただし、Googleの検索結果をスクレイピングするのは、利用規約違反にあたりますので、実際の利用には適していません。
不具合等あったら申し訳ありませんが、掲載したコード自体は、学習用として自由に改変してお使いください。
このコードも、既述のサイト様のソースを参考に改変させていただきました。ありがとうございました。
Option Explicit
Private driver As Selenium.WebDriver
Private Const cnsGUrl As String = "https://www.google.com/"
Sub RankCheker()
'起動シートの初期処理
Dim ws As Worksheet
Set ws = ActiveSheet
'Seleniumの初期処理
Dim sKey As New Selenium.Keys
Dim elm As Selenium.WebElement
Dim wkRow&, lngRank&, wkStr$
Set driver = New Selenium.WebDriver
driver.AddArgument "--incognito" 'シークレットモード
driver.Start "chrome"
driver.Window.Maximize
AppActivate Application.Caption
With ws
'前回実行日が前日以前なら履歴を残す
If .Range("C1").Value < Date Then
Call subSetHeadFormat(ws)
Call subSetDetailFormat(ws)
End If
For wkRow& = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row
If ws.Cells(wkRow&, 2) <> "" Then
driver.Get cnsGUrl
AppActivate Application.Caption
'検索語句はC列から取得
wkStr$ = Trim(Replace(ws.Cells(wkRow&, 2), " ", " "))
driver.FindElementByName("q").SendKeys(wkStr$).Value
driver.FindElementByName("q").SendKeys sKey.Enter
driver.Wait (2000)
'検索結果からサイト掲載要素を取得
Set elm = fncGetElement(ws.Cells(wkRow&, 1), lngRank&)
If Not elm Is Nothing Then
.Cells(wkRow&, 3) = lngRank&
Else
.Cells(wkRow&, 3) = "圏外"
End If
End If
Next wkRow&
End With
'終了処理:Close,Quitは無くても良いけど
driver.Close
driver.Quit
Set driver = Nothing
MsgBox "取得完了"
End Sub
'概 要:指定したXPathの要素を取得:ページ内に無い場合は「次へ」
'引 数:piURL 検索するURL
' poRank 順位(戻り値のような扱い)
'戻り値:Selenium.WebElement
Private Function fncGetElement(ByVal piURL As String, ByRef poRank As Long) As Selenium.WebElement
Set fncGetElement = Nothing
Dim elm As Selenium.WebElement
Dim elms As Selenium.WebElements
Dim myBy As New By
Dim cntPage%
Dim wkStr$
cntPage% = 1
poRank = 1
On Error Resume Next
Do
'H3タグの一覧を取得
Set elms = driver.FindElementsByXPath("//*[@id='rso']//h3")
'H3タグ内のリンクを検索
For Each elm In elms
' H3タグを含むセクション内のaタグを取得
wkStr$ = elm.FindElementByXPath("ancestor::div[contains(@class, 'g')]//a").Attribute("href")
'URLが一致するかを確認
If wkStr$ = piURL Then
' 順位が判明したので、処理終了
Set fncGetElement = elm
Exit Function
End If
poRank = poRank + 1
Next elm
' 5ページまで検索
cntPage% = cntPage% + 1
If cntPage% > 5 Then
Exit Function
End If
' 次へをクリック
driver.FindElementByXPath("//*[@id='pnnext']/span").Click
driver.Wait (2000)
Loop
End Function
'日付履歴追加
Private Sub subSetHeadFormat(ByVal ws As Worksheet)
With ws
.Columns("C").Insert
.Columns("C").ColumnWidth = 5
.Range("C1").Clear
.Range("C1").NumberFormatLocal = "m/d"
.Range("C1").HorizontalAlignment = xlCenter
.Range("C1").Value = Now()
.Range("C1").Interior.Color = RGB(32, 55, 100)
.Range("C1").Font.Color = RGB(255, 255, 255)
.Range("C1").Font.Bold = True
.Columns("C").EntireColumn.AutoFit
End With
End Sub
'明細アイコンセットの設定
Private Sub subSetDetailFormat(ByVal ws As Worksheet)
Dim tgRng As Range, myRng As Range
Dim strAdr1 As String, strAdr2 As String
With ws
Set tgRng = .Range("A1").CurrentRegion
Set tgRng = Intersect(tgRng, tgRng.Offset(1, 2))
End With
tgRng.FormatConditions.Delete
For Each myRng In tgRng
strAdr1 = myRng.Address(True, True)
strAdr2 = myRng.Offset(, 1).Address(True, True)
' 既存のアイコンセットの条件付き書式
With myRng.FormatConditions.AddIconSetCondition
.IconSet = ws.Parent.IconSets(xl3TrafficLights1)
.IconCriteria(1).Icon = xlIconGreenUpArrow
With .IconCriteria(2)
.Type = xlConditionValueFormula
.Value = "=IF(" & strAdr2 & " = """", " & strAdr1 & ", IF(AND(NOT(ISNUMBER(" & strAdr2 & ")), ISNUMBER(" & strAdr1 & ")), " & strAdr1 & " + 1, " & strAdr2 & "))"
.Operator = 7
.Icon = xlIconNoCellIcon
End With
With .IconCriteria(3)
.Type = xlConditionValueFormula
.Value = "=IF(AND(NOT(ISNUMBER(" & strAdr2 & ")), ISNUMBER(" & strAdr1 & ")), " & strAdr1 & " + 1, IF(" & strAdr2 & " = """", " & strAdr1 & ", " & strAdr2 & "))"
.Operator = 5
.Icon = xlIconRedDownArrow
End With
End With
With myRng.FormatConditions.Add(Type:=xlExpression, Formula1:="=ISTEXT(" & myRng.Address(False, False) & ")")
.Interior.Color = vbYellow
End With
Next
End Sub
実務に適した検索順位追跡ツールの選択肢
検索順位を確認するための手法として、VBAによるスクレイピングやAPIの利用にはいくつかの制約があるため、実用面で難しい点もあります。
特に、Googleの利用規約ではスクレイピングによるデータ取得が禁止されているため、検索エンジンからのデータ取得には注意が必要です。
また、Custom Search APIを利用した場合も、無料の利用枠では実行回数が限られており、頻繁に利用するには実用的ではないと感じました。
推奨される検索順位チェックツール
1. GRC(無料版は3つのURLまで)
- 特徴:GRCは、SEOに特化した検索順位チェックツールで、日本語キーワードの検索順位を追跡するのに優れています。無料版はURLを3つまで登録できますが、有料プランでは登録数が増え、詳細な分析機能が使えるようになります。
- おすすめ利用方法:無料プランで基本的な検索順位の確認を行いたい場合や、主要なURLを3つだけ追跡したい場合には、GRCは非常に便利です。SEOの効果を確認しながら、予算に合わせて有料プランへの移行も検討できます。
- 料金:無料版は制限がありますが、有料版は月額約500円からとリーズナブルですが、本格的に使用するには月990円以上のプランが必要です。
- GRC公式サイト
2. Serposcope(完全無料・オープンソース)
- 特徴:Serposcopeは、インストールして使える無料のオープンソースツールで、キーワードごとの順位を細かく追跡する機能を備えています。データをPC上で直接管理できるため、セキュリティ面でも安心です。
- 注意点:私の環境ではアクセスできないトラブルが発生し、解決できませんでした。利用環境によっては、動作がうまくいかない可能性があるため、トラブル対応が可能な方におすすめです。
- Serposcope公式サイト
3. ohotukuの検索順位チェックツール(無料でオンライン利用可能)
- 特徴:インストール不要で、ブラウザから直接利用できるオンラインツールです。URLとキーワードを入力するだけで順位が確認できるため、手軽に利用したい方には最適です。
- 注意点:複数のキーワードやURLを定期的に追跡する場合にはやや不向きです。自分で順位を記録していく必要があるため、ログを残したい人は工夫が必要です。
- ohotuku公式サイト
結論
GRCやSerposcopeなどのツールは、手軽にSEO管理を行うために役立ちます。
GRCの無料版でまず基本的な順位変動を確認し、必要に応じて有料版に移行するのも有効です。
Serposcopeやohotukuも選択肢として検討し、管理ニーズに合ったツールを選んでください。