Is there a way to automate checking Google Page Speed scores?
Advertisement
Answer
So I figured out how to do this using the Google Page Speed API buried in the documentation.
The TL:DR explanation is you can use the following URL setup, replacing the bracketed values after enabling Google Pagespeed API in Cloud Console (and if in a browser you must also have Authenticated Google Cloud User Signed In).
https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url={YOUR_SITE_URL}/&filter_third_party_resources=true&locale=en_US&screenshot=false&strategy=desktop&key={YOUR_API_KEY}
As you can see from the link above you will need a Google Pagespeed API Key. These are from scratch setup instructions. If your project is already on Cloud Console you can skip the first few steps.
- Go to Cloud https://console.developers.google.com
- Sign up for an account if necessary.
- Create a Project
- Go to Menu > API Manager > Credentials
- Create credentials button > API Key
- Copy Key then hit close
- Menu > Dashboard > Enable API
- Use Search to find PageSpeed insights API and click on it
- Use the “|> ENABLE” button near the title
Once you have an API Key you can replace the values in the URL, it should look something like this:
https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=https://www.example.com/&filter_third_party_resources=true&locale=en_US&screenshot=false&strategy=desktop&key=FaKeApIKey29nS8U22mM
The parameter strategy=desktop in the url can be changed to strategy=mobile. For mobile you get a speed and a usability score. Here’s what the start of the JSON looks like:
{ "kind": "pagespeedonline#result", "id": "https://www.example.com/fake/page”, "responseCode": 200, "title": "Example Domain", "ruleGroups": { "SPEED": { "score": 100 }, "USABILITY": { "score": 100 } }, ....continued...
So I automated this using a Python & Python Unit Test.
import requests import json import unittest from globes import * api_key = '' # Add API key. Found here: https://console.developers.google.com/apis/credentials/key/ base = 'http://example.com' locale_code = 'en_US' def get_insights_json(self, page_url, local, device_type, api_key, speed_or_useability, expected_score): url = 'https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=' + page_url + '&filter_third_party_resources=true&locale=' + local + '&screenshot=false&strategy=' + device_type + '&key=' + api_key # print "Getting :: " + url r = requests.get(url) return_code = r.status_code try: self.assertEqual(return_code, 200) except AssertionError, e: self.verificationErrors.append(str(page_url) + " did not return 200") return_text = r.text return_json = json.loads(return_text) score = return_json['ruleGroups'][speed_or_useability]['score'] print 'Getting ' + speed_or_useability + ' for ' + page_url + ' and got a score of ' + str(score) try: self.assertTrue(int(score) >= expected_score) except AssertionError, e: self.verificationErrors.append(str(page_url) + ' expected ' + device_type + ' speed score to be greater than ' + str(expected_score) + ', instead got ' + str(score) ) class TestAllAPIs(unittest.TestCase): def setUp(self): self.verificationErrors = [] self.maxDiff = None def tearDown(self): self.assertEqual([], self.verificationErrors) def test_desktop_speed(self): current_page = base + '' # You could add to the url to test other pages, I tend to do this is a loop using a list I set up by base url. device_type = 'desktop' target = 'SPEED' get_insights_json(self, current_page, locale_code, device_type, api_key, target, 80) def test_mobile_speed(self): current_page = base + '' device_type = 'mobile' target = 'SPEED' get_insights_json(self, current_page, locale_code, device_type, api_key, target, 80) def test_mobile_useability(self): current_page = base + '' device_type = 'mobile' target = 'USABILITY' get_insights_json(self, current_page, locale_code, device_type, api_key, target, 80) if __name__ == "__main__": unittest.main()
There is one thing that’s a little of a mystery to me is why browsers need to be authenticated with Google to get JSON from URL but Python requests does not.