AMP の 妥当性検証 を一括実行できるようにしたので、
妥当性検証 で NG ページを修正した後、
再クロールを促すを一括実行できるようにしたいと思いました。

AMP(Accelerated Mobile Pages)URL APIいうものがあります。
これで、現状 Cache されている AMP の URL 一覧を取得できそうなので、最終的に再クロールを促すを実施できないか試してみました。
結果を以下記載します。


前提

Python の version

AMP(Accelerated Mobile Pages)URL API batchget実行するスクリプトは、Python で作成しました。
Python の version は以下の通りです。

python -V
--------------------------
Python 2.7.10
--------------------------

api key の 取得 と api の 有効化

batchget実行には、api key の取得と、Developer Console から api の 有効化 が 必要です。
api key を とらずに、batchget実行したところ、以下のエラーが response で返ってきて気がつきました。
PERMISSION_DENIED 戻ってきます。

{u'error': {u'code': 403,
            u'message': u'The request is missing a valid API key.',
            u'status': u'PERMISSION_DENIED'}}

以下の手順を踏んで、api の 有効化 key の発行を行いました。

1. API の 有効化

https://console.developers.google.com/アクセスして、
ライブラリから、Accelerated Mobile Pages (AMP) URL API選択し、有効化します。

  • Accelerated Mobile Pages (AMP) URL API
    Accelerated Mobile Pages (AMP) URL API

  • API を有効化する
    API を<wbr>有効化する<wbr>

2. API KEY の発行 と referer の設定

続いて、API KEY の発行 と referer の設定 をします。

  • 認証情報を作成する
    認証情報を作成します。Accelerated Mobile Pages (AMP) URL API は、API KEY のみ使えるようなので、
    そちらを作成します。
    認証情報を<wbr>作成
    キーの<wbr>確認画面

  • refererの設定
    referer の設定をします。
    python スクリプトからは、ここで許可ドメインをrefererに設定します。
    IPアドレス固定ならIPアドレスでもいいかもしれません。
    refererの<wbr>設定


Python スクリプト

