0

I am trying to scrape very small information from a webpage using Cheerio and Google Apps Script. I want to get the performance number from this webpage:

enter image description here


Following is the code snippet that I am using to get it:

function LinkResult(){

  var url ='https://pagespeed.web.dev/report?url=http%3A%2F%2Fwww.juicecoldpressed.com%2F';

  var result = UrlFetchApp.fetch(url);
  var content = Cheerio.load(result.getContentText())
  var item = content(".lh-gauge__percentage").text()

  Logger.log(item)
  
}

As I run, this code does not show any output in the variable item. Surely there is something which I am missing, can you please guide me? Thank you.

1 Answers1

2

Issue and workaround:

In this case, I'm worried that your goal might not be able to be directly achieved using the URL of https://pagespeed.web.dev/report?url=http%3A%2F%2Fwww.juicecoldpressed.com%2F and Cheerio. Because the HTML data retrieved from UrlFetchApp.fetch(url) is different from that on the browser. And, it seems that the value is calculated using a script.

Fortunately, in your situation, I thought that your values can be retrieved using PageSpeed Insights API. In this answer, I would like to propose achieving your goal using PageSpeed Insights API.

Usage:

1. Get Started with the PageSpeed Insights API.

Please check the official document for using PageSpeed Insights API. In this case, it is required to use your API key. And, please enable PageSpeed Insights API at the API console.

2. Sample script.

function myFunction() {
  const apiKey = "###"; // Please set your API key.
  const url = "http://www.juicecoldpressed.com/"; // Please set URL.

  const apiEndpoint = `https://www.googleapis.com/pagespeedonline/v5/runPagespeed?key=${apiKey}&url=${encodeURIComponent(url)}&category=performance`;
  const strategy = ["desktop", "mobile"];
  const res = UrlFetchApp.fetchAll(strategy.map(e => ({ url: `${apiEndpoint}&strategy=${e}`, muteHttpExceptions: true })));
  const values = res.reduce((o, r, i) => {
    if (r.getResponseCode() == 200) {
      const obj = JSON.parse(r.getContentText());
      o[strategy[i]] = obj.lighthouseResult.categories.performance.score * 100;
    } else {
      o[strategy[i]] = null;
    }
    return o;
  }, {});
  
  console.log(values);
}

3. Testing.

When this script is run, you can see the returned value of { desktop: ##, mobile: ## } at the log. The values (the unit is %.) of desktop and mobile are the values for the desktop and the mobile, respectively.

Reference:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • thank you for your answer. I tried to get an API key from the API link you provided but it is saying that "permission denied". So I couldn't get around it. –  Jun 19 '22 at 05:53
  • 1
    @Roomi Thank you for replying. I apologize for the inconvenience. About `I tried to get an API key from the API link you provided but it is saying that "permission denied".`, unfortunately, after the setting was finished, when I tested my sample script, no error occurs. But, I would like to support you. So can you provide the detailed flow for correctly replicating your issue of `"permission denied"`? By this, I would like to confirm it. Unfortunately, I cannot understand your situation from only `"permission denied"`. This is due to my very poor skill. I deeply apologize for this. – Tanaike Jun 19 '22 at 05:56
  • 1
    @Roomi By the way, for example, have you already enabled PageSpeed Insights API at the API console? – Tanaike Jun 19 '22 at 05:57
  • Yes, I enabled it and testing now –  Jun 19 '22 at 06:07
  • 1
    @Roomi Thank you for replying. I apologize for the inconvenience, again. About `Yes, I enabled it and testing now`, I understood that you enabled PageSpeed Insights API. As an important point, the API is required to be enabled with the same client of the API key. Please be careful about this. When you enabled the API and the retrieved API key is used to my proposed script, I think that the script works. For example, in order to check the error, how about putting `console.log(r.getContentText())` just after `o[strategy[i]] = null;`? By this, when an error occurs, you can see the error message. – Tanaike Jun 19 '22 at 06:15
  • Ok I tested the script, the output from the script is `{ desktop: 80, mobile: 42 }` , when I go to the website and checked it showed `{ desktop: 86, mobile: 53 }`. Don't know why the difference is. –  Jun 19 '22 at 06:15
  • @Roomi Thank you for replying. From `Ok I tested the script, the output from the script is { desktop: 80, mobile: 42 } , when I go to the website and checked it showed { desktop: 86, mobile: 53 }. Don't know why the difference is. `, I understood that the script worked. About the difference values, in this case, it seems that when the script is run, the values are changed every time. Because the response time of the site is changed and this is reflected in the calculation of the value. – Tanaike Jun 19 '22 at 06:18
  • Ok clear thank you, one more thing, if I have 500 URLs to check in the Google sheet, then what is the daily limit of URLs that this script can check. I do not find any information about the daily limit of the script. –  Jun 19 '22 at 06:21
  • @Roomi Thank you for replying. About your additional question of `one more thing, if I have 500 URLs to check in the Google sheet, then what is the daily limit of URLs that this script can check. I do not find any information about the daily limit of the script.`, in this case, I think that it can be seen "Quotas" of "APIs & Service" of "PageSpeed Insights API". In the current stage, when I check it, it seems that "Queries per day" and "Queries per 1 minute" are 25000 and 240, respectively. [This thread](https://stackoverflow.com/q/37122041) might be the answer of your additional question. – Tanaike Jun 19 '22 at 06:31
  • thank you for your help so far, I found this solution very helpful. But it is too slow to get the result that sometimes it crashes, can you advise me on this? thank you –  Jun 25 '22 at 16:43
  • @Roomi About your new question of `But it is too slow to get the result that sometimes it crashes, can you advise me on this?`, in this case, I would like to propose to post it as a new question. Because I have no clear answer. I deeply apologize that I cannot resolve your all questions soon. This is due to my very poor skill. I deeply apologize for this. I have to study more. – Tanaike Jun 25 '22 at 23:23
  • sure, I'll do that now –  Jun 26 '22 at 02:13