#1 Posted by papuccino1 (311 posts) -

Has anyone used this in Python 3?
 
Just a simple tutorial that shows me how to download all information for the game Super Mario World for instance. Thank you!

#2 Posted by LtSquigs (253 posts) -

Ok, I am not great at giving tutorials but I'll attempt to explain a way to do it.
The first thing you need to do is get a python module that can be used to parse xml. I suggest lxml:  http://codespeak.net/lxml/index.html
There is a pretty good tutorial on how to use lxml on the site, but I will go over some of the things that are specified there in this post too.
 I assume you have read the instructions that explain how to access the API through HTTP requests, so I won't go over that here. If you haven't read it yet here's the url to it:  http://api.giantbomb.com/documentation/
 
So to explain by example, let's take the case where you want information on Super Mario World.  Super Mario World is a game, so we will most likely find its information in a game resource in the API. If you look at the game resource in the API documentation you may notice that there are a ton of things associated with the game, most of which we probably don't want, so let's restrict our request to only give us the information that we actually want. Let's say we only want the characters, concepts, and the description of the game. Finally, the last piece of information we need is the ID of the Super Mario World resource, to be honest I'm not entirely sure of a good way to quickly get the ID, I got the ID of Super Mario World by looking at the url for the page on the actual Giantbomb site, which had the ID 1334 in it, which turned out to be right. So now we have all the information we need to do a search in the api:
 
API Key: 123456789 (Just made this up, replace this with your own)
Resource Type: Game
Detail or List Resource?: Detail
Object ID: 1334
Parts of the resource we are interested in: Characters, Concepts, Description
 
From this we get the following url to query to get the XML information we want:
http://api.giantbomb.com/game/1334/?api_key123456789&format=xml&field_list=characters,concepts,description
 
Now the question becomes how do we parse this into something python can use? Luckily the lxml module gives us a way to directly parse this page from python, using the etree parse method. 
The first thing we must do is import the etree object from the lxml package, and then construct an etree from the api request:

  # First we import the etree object from lxml
  from lxml import etree
 
  # Then we parse the api request into an etree object, in real code this string probably wouldn't be hard coded
  request = etree.parse("http://api.giantbomb.com/game/1334/?api_key123456789&format=xml&field_list=characters,concepts,description")

After getting the file into an etree object, the first thing we should check is if the query even managed to succeed. The giantbomb API always puts a tag into the request called "error" that contains information on whether or not the request succeeded, and if not what went wrong. If it did succeed it will contain the string "OK", which we should check for.

 So how do we check for this using the etree? The etree object exposes a method called find. It takes a string, and finds the first tag that matches that string. So using the find method we search for the error tag. Then after we get the tag, etree allows us to access the text included in the tag by using the text attribute of the tag:
 
  # We grab the error tag from the etree 
  errortag = request.find("error")
  # Then we check against "OK" to see if it succeeded, you can also check the other error codes for better error handling
  if errortag.text != "OK" :
      exit(1) # If this was a function you could just return with an error code.
             
So now that we've checked the error tag, we want to extract the information we were looking for. The first thing we will extract is the "description" tag. This is because the description tag is really simple. The text of the tag simply contains the description we are looking for. We can do this in a similar way to how we extracted the error tag, but not quite the same. The "description" tag is actually a child tag of the "results" tag (you can see this if you look at the XML file in an internet browser). So first we have to grab the "results" tag, and then we can grab the "description" tag:
   # First we have to grab the results tag, we will use this later to grab other tags so we want to keep it around
   resultsTag = request.find("results")
   # Now using the results tag we can grab the description tag
   descriptionTag = resultsTag.find("description")
   # Store the text to be used later
   descriptionText = descriptionTag.text

 The hard part is extracting the information on the characters and concepts. The characters tag actually contains a subtag for each character associated with the game (you can see this if you just go to the XML file in an internet browser). Each character in turn contains several subtags of information (described by the character object in the API). So for simplicity in the case of characters, lets say we are simply interested in the name of every character in the game. The first thing we do is extract the "characters" tag, we  can do this by extracting it from the "results" tag just like the "description" tag like before. Then we want to extract all of the "character" tags from the "characters" tag, and all of the "name" tags from the "character" tags. Luckily lxml provides an easy way to do this, using the findall method. The findall method finds all tags that match a string, and returns an iterable list of those tags. So in this case the following code will do what we want:
   # Using the resultTag from earlier we grab the characters tag
   charactersTag = resultsTag.find("characters")
   # We create a list to contain all the character names   
   characterNames = list()
   # Now we want to iterate through all the character tags that are subtags of characters
   for character in charactersTag.findall("character"): 
          # We extract the name subtag, and the text in the name field
          characterNames.append(character.find("name").text)     

Simalarly extracting information about concepts is easy too, assuming we also just want to extract the "name" information about the concept:
  # Once again using the resultsTag from earlier we grab the concepts tag this time
  conceptsTag = resultsTag.find("concepts")
  # We create a list to contain the concept names
  conceptNames  = list()
  # We iterate through all the concept tags that are subtags of concpets
  for concept in conceptsTag.findall("concept"):
         # We extract the name subtag, and the text in the subtag
         conceptNames.append(concept.find("name").text)

And with that we have extracted the information that we wanted to out of the Super Mario World game.  Of course if you wanted more information from the Super Mario World database entry all you have to do is extract more tags, and change the field_list filter that is in the url.
 
Hopefully this example will help you out.