Build Your Own Keyword Rank Checker with PHP

Valentina Skakun Valentina Skakun
Last update: 26 Jun 2024

Rank checking is the process of monitoring the position of your website’s pages in the SERP for specific keywords. It’s a critical part of SEO because it helps you understand your website’s visibility for relevant searches and identify areas for improvement. There are many ready-made rank checking solutions and services available, but they often have limitations, such as low flexibility and high cost.

This article will show you how to create your rank checker in PHP scripting language. PHP is a powerful and versatile language that is well-suited for SEO tasks. It has a large community of developers and a wide range of libraries and tools.

Prerequisite Technologies

PHP is one of the most popular and oldest server-side scripting languages. It is often used in web development to create dynamic and interactive websites. In the previous article, we discussed PHP, how to set up a development environment, and which libraries can be used for making requests and scraping data.

In this article, we will not go into detail about the previously discussed topics, but we will simply list the tools and libraries that we will use:

Alternatively, you can use a tool like XAMPP to start a virtual Apache server for PHP development. This is a good option if you don’t want to go through the hassle of installing and configuring all the above components.

Developing the Keyword Rank Checker PHP Script

Keyword rank checkers are software applications or online platforms that help you track your website’s ranking position for specific keywords in search engine results pages (SERPs).

By tracking keyword rankings over time, you can pinpoint the effectiveness of your efforts, discover high-potential keywords with minimal competition, and analyze your rivals’ strategies. This process, an integral part of keyword research, not only informs your SEO tactics but also provides a competitive edge.

This invaluable data fuels your SEO decisions, guiding content creation, on-page optimization, and link building while serving as an early warning system for technical issues or search engine penalties.

Scraping Google Search Results with SERP API

Google is the most popular search engine, so using a rank checker based on Google SERP results is very in demand. To create your keyword position checker, you should consider all the restrictions Google imposes on scraping. However, this is still a relatively achievable task, and we have previously written about how to scrape Google search results yourself.

However, creating a Google rank checker involves scraping data and processing it. Therefore, to simplify the process, in this example we will use the HasData’s SERP API, which provides structured search results without the need to scrape Google yourself. This approach has several advantages:

  1. The SERP API provides ready-made and structured data.

  2. There is no need to use proxies.

  3. There are no problems with solving CAPTCHAs and bypassing them.

  4. If the structure of the search results page changes, you do not need to change the data processing logic since you receive a ready-made set of data.

  5. This approach is much simpler and can be handled even by beginners.

If you are still unsure of your abilities, we have already written an article in which you can find a ready-made rank checker and rank tracker, as well as a Google scraper, in Google Sheets. You can use the ready-made template and get all the necessary data. However, if you want to create your rank checker tool in PHP, this tutorial can help you.

Import Libraries and Make a Request

As we mentioned earlier, we will use Composer to import libraries. To do this, create a new file named composer.json and add the libraries used in the project. We will use the httpful library, so the file contents will be as follows:

{
    "require": {
        "nategood/httpful": "*"
    }
}

You can also replace * with a specific library version, but if you are unsure or just want to use the latest compatible version, leave *.

Create a file with the extension .php and import the necessary modules:

<?php
require 'vendor/autoload.php';
use Httpful\Request;

// Here will be code

?>

Set the parameters that we will pass to the API. You can find the full list in the official documentation, but we will only use the basics:

$location = 'Austin,Texas,United States';
$query = 'Coffee';
$filter = 1;
$domain = 'google.com';
$gl = 'us';
$hl = 'en';
$deviceType = 'desktop';

The most critical parameter is the contents of the variable $query, which stores the keyword or phrase for which the query is executed. You can also configure the localization and language of the search engine to get the most relevant data.

Set the domain of the resource for which the position search will be performed:

$searchedDomain = 'wikipedia.org';

We also need to specify the request header to pass the unique API key that can be found in your account after registering on the HasData website:

$headers = array(
    'x-api-key' => YOUR-API-KEY',
);

Then, assemble the request string:

$url = sprintf(
    'https://api.hasdata.com/scrape/google?location=%s&q=%s&filter=%d&domain=%s&gl=%s&hl=%s&deviceType=%s',
    rawurlencode($location),
    rawurlencode($query),
    $filter,
    rawurlencode($domain),
    rawurlencode($gl),
    rawurlencode($hl),
    rawurlencode($deviceType)
);

And execute the resulting request:

$response = Request::get($url)
    ->addHeaders($headers)
    ->send();

After this, the request will return a response, which we will process further.

Parsing and Extracting Keyword Ranks

The SERP API response returns a JSON object with the necessary data. Before we proceed to retrieve the required parameters, let’s take a look at the JSON response structure:

