It occurred to me yesterday that I better have a list of the names of all my friends who like the CyberPlus Facebook Page. I was surprised that Facebook did not have any provision of allowing me to download it. The next option for people like us is to do some hacking, given the fact that it should be logically possible, albeit indirectly. What’s the use of programming skills if you can’t use it to conquer problems? 😉
So these are the steps I took:
1.Clicked on “Likes” in the CyberPlus Facebook Page. It showed 3 rows of photos of friends who like CyberPlus and “Show all 240”. Clicked on “Show All 240”.
2. Obtained the HTML source of the web page. Searched for “Friends Who Like CyberPlus”, because the photos were immediately after that.
3. Saw that the name of the first person was “Abdul Ahmed” and the last person was “Visweswara Reddy”. Copied everything between these two.
4. Observed that each person was listed with the following code:
<li><a data-hover="tooltip" aria-label="Abdul Ahmed" class="link" href="https://www.facebook.com/tausif.ahmed.5648" data-jsid="anchor"> <img src="https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/t1.0-1/c0.11.50.50/p50x50/1493206_10203154221643913_464314181_t.jpg" alt="Abdul Ahmed" data-jsid="img" /> </a></li>
5. Realised that the name of the person is present in the “aria-label” and “alt” attributes, and the profile ID is also present, if required.
6. Took everything from <ul> to </ul> and saved it as an XML file. Opened the file in the browser to verify that it is indeed well-formed and contains details of all people. It did!
7. Now the next step would be to extract details from an XML file – which should be simple. This is where there is a wide wide gap between Perl and Java. In Java, we would have to deal with SAX or DOM, import packages, define classes, implement interfaces, add listeners, handle exceptions, override methods, create objects, and what not! Wrote a Perl script like this:
while (my $line = <>) { while ($line =~ /label=\"([^\"]*)"/g) { print $1,"\n"; } }
8. Job over! This printed out all the names!
That’s why I love Perl! And hate Java!
Oh, of course your Java code will be far more readable, but hey, I just wanted to do a small simple thing!
9. And then I did what I do after I get some free time after Perl coding: reduce the code! This is the next version:
print $1,"\n" while (/label=\"([^\"]*)"/g)
And ran it like this:
perl -n likes.pl < likes.xml > likes.txt
(where likes.pl contained the above Perl code, likes.xml was the html file from <ul> to </ul> and likes.txt was the target file that would eventually contain the names of all friends who like CyberPlus)
So then I thought, just to prove the point, why not write a Java program to do the same? Here it is:
import javax.xml.parsers.*; import org.xml.sax.*; import org.xml.sax.helpers.*; import java.io.*; public class Likes extends DefaultHandler { public static void main(String args[]) throws ParserConfigurationException, SAXException, IOException { new Likes(new File(args[0])); } public Likes(File f) throws ParserConfigurationException, SAXException, IOException { SAXParserFactory.newInstance().newSAXParser().parse(f, this); } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals("a")) { System.out.println(attributes.getValue("aria-label")); } } }
Java supporters would be very angry with this comparison now! I totally agree that Java is a far more organised programming language that prevents programmers from going wrong. I also admit that Perl code is highly un-maintainable. But hey, 1 small line of Perl code here is equivalent to 20+ long lines of Java code! I rest the case!
Oh, and in the process, I did find something else interesting about facebook. But more on that in a separate post!