以下、作成した Python スクリプトになります。

  • batch_get_amp_url.py

    # -*- coding: utf-8 -
    
    import requests
    from bs4 import BeautifulSoup
    import json
    try:
        # Python 3
        from itertools import zip_longest
    except ImportError:
        # Python 2
        from itertools import izip_longest as zip_longest
    
    SITEMAP_URL = "your_sitemap_url"
    BATCH_GET_API_URL = "https://acceleratedmobilepageurl.googleapis.com/v1/ampUrls:batchGet"
    API_KEY = "your_api_key"
    REFERER = "your.domain.com"
    LOOKUP_STRATEGY = "IN_INDEX_DOC"
    
    def execute():
        soup = BeautifulSoup(requests.get(SITEMAP_URL).text, "xml")
        urls = []
        for loc in soup.find_all('loc'):
            urls.append(loc.get_text())
    
        collect_exists_urls = []
        collect_url_errors = []
        for splited_urls in zip_longest(*[iter(urls)] * 50):
            obj = {"urls": filter(lambda n: n is not None,
                                  splited_urls), "lookupStrategy": LOOKUP_STRATEGY}
            json_data = json.dumps(obj).encode("utf-8")
            headers = {'X-Goog-Api-Key': API_KEY,
                       'referer': REFERER}
            response = requests.post(BATCH_GET_API_URL,
                                     data=json_data,
                                     headers=headers)
            json_o = response.json()
            if json_o.get("ampUrls"):
                collect_exists_urls.extend(json_o.get("ampUrls"))
            if json_o.get("urlErrors"):
                collect_url_errors.extend(json_o.get("urlErrors"))
    
        print("### EXISTS URLS ### ")
        for idx, amp_url_dict in enumerate(collect_exists_urls):
            print("|[" + str(idx) + "]" + "|URL:" + amp_url_dict.get("originalUrl") +
                  "|AMPURL:" + amp_url_dict.get("cdnAmpUrl") + "|")
    
        print("### ERROR URLS ### ")
        for idx, amp_url_dict in enumerate(collect_url_errors):
            error_code = amp_url_dict.get("errorCode")
            if error_code != "URL_IS_VALID_AMP":
                print("|[" + str(idx) + "]" + "|URL:" + amp_url_dict.get("originalUrl") +
                      "|CODE:" + str(amp_url_dict.get("errorCode")) + "|")
    
    
    if __name__ == '__main__':
        execute()
    
    こちらを実行すると、以下のようなOUTPUT が出力されます。

  • OUTPUT

    ### EXISTS URLS ### 
    |[0]|URL:https://www.monotalk.xyz/blog/In-IntelliJ-IDEA-Could-not-find-executable-in-%60GAUGE_HOME%60,%60PATH%60-or-%60GAUGE_ROOT%60-occurred/|AMPURL:https://www-monotalk-xyz.cdn.ampproject.org/c/s/www.monotalk.xyz/blog/In-IntelliJ-IDEA-Could-not-find-executable-in-%60GAUGE_HOME%60,%60PATH%60-or-%60GAUGE_ROOT%60-occurred/|
    |[1]|URL:https://www.monotalk.xyz/blog/Try-Japanese-translation-of-rule-of-SonarQube/|AMPURL:https://www-monotalk-xyz.cdn.ampproject.org/c/s/www.monotalk.xyz/blog/Try-Japanese-translation-of-rule-of-SonarQube/|
    |[2]|URL:https://www.monotalk.xyz/blog/Wicket-AjaxButton-Controls-behavior-when-an-error-occurs-onSubmit-method/|AMPURL:https://www-monotalk-xyz.cdn.ampproject.org/c/s/www.monotalk.xyz/blog/Wicket-AjaxButton-Controls-behavior-when-an-error-occurs-onSubmit-method/|
    ### ERROR URLS ### 
    |[0]|URL:https://www.monotalk.xyz/blog/execute_redpen_on_wercker/|CODE:URL_IS_INVALID_AMP|
    |[1]|URL:https://www.monotalk.xyz/blog/django-htmlmin-on-mezzanine/|CODE:NO_AMP_URL|
    |[2]|URL:https://www.monotalk.xyz/blog/rundeck-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E5%90%8D%E7%A7%B0%E5%A4%89%E6%9B%B4%E3%81%97%E3%81%9F%E3%82%89%E5%8B%95%E3%81%8B%E3%81%AA%E3%81%8F%E3%81%AA%E3%81%A3%E3%81%9F/|CODE:NO_AMP_URL|
    |[3]|URL:https://www.monotalk.xyz/blog/migrations-to-mezzanine-4.2.2-from-4.2.0/|CODE:NO_AMP_URL|
    

説明

  • batchget のリクエストに含めることのできる URL の上限について
    Link to AMP Content | Google AMP Cache | Google Developers記載がありますが、
    上限は50 URLになります。sitemap上 50以上 url が記載されていたので、
    itertools.zip_longest使って、要素数50 にリストを分割して、リクエストを送付するようにしています。

  • API KEY の設定方法について
    Link to AMP Content | Google AMP Cache | Google Developers記載がありますが、
    request ヘッダーにX-Goog-Api-Key: YOUR-DEVELOPER-KEY形式で設定します。
    スクリプトでは、requests使用したので以下のようにreferer とともに設定しました。

           headers = {'X-Goog-Api-Key': API_KEY,
                      'referer': REFERER}
    

  • 戻り値について
    戻りはJSON電文で返却されます。
    ampUrls には、正常にcacheされている URL情報 が設定され、
    urlErrors には、cacheされていない、またはcacheされているがなんらかの異常がある URL情報が設定されます。

  • errorCode について
    urlErrors設定されたエラー情報には、errorCode が設定されますが、
    設定されるエラーコードは以下になります。
    Method: ampUrls.batchGet  |  Google AMP Cache  |  Google Developers説明を参考にしています。

    • INPUT_URL_NOT_FOUND
      要求されたURLが何らかの理由で、インデックスに見つからない場合、設定されます。

    • NO_AMP_URL
      要求されたURLに対応するAMP URLが見つからなかった場合、設定されます。

    • APPLICATION_ERROR
      サーバーで何らかの種類のアプリケーションエラーが発生した場合、設定されます。

    • URL_IS_VALID_AMP
      要求されたURLが有効なAMP URLである場合、設定されます。 APIの説明で廃止されるとあり、このエラーの場合は、実装上エラーとして出力しないようにしました。

    • URL_IS_INVALID_AMP
      リクエストURLに対応するAMP URLが見つかったが、有効なAMP HTMLではない場合、設定されます。