The SERP API response is a JSON object that contains the data needed to check a website's ranking on a search engine results page (SERP). The JSON object includes the organicResults attribute, which contains the URLs of the websites that are ranked for the search term. In addition to the organicResults attribute, the JSON object may also include other relevant data.

The JSON response structure

For the simplest Rank Checker, we can use the contents of the organicResults attribute. However, we will later add the date and time of the check, the link to the query page, and show how to get data from rich snippets.

Let’s decode the JSON response and store the result in a variable for further processing.

$data = json_decode($response->raw_body, true);

First, check if the JSON response is empty. If the request fails, we should stop the script and display an error message.

if (!is_array($data) || empty($data)) {
    die('Error with JSON decoding or Empty data');
}

Next, we should ensure that the organicResults property contains data and is an array. If not, we should also stop the script.

if (isset($data['organicResults']) && is_array($data['organicResults']) && !empty($data['organicResults'])) {
    // Here will be code
} else {
    die('organicResults is empty');
}

Now, let’s create a variable to store the position data.

    $result = array();

Iterate over the organicResults array and find the results that contain the domain in the URL.

    foreach ($data['organicResults'] as $item) {
        if (isset($item['link']) && strpos($item['link'], $searchedDomain) !== false) {
            // Here will be code
        }
    }

Finally, we can store the position, google keyword, domain, and other data in the results variable.

            $result[] = array(
                'position' => $item['position'],
                'domain' => $searchedDomain,
                'keyword'=> $query,
                'link' => $item['link'],
                'title' => $item['title'],
                'displayedLink' => $item['displayedLink'],
                'source' => $item['source'],
                'snippet' => $item['snippet'],
       );

At this step, you have the desired data in the results variable. You can either process it further, display it on the screen, or save it in a convenient format for future use or storage.

Storing and Presenting Results

As search engine ranking data has a certain structure, storing it in a tabular format is very convenient. CSV is one of the most popular formats, supported by most operating systems. Therefore, consider saving the obtained data set to a CSV file step by step.

Set the name of the file with rank data:

    $csvFilePath = 'rank_checker.csv';

Check if the file exists at the current time:

    $fileExists = file_exists($csvFilePath);

Then, open the file to add data to the end of the file. If you want the file to be overwritten each time, use the “w” parameter instead of “a”.

    $file = fopen($csvFilePath, 'a');

Now let’s check if the file is empty or did not exist previously, then set the column headers:

    if (!$fileExists || filesize($csvFilePath) == 0) {
        fputcsv($file, array_keys($result[0]));
    }

Enter the collected data line by line in case the domain name was found in the search results several times:

    foreach ($result as $row) {
        fputcsv($file, $row);
    }

Finally, don’t forget to close the file:

    fclose($file);

To know if the data was saved successfully, you can output a notification to the command line:

    echo 'Data saved to CSV file: ' . $csvFilePath;

The last action is not mandatory, but it allows you to have an idea of the current stage of the script execution. As a result of the execution, you will get a file with similar content:

The CSV file contains the results of a Rank check. The file is updated whenever the script is launched, so you can track the position changes of your keywords over time.

A CSV file with Rank Check results.

As the script is launched, the file’s contents will be updated, and over time, you will be able to have detailed data on the position changes in a convenient format.

Scheduling and Automation

To automate ranking position, you can use the built-in system features. For example, on Windows, this creates a task in the Task Scheduler, and on Linux, it uses Cron. Adding tasks to the Task Scheduler is visual and intuitive, so we will not dwell on it.

Let’s consider how to add PHP Rank Checker to Cron, with a launch frequency of once a day. To do this, you need to know the location of the PHP package and your PHP rank checker.

The crontab -e command opens the cron job configuration file, allowing you to modify the scheduling of tasks. In this case, you will add a new task to run the PHP Rank Checker script daily.

A computer screen displaying the terminal interface with the crontab command.

Then, you need to set a rule for Cron. You can use a task generation service for this. In our case, it will be enough for a daily launch to use @daily.

Now, let’s go to the Cron job configuration file. To do this, type the following command in the terminal:

crontab -e

Then, add a new task line in the form of “frequency location-of-php-package location-of-rank-checker,” for example:

@daily /usr/bin/php /root/php_script/rank.php

After that, save your changes and close the editor. You can later view existing tasks using the following command:

crontab -l

To delete a task from Cron, you can use the same command to launch the editor when you add a new task. Simply delete the necessary line.

Enhancing the Keyword Rank Checker PHP Script

While functional, the previous version of the SERP checker does not save all the data we would like. As you can see from the structure of the returned JSON, we can get a larger number of parameters. Therefore, let’s add to the previous script and save the most useful ones.

SERP Snapshot

One of the most important and useful parameters we receive from the SERP API is the SERP snapshot. In our case, this is a link you can click to see what the search results looked like at the time of the position check. This is very important if you want to know, for example, the top 10 results, who was in first place, and who occupied the positions before and after your resource.

The link to the SERP snapshot is located in the googleHtmlFile attribute, so let’s add some additional parameters to our $results variable:

            $result[] = array(
                'position' => $item['position'],
                'domain' => $searchedDomain,
                'keyword'=> $query,
                'link' => $item['link'],
                'title' => $item['title'],
                'displayedLink' => $item['displayedLink'],
                'source' => $item['source'],
                'snippet' => $item['snippet'],
                'googleUrl' => $data['requestMetadata']['googleUrl'],
                'googleHtmlFile' => $data['requestMetadata']['googleHtmlFile'],
            );

The rest of the code will remain unchanged.

Another useful parameter to include is the date and time. While we can collect data and observe changes over time, we won’t be able to build accurate charts without knowing the specific dates of each check. To address this, let’s add a new parameter to the variable $result:

                'position' => $item['position'],
                'domain' => $searchedDomain,
                'keyword'=> $query,
                'link' => $item['link'],
                'title' => $item['title'],
                'displayedLink' => $item['displayedLink'],
                'source' => $item['source'],
                'snippet' => $item['snippet'],
                'googleUrl' => $data['requestMetadata']['googleUrl'],
                'googleHtmlFile' => $data['requestMetadata']['googleHtmlFile'],
                'date' => date('Y-m-d H:i:s'),

In addition to the search results, you can also access other data from the JSON response, such as People also ask or Related Questions. For example, to get related questions data, you can use the following code:

    $relatedQuestions = array();

    foreach ($data['relatedQuestions'] as $question) {
        $relatedQuestions[] = array(
            'title' => $question['title'],
            'link' => $question['link'],
            'source' => $question['source'],
            'snippet' => $question['snippet'],
        );
    }

Thus, you can customize the format and amount of data you receive from the Google SERP API.

Full Code of Rank Checker

Here you can find the full code of the rank checker on PHP:

<?php
require 'vendor/autoload.php';
use Httpful\Request;

// Set your params
$location = 'Austin,Texas,United States';
$query = 'Coffee';
$filter = 1;
$domain = 'google.com';
$gl = 'us';
$hl = 'en';
$deviceType = 'desktop';

// Set your domain to check
$searchedDomain = 'wikipedia.org';

// Set your api-key
$headers = array(
    'x-api-key' => 'YOUR-API-KEY',
);

$url = sprintf(
    'https://api.hasdata.com/scrape/google?location=%s&q=%s&filter=%d&domain=%s&gl=%s&hl=%s&deviceType=%s',
    rawurlencode($location),
    rawurlencode($query),
    $filter,
    rawurlencode($domain),
    rawurlencode($gl),
    rawurlencode($hl),
    rawurlencode($deviceType)
);

$response = Request::get($url)
    ->addHeaders($headers)
    ->send();
$data = json_decode($response->raw_body, true);

if (!is_array($data) || empty($data)) {
    die('Error with JSON decoding or Empty data');
}

if (isset($data['organicResults']) && is_array($data['organicResults']) && !empty($data['organicResults'])) {
    $result = array();
    foreach ($data['organicResults'] as $item) {
        if (isset($item['link']) && strpos($item['link'], $searchedDomain) !== false) {
            $result[] = array(
                'position' => $item['position'],
                'domain' => $searchedDomain,
                'keyword'=> $query,
                'link' => $item['link'],
                'title' => $item['title'],
                'displayedLink' => $item['displayedLink'],
                'source' => $item['source'],
                'snippet' => $item['snippet'],
                'googleUrl' => $data['requestMetadata']['googleUrl'],
                'googleHtmlFile' => $data['requestMetadata']['googleHtmlFile'],
                'date' => date('Y-m-d H:i:s'),
            );
        }
    }
    $csvFilePath = 'rank_checker.csv';
    $fileExists = file_exists($csvFilePath);

    $file = fopen($csvFilePath, 'a');

    if (!$fileExists || filesize($csvFilePath) == 0) {
        fputcsv($file, array_keys($result[0]));
    }

    foreach ($result as $row) {
        fputcsv($file, $row);
    }

    fclose($file);

    echo 'Data saved to CSV file: ' . $csvFilePath;
} else {
    die('organicResults is empty');
}

?>

Conclusion

In this article, we step-by-step reviewed the process of creating a custom rank checker in PHP using the SERP API. In addition to retrieving the basic parameters, we also discussed how to get and save a request snapshot and how to get the current date and time.

For convenience, we provided the entire script at the end of the article, which can help you better understand the principles of creating a Rank Checker based on the SERP API.

However, as mentioned earlier, the SERP API returns more data than we used in our script. Therefore, by knowing the JSON response structure, you can make your tool flexible and transmit all the data you need.

 

Blog

Might Be Interesting