In the last part of this series, we looked at how web pages are loaded into the browser, and how the content that is downloaded (HTML & CSS) is designed for humans to understand, primarily visually.
We also discussed that for a machine, parsing (or understanding) this content works differently.
Instead of using a medium that's designed to organise information visually, for the machine we need a medium that organises information semantically.
In computer science, "semantics" refers to meaning.
When data is organised semantically, every single piece of information is explicitly labeled with what it is, rather than how it should look.
A machine doesn't have to infer that a number is a price because it is big and red; the data is explicitly self-describing:
"price": 12.99
What could be more clear than that? To a computer, not much! That's why we use this kind of format.
The above code snippet is written in JSON.
JSON (pronounced JAY-sawn) stands for JavaScript Object Notation. What's important for our purposes, is how JSON is organised (or formatted).
This is actually a very common pattern in computer science: key/value pairs.
"key": "value"
The computer will look for a specific key, and when it finds it, will access the related value.
Let's take a look at another example, this time from one of our APIs. Note: this example has been simplified for brevity:
{
"organic_results":[
{
"position":1,
"title":"Les Paul Electric Guitars",
"link":"https://www.gibson.com/en-gb/collections/gibson-les-paul-electric-guitars"
},
{
"position":2,
"title":"Gibson Les Paul",
"link":"https://en.wikipedia.org/wiki/Gibson_Les_Paul"
},
{
"position":3,
"title":"Gibson Les Paul | Over 700 To Choose From",
"link":"https://www.guitarguitar.co.uk/gibson/les-paul/"
}
]
}That might look a bit intimidating, but really there are only three little symbols we need to be aware of in order to use JSON to its full potential:
- Colons
: - Curly brackets/braces
{} - Square brackets/braces
[](optional)
Let's take a look at each of these in order!
Colons (:)
A colon splits a line of JSON into two very strict zones: the Key (on the left) and the Value (on the right).
"coffee_type" : "Espresso"
- Left of the colon: The Key (the unique label, always in quotation marks). It answers the question: "What is this piece of information?"
- Right of the colon: The Value (the actual data). It answers the question: "What is the answer/content?"
JSON isn't a programming language that does things; it's a data format that just holds things. The colon was chosen because it represents a relationship, not an action. It's just like writing a grocery list:
- Apples: 4
- Milk: 1 pint
- Coffee Beans: 2 bags
Curly Brackets/Braces ({})
Curly brackets/braces (I prefer the latter so let's go with those) come in matching pairs.
The opening brace looks like { and signals the beginning of a JSON Object. The closing brace } signifies the end of the object.
While the concept of a JSON Object might seem a little overwhelming, in reality all it means, is between these curly braces, there might be a collection of key/value pairs (each separated by a comma).
Let's take a look at an example.
A JSON object with 3 key/value pairs:
{
"name": "Java Junction",
"type": "Coffee Shop",
"is_open": true
}
In the above we have a JSON object with 3 key/value pairs:
name- gives us the name of a businesstype- provides information on the type of businessis_open- tells us if the business is currently open to the public
(Sidenote): Accessing JSON values:
Let's take a look at how this might be used in a program. Programmers use something called variables which are essentially labels, to store and organise parts of a program.
If it helps, you can think of it as a "labelled box" for now.
So let's say we stored the above JSON object in a variable (box) called result - the process of storing this would look like this:
result = {
"name": "Java Junction",
"type": "Coffee Shop",
"is_open": true
}
The = sign means "put the stuff on the right of = into the result variable".
Now we have a "box" called result which contains:
{ "name": "Java Junction", "type": "Coffee Shop", "is_open": true }
(It's on a single line to save space - from the computer's perspective it's all the same, we just break it over multiple lines to make it easier for us to read.)
Let's say we want to go into the result box and get the value associated with the name key of the JSON (which should be: "Java Junction").
We can do this by referencing the JSON (using the name of the variable: result) and writing the key right after. Note: we will need to use a "dot" or "period" (.) between so that the computer understands we mean two separate things - the variable/box name, and the key:
result.name
If we ran the above line, we should get:
"Java Junction"
Success! Now, our JSON object (which currently lives inside of result) has 3 keys. We've already accessed name, so what if we wanted to use type?
result.type
This should output:
"Coffee Shop"
How do you think you would get the value for is_open? Give it a try!
Square Brackets/Braces ([])
The last aspect of JSON we need to cover before we look at a real-world example from SerpApi, is the square braces.
These work in a similar way to curly braces, but where curly braces have a collection of key/value pairs separated by commas, square brackets are reserved for holding lists of items (which, in our case, will be a collection of JSON objects), separated by commas:
[
{ "person_name": "Alex", "nationality": "American"},
{ "person_name": "Agata", "nationality": "Polish"},
{ "person_name": "Andy", "nationality": "British"}
]
In the above, we can see that in-between the '['and']', we have 3 entire JSON objects.
This gives JSON a lot of power structurally to contain collections of similar things. For example, a search engine results page might have multiple organic results - all with a title, link and a number to show their ranking position.
Let's revisit our previous example:
{
"organic_results":[
{
"position":1,
"title":"Les Paul Electric Guitars",
"link":"https://www.gibson.com/en-gb/collections/gibson-les-paul-electric-guitars"
},
{
"position":2,
"title":"Gibson Les Paul",
"link":"https://en.wikipedia.org/wiki/Gibson_Les_Paul"
},
{
"position":3,
"title":"Gibson Les Paul | Over 700 To Choose From",
"link":"https://www.guitarguitar.co.uk/gibson/les-paul/"
}
]
}Now we've discussed that curly braces contain JSON objects, we can see that the first thing we see is actually one large JSON object:
{ "organic_results":[] }
So in this example, the square braces are actually the value associated with the key organic_results!
Using our previous technique of putting the JSON into a variable to access parts of it, let's see what happens when we want to access the key organic_results.
First let's assign the JSON to a new variable, called more_results:
more_results = {
"organic_results":[
{
"position":1,
"title":"Les Paul Electric Guitars",
"link":"https://www.gibson.com/en-gb/collections/gibson-les-paul-electric-guitars"
},
{
"position":2,
"title":"Gibson Les Paul",
"link":"https://en.wikipedia.org/wiki/Gibson_Les_Paul"
},
{
"position":3,
"title":"Gibson Les Paul | Over 700 To Choose From",
"link":"https://www.guitarguitar.co.uk/gibson/les-paul/"
}
]
}Now we can do the following:
more_results.organic_results
Now in the previous examples, the value of each key/value pair was simply some text. But in this case, our value is actually a much more complex structure of data! So the above line would return:
[
{
"position":1,
"title":"Les Paul Electric Guitars",
"link":"https://www.gibson.com/en-gb/collections/gibson-les-paul-electric-guitars"
},
{
"position":2,
"title":"Gibson Les Paul",
"link":"https://en.wikipedia.org/wiki/Gibson_Les_Paul"
},
{
"position":3,
"title":"Gibson Les Paul | Over 700 To Choose From",
"link":"https://www.guitarguitar.co.uk/gibson/les-paul/"
}
]But what if we just wanted the first object - the one with a position value of 1?
Well the cool thing about these square brackets, is that the order of the JSON objects inside them stays the same. So if you say: "give me the first object", it will always be the same one.
So this means that inside the square brackets, items have a position, or index.
With this information, we can ask for a specific position to get one specific result:
more_results.organic_results[1]
Which would return:
{
position: 2,
title: "Gibson Les Paul",
link: "https://en.wikipedia.org/wiki/Gibson_Les_Paul"
}
But wait—why did we get the second position when we asked for organic_results[1]?
In programming, we start counting from 0 instead of 1. The easiest way to think about this is like an elevator:
- The very first item is on the Ground Floor (Floor 0) because you have traveled zero floors up from the entrance.
- The second item is on Floor 1 because it is exactly one step away from the start.
So, in our code, the number in the brackets [ ] is actually telling the computer: "How many items should I skip from the very beginning?"
[0]= Skip zero items (Gives you the 1st result).[1]= Skip one item (Gives you the 2nd result).
So to get the first result, we need to revise the command:
more_results.organic_results[0]
which results in:
{
"position":1,
"title":"Les Paul Electric Guitars",
"link":"https://www.gibson.com/en-gb/collections/gibson-les-paul-electric-guitars"
}If we wanted to just isolate the position part of that object, then we could tack it on to the end, like so:
more_results.organic_results[0].position
Which would result in:
1
And that's all the important stuff!
Sure, there are finer points - such as the possibility of encountering empty {} or [], and nested objects within objects.
But while you might wonder why this is even possible, in the real world, APIs use empty braces as placeholders for information that could exist, but doesn't have any data yet.
And when it comes to the nested objects, you already have all the tools you need to work with those.
Join us in the next part of the series, where we will look at taking a HTML/CSS/JavaScript front end, and have it consume JSON from a pre-existing API!
Until then, if you have any questions about this article, please feel free to reach out to roi@serpapi.com - see you next time!