'How to automate Google PageSpeed Insights tests using Python

Is there a way to automate checking Google Page Speed scores?



Solution 1:[1]

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.

  1. Go to Cloud https://console.developers.google.com
  2. Sign up for an account if necessary.
  3. Create a Project
  4. Go to Menu > API Manager > Credentials
  5. Create credentials button > API Key
  6. Copy Key then hit close
  7. Menu > Dashboard > Enable API
  8. Use Search to find PageSpeed insights API and click on it
  9. 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.

Solution 2:[2]

Anybody using this guide (as of April 2022) will need to update to the following:

https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url={YOUR_SITE_URL}/&filter_third_party_resources=true&locale=en_US&screenshot=false&strategy=desktop&key={YOUR_API_KEY}

The difference is the "/v2/" needs to be replaced with "/v5/"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 David Jerome