Wednesday, November 05, 2014

Web scrapping con Go y PhatomJS

Hace algún tiempo escribí un blog llamado Web scrapping con Julia y PhantomJS...luego escribí otro blog llamado Web scrapping con Haskell y PhantomJS...

Ahora...es el turno de Go's -;)

El concepto es el mismo...creamos un script en PhantomJS que va a leer la página de Twitter de un usuario y obtener los hashtags de las primeras 5 páginas...aquí está el script en PhantomJS...

Hashtags.js
var system = require('system');

var webpage = require('webpage').create();
webpage.viewportSize = { width: 1280, height: 800 };
webpage.scrollPosition = { top: 0, left: 0 };

var userid = system.args[1];
var profileUrl = "http://www.twitter.com/" + userid;

webpage.open(profileUrl, function(status) {
 if (status === 'fail') {
  console.error('webpage did not open successfully');
  phantom.exit(1);
 }
 var i = 0,
 top,
 queryFn = function() {
  return document.body.scrollHeight;
 };
 setInterval(function() {
  top = webpage.evaluate(queryFn);
  i++;
   
  webpage.scrollPosition = { top: top + 1, left: 0 };

  if (i >= 5) {
   var twitter = webpage.evaluate(function () {
    var twitter = [];
    forEach = Array.prototype.forEach;
    var tweets = document.querySelectorAll('[data-query-source="hashtag_click"]');
    forEach.call(tweets, function(el) {
     twitter.push(el.innerText);
    });
    return twitter;
   });

   twitter.forEach(function(t) {
    console.log(t);
   });

   phantom.exit();
  }
}, 3000);
});

Si ejecutamos el script vamos a ver el siguiente resultado...


Ahora...lo que quiero hacer con esta información...es enviarla a Go...y obtener los hashtags más usados...así que los voy a sumarizar y luego deshacerme de los que no se repiten al menos 5 veces...

Veamos el código en Go...

TwitterHashtags.go
package main

import ( "os/exec"
  "strings" 
  "fmt" )

func main() {
 cmd := exec.Command("phantomjs","--ssl-protocol=any","Hashtags.js", "Blag")
 out, err := cmd.Output()
 if err != nil {
  println(err.Error())
  return
 }
 
 Tweets := strings.Split(string(out), "\n")
 charmap := make(map[string]int)
 for _, value := range Tweets {
  if value != "" {
   charmap[value] += 1
  }
 }
 
 for key, value := range charmap {
  if value >= 5 {
   fmt.Print("(", key, ", ")
   fmt.Println(value, ")")
  }
 }
}

El único problema con este script es que no hay una manera simple y sencilla de ordenar un map[string]int...así que simplemente lo dejo ahí -:)

Aquí está el resultado...


Si alguien conoce alguna manera simple de ordenar esto...por favor avisenme -:)

Saludos,

Blag.
Development Culture.

No comments: