Building a Twitter client is nothing new to those of us here. We've done it in WCF and Silverlight. To be honest though, using the Twitter API is a great way to exercise two very useful parts of a language and framework - making web requests and parsing XML. That's what we're going to do today. We're going to build a very simple command line twitter client (read-only) using Python.
Today's app will be very simple. It will request Tech.Pro's twitter feed and display them with
their dates. This could be useful in a variety of ways.
Here's what the first five tweets in the output will look like:
Date: Thu Jul 22 19:46:19 +0000 2010 Tweet: VS 2010 Productivity Power Tools Update (with some cool new features) http://sotc.me/46680 via @scottgu #vs2010 #programming Date: Thu Jul 22 17:34:45 +0000 2010 Tweet: SQLite 3.7.0 released http://sotc.me/92864 #sqlite Date: Wed Jul 21 19:08:01 +0000 2010 Tweet: 20+ Required #Windows Apps: Web DesignerGÇÖs Choice http://sotc.me/28662 via @nettuts - I personally love Notepad++ myself! Date: Mon Jul 19 20:20:23 +0000 2010 Tweet: Windows Phone 7 in-depth preview http://sotc.me/58189 via @engadget #wp7 #microsoft Date: Mon Jul 19 17:13:38 +0000 2010 Tweet: Would love to get a hold of Windows Phone 7 device to build a couple applications for it, anyone know how to go about that? #windowsphone7
Python has a very large and powerful framework behind it, so doing simple things like making web requests and parsing XML are fairly straight forward and don't require a lot of code. Let's start by requesting the XML from Twitter's API.
import httplib # Open a connection to twitter.com. twitterConn = httplib.HTTPConnection("www.twitter.com") # Requestion Switch On The Code's tweets. twitterConn.request("GET", "/statuses/user_timeline.xml?screen_name=SwitchOnTheCode") twitterResponse = twitterConn.getresponse() # Check that everything went ok. if twitterResponse.status != 200: print("Failed to request tweets.") # Read the response. tweets = twitterResponse.read() # Close the connection. twitterConn.close()
The first thing we do is create an HTTPConnection object for twitter.com. We then tell it to request the timeline for the user SwitchOnTheCode. Next, we get the response as an HTTPResponse object. I do a quick check to make sure the request went ok, since we all know how often Twitter goes down. All that's left to do is simply read the contents of the response, which will be our XML.
Now we need to parse the XML. There are a couple of available options, but I chose the DOM approach as I think it makes more logical sense.
import httplib from xml.dom.minidom import parseString # Open a connection to twitter.com. twitterConn = httplib.HTTPConnection("www.twitter.com") # Request Switch On The Code's tweets. twitterConn.request("GET", "/statuses/user_timeline.xml?screen_name=SwitchOnTheCode") twitterResponse = twitterConn.getresponse() # Check that everything went ok. if twitterResponse.status != 200: print("Failed to request tweets.") # Read the response. tweets = twitterResponse.read() # Close the connection. twitterConn.close() #Parse the XML. twitterDom = parseString(tweets) # Find all the status tweets. for tweet in twitterDom.getElementsByTagName("status"): for tweetParts in tweet.childNodes: # Find the date tag. if tweetParts.nodeName == "created_at": for textNode in tweetParts.childNodes: # Find the contents of the date tag. if textNode.nodeType == textNode.TEXT_NODE: print("Date: " + textNode.nodeValue) # Find the tweet tag. elif tweetParts.nodeName == "text": for textNode in tweetParts.childNodes: # Find the contents of the tweet tag. if textNode.nodeType == textNode.TEXT_NODE: print("Tweet: " + textNode.nodeValue.encode('utf-8') + "\n")
Using Python's minidom, we first parse the XML returned from Twitter using parseString (don't forget to import parseString at the top of the file). Now things get a litte tricky. We need to rip through the DOM looking for the items we want to display. First off, every tweet is stored beneath a "status" tag, so we need to loop through every one of those. Underneath each status tag there's the date (created_at) and the actual tweet (text), so we need to loop through every child of the status tag looking for those. Once we find one, we then need to find the text contained within it. Text is contained in TEXT_NODE type nodes, so we need to search through the children of our created_at and text tags looking for that specific type. Once we find it, we then print the nodeValue and we're done.
Since tweets are Unicode, I needed to encode the text as utf-8 before printing it to the console.
And that's it. With just a few lines of code, and some pretty complicated DOM traversing, we've got a very basic Twitter reader built in Python.