実際にスクリプトを実行し、その結果を元に改善してみる

正常に Cache されている URL は問題ないとして、
エラーになったURLについて何か改善できないか検討してみます。

INPUT_URL_NOT_FOUND

以下、コマンドを実行して、数を数えてみました。

python2.7 batch_get_amp_url.py | grep INPUT_URL_NOT_FOUND | wc
-------------------
      27      27    4319
-------------------

結構な数が出力されています。
URL に法則がありそうもなく、 Google に index されてないかというとそうでもなく、
何故ここに、分類されているのか正直よくわからなかったので、一旦放置します。

NO_AMP_URL

以下、コマンドを実行して、数を数えてみました。

python2.7 batch_get_amp_url.py | grep NO_AMP_URL | wc
-------------------
     105     105   16661
-------------------

これも結構な数が出力されています。そもそも AMP にまだcacheされていないということなので、
batchget api の LOOKUP_STRATEGY オプションを FETCH_LIVE_DOC変えて再実行してみます。1

[1] batchget の デフォルトのLOOKUP_STRATEGY は、FETCH_LIVE_DOC です。
これで、まだ Cache されていない URL の場合は、batchget 時に Cache を作成してくれるようになります。

再度、コマンドを実行します。

python2.7 batch_get_amp_url.py | grep NO_AMP_URL | wc
-------------------
     105     105   16661
-------------------

結果が変わりません。。試しに、
python2.7 batch_get_amp_url.py | grep INPUT_URL_NOT_FOUND | wc再実行したところ、
結果は以下になりました。

-------------------
     0       0       0
-------------------

LOOKUP_STRATEGY は、INPUT_URL_NOT_FOUNDなった URL に影響を与えるようです。

APPLICATION_ERROR

以下、コマンドを実行して、数を数えてみました。
特にエラーはないようです。

python2.7 batch_get_amp_url.py | grep APPLICATION_ERROR | wc
-------------------
       0       0       0
-------------------

URL_IS_INVALID_AMP

以下、コマンドを実行して、数を数えてみました。

python2.7 batch_get_amp_url.py | grep URL_IS_INVALID_AMP | wc
-------------------
      32      32    4951
-------------------

32件あります。
update-pingを使ったAMPページのキャッシュの消し方 - 株式会社インターエデュ・ドットコム
参考に、以下 curl のようなコマンド を作成し、
cache の削除を促します。

curl --head "https://cdn.ampproject.org/update-ping/c/s/www.monotalk.xyz/blog/mezzanine-amp-%E5%AF%BE%E5%BF%9C%E3%81%AE%E3%83%86%E3%83%BC%E3%83%9E%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F"
----------------------------------------------
HTTP/1.1 204 No Content
Content-Type: text/html; charset=ISO-8859-1
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
Date: Fri, 14 Jul 2017 09:50:16 GMT
Server: sffe
X-XSS-Protection: 1; mode=block
Alt-Svc: quic=":443"; ma=2592000; v="39,38,37,36,35"
----------------------------------------------

以下、コマンドを実行して、再度数を数えてみました。

python2.7 batch_get_amp_url.py | grep URL_IS_INVALID_AMP | wc
-------------------
      32      32    4951
-------------------

即時だと、特に変化はないようです。
しばらく時間をおくと、状況は変わるのかもしれません。


まとめ

以下、まとめます。

  • batchget API の実行には、API KEY の発行と、referer、IP アドレスなどでの制限が必要(いれることは必須ではないがいれたほうがいい)。

  • batchget API は上限50URL までなので、50以上の URL の状況を調べるには、千切って何回かリスエストを投げる必要がある。

  • INPUT_URL_NOT_FOUND エラーは、LOOKUP_STRATEGY は、FETCH_LIVE_DOCすることで解消される。

  • URL_IS_INVALID_AMP は、AMP Cache の妥当性検証エラーとなっている。元のAMP のエラーが解消されても、
    Cacheは残り続けるので、update-ping でcache 削除を促したほうがいいと思う。(が、即時反映はされない)。


参考

以下、記事、ドキュメントが参考になりました。

以上です。

コメント