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
-
API を有効化する
2. API KEY の発行 と referer の設定
続いて、API KEY の発行 と referer の設定 をします。
-
認証情報を作成する
認証情報を作成します。Accelerated Mobile Pages (AMP) URL API
は、API KEY のみ使えるようなので、
そちらを作成します。
-
refererの設定
referer の設定をします。
python スクリプトからは、ここで許可ドメインをrefererに設定します。
IPアドレス固定ならIPアドレスでもいいかもしれません。
Python スクリプト
以下、作成した Python スクリプトになります。
-
batch_get_amp_url.py
こちらを実行すると、以下のようなOUTPUT が出力されます。# -*- 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
### 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 削除を促したほうがいいと思う。(が、即時反映はされない)。
参考
以下、記事、ドキュメントが参考になりました。
以上です。
コメント