Guia: Descarga tus contactos de facebook a Outlook
Cada 4 a seis meses me encuentro con el siguiente problema: 400 contactos en outlook, 500 contactos en Facebook. Dejando de lado la discusión de si son “amigos” o no, yo mas bien me pregunto: quienes son esos extra 100? (o 200, 300?).
De costumbre, me gusta tener todos mis contactos en Outlook, que a su ves se vuelve mi lista de números en el iphone, mac address book y otro sinnúmero de lugares gracias al plaxo sync. Así que amigo o no amigo, igual clasifica como contacto.
De costumbre, y gracias al hecho que facebook no permite hacer descargas de listas a Outlook (o a cualquier cosa ya que va en contra del EULA), por los últimos 2 años me he llevado a la costumbre de planear una noche, mañana o día para que, en viñetas únicas de firefox, cargue cada uno de mis contactos y, con mucho café en mano; me dedico a copiar la información a Outlook, uno a uno. Si ya se, que tedio!.
Hoy decidí hacerle corte a este vicio. De hecho, con los 530-yalgo contactos que encuentro bajo mi perfil de Facebook, estaría viendo unos dos o tres días de labor manual, esta guia explica el como solucione mi problema con un poco de PHP, MySQL y paciencia.
De antemano me disculpo si el articulo cae un poco, técnico. Traten de seguirme la bola. Algún día muy pronto, Facebook y Plaxo harán un import/export tool, pero por ahora, es así o así.
Screen Scraping - Que es?
Primero que todo, no esta bien visto esto del “scraping”. A través de PHP, es la practica de programar un website para que “a mano automatizada” lea otro website (ej: programar una pagina _mía_ que da los precios del NASDAQ en el instante que cargue, leyendolos del código fuente de CNNMoney.com). Y que es lo que pasa con el scraping? no solo anota visitas “falsas” del lado de CNNMoney, sino que trae a luz moderna la vieja practica del “hotlinking”, donde yo en esencia me estoy robando ancho de banda de otros al colgar imágenes en mis paginas, que no estén hospedadas en mi servidor.
Estrategia
Primero lo primero. Para aquellos que no lo tengan bien medido, hay tres (si, tres) portales de facebook (en la plataforma publica). Facebook estandar (en www.facebook.com), Facebook Mobile (en m.facebook.com) y Facebook para iphone (en iphone.facebook.com). Para los curiosos, facebook tambien tiene portales privados (en los casos de compañias que compran facebook corporate -ejemplo: redbull). Para este proyecto voy a explotar la diferencia entre portales, mas importantemente; el hecho que facebook mobile es un mini-facebook en html plano (de minimo uso de ancho de banda), que le da la vuelta al problema que en los otros portales, los llamados de datos son tablas en ajax o flash, para el caso de PHP cURL, es lo que llaman un “showstopper”.
De hecho, los invito a pasarse por m.facebook.com, desde firefox o desde el celular (el portal de iphone tambien sirve!).
El proyecto entonces, gracias a las herramientas disponibles, lo armo del siguiente modo:
- Paso 1: Un levante de información que trae a mi base de datos una lista de todos mis contactos y su identificador privado dentro de Facebook
- Paso 2: Un proceso iterativo que se base en la lista generada en el paso 1, que mire cada pagina de perfil de usuario según el id privado, levante cuanta información pueda de este y la anote a otra tabla en la base de datos
- Paso 3: Un script que deje descargar los datos desde la base de datos en formato vcard (vcf)
Retos y problemas previstos? Uno, y grande. Facebook no presenta las direcciones de email en texto plano sino en ves genera una imagen con el email impreso (trata de hacer copy paste de cualquier email en algun perfil de usuario!). De todos modos, para traer la foto del perfil del usuario existen soluciones simples.
Un poco de codigo
Asi que, manos a la obra.
Paso 1:
Primero voy a generar un script que me deje emular el sistema de login a facebook mobile, para este; voy a explotar el hecho que www.facebook.com (un login por html), envía una variable que genera una redirección. Para aquellos que no saben nada de cURL, aca hay una guia.
Las variables importantes acá son:
curl_setopt($ch, CURLOPT_URL, ‘https://login.facebook.com/login.php?m&next=http%3A%2F%2Fm.facebook.com%2Fhome.php’);curl_setopt($ch, CURLOPT_POSTFIELDS,’email=’.urlencode($login_email).’&pass=’.urlencode($login_pass).’&login=Login’);
Y ojo que también hay que decirle a cURL donde dejar las cookies que entregue Facebook (ojo que el archivo tiene que existir, y debe de tener privilegios de acceso para escritura, osea: chmod 777):
curl_setopt($ch, CURLOPT_COOKIEJAR, “myCookieFile.txt”);
curl_setopt($ch, CURLOPT_COOKIEFILE, “myCookieFile.txt”);
Y una mas, a facebook no le gustan los headers básicos de cURL, asi que toca simular que somos alguien en un browser normal, ya que planeo ejecutar el codigo desde el browser, voy a decirle a cURL que recicle el agente:
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
Va? Nuestro script entero, para hacer login a facebook y traerse el contenido entero al browser entonces es:
//login a fb
$login_email = ‘FACEBOOK@EMAIL.COM’;
$login_pass = ‘PASSWORD’;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ‘https://login.facebook.com/login.php?m&next=http%3A%2F%2Fm.facebook.com%2Fhome.php’);
curl_setopt($ch, CURLOPT_POSTFIELDS,’email=’.urlencode($login_email).’&pass=’.urlencode($login_pass).’&login=Login’);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR, “myCookieFile.txt”);
curl_setopt($ch, CURLOPT_COOKIEFILE, “myCookieFile.txt”);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_exec($ch);
//So what? bueno, ahora hagamos un llamado con cURL!
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, ‘http://m.facebook.com/home.php’);
$page = curl_exec($ch);
print_r($page);
Guarda, abre el script desde firefox (ojo a los permisos del archivo txt de cookies -myCookieFile.txt) y:
Fácil ah? Bueno, ahora lo divertido.
Primero, me dirijo a la pagina que me interesa http://m.facebook.com/friends.php?a, y le digo a cURL que envie todo a una variable $html :
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, “http://m.facebook.com/friends.php?a”);
$page = curl_exec($ch);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$html= curl_exec($ch);
if (!$html) {
echo “<br />cURL error number:” .curl_errno($ch);
echo “<br />cURL error:” . curl_error($ch);
exit;
}
y despues, le digo a PHP que lo traduzca a un DOM…
$dom = new DOMDocument();
@$dom->loadHTML($html);
… se pesque solo los items <a href> (links)…
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate(”/html/body//a”);
… y finalmente, lo pongo en un loop a analizar cada enlace por si solo:
//iteramos …
for ($i = 0; $i < $hrefs->length; $i++) {
$href = $hrefs->item($i);
$profile_url = $href->getAttribute(’href’);
//… filtrando solo los enlaces que lleven a perfiles
if((strpos($profile_url,”/profile.php?id=”) !== false) && strpos($profile_url,”http://m.facebook.com/”) === false){
//… y nos guardamos en la base de datos el nombre del contacto y la URL que apunta al perfil
$profile_name = $href->nodeValue;
storeLink($profile_url,$profile_name);
echo “<br />Profile URL Stored: $profile_name ($profile_url)”;
} //end filter
}//end single page reading
BTW, esa funcion que guarda en la base de datos (storeLink), la arme del siguiente modo (usando ADOdb):
function storeLink($url,$profile_name) {
global $db;
$query = “INSERT INTO fb_profiles_list (profile_url, profile_name) VALUES (’$url’, ‘$profile_name’)”;
$insert = $db->Execute($query);
}
Listos? bueno pues falta. resulta que la pagina que estamos mirando solo muestra 10 records, asi que hay que iterar, segun la cantidad de contactos, la estructura es la siguiente: http://m.facebook.com/friends.php?a&p=$page_counter. Personalmente, tengo el loop estructurado a mano, asi que; como poseo 532 contactos, a 10 contactos por pagina; pues me preparo un loop que cuente 54 pasadas de pagina.
$num_pageflips = 54;
for ($page_counter = 1; $page_counter <= $num_pageflips; $page_counter++) {
…
curl_setopt($ch, CURLOPT_URL, “http://m.facebook.com/friends.php?a&p=$page_counter”);
…
Asi que, nuestro script para el paso 1 (incluyendo el archivo de los cookies), lee asi (Phew!):
<?
/*******************************
* Facebook Downloader (to MySQL)
* Mauricio Pastrana
* http://www.via-the-internet.com
* January 2008
*
* Many Thanks to: Christian Flickinger (http://nexdot.net/blog) and (http://textsnippets.com/posts/show/1204)
* Justin Laing (http://www.merchantos.com/makebeta/php/scraping-links-with-php/)
*
* **DONT RUN BLINDLY, DONT DISTRIBUTE SO FREELY, WATCH OUT FOR LINES 26, 27 and 56
*
*******************************/
//get our database (using ADODB: http://adodb.sourceforge.net/)
require(’includes/database/connection.inc’);
//a function to write to the database
function storeLink($url,$profile_name) {
global $db;
$query = “INSERT INTO fb_profiles_list (profile_url, profile_name) VALUES (’$url’, ‘$profile_name’)”;
$insert = $db->Execute($query);
}
//login to fb
$login_email = ‘FACEBOOK@EMAIL.COM’;
$login_pass = ‘PASSWORD’;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ‘https://login.facebook.com/login.php?m&next=http%3A%2F%2Fm.facebook.com%2Fhome.php’);
curl_setopt($ch, CURLOPT_POSTFIELDS,’email=’.urlencode($login_email).’&pass=’.urlencode($login_pass).’&login=Login’);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR, “myCookieFile.txt”);
curl_setopt($ch, CURLOPT_COOKIEFILE, “myCookieFile.txt”);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_exec($ch);
//need to test this? comment the uncomment this, comment everything else below it and browse to the script, you should get the m.facebook.com home page
/*curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, ‘http://m.facebook.com/home.php’);
$page = curl_exec($ch);
print_r($page);
*/
//ok, we’re in! now head over to friends, if you have more than 10 (most likely), then we will have to iterate
// ok so: I know this can be done on automatic, but it makes the script more readable if you do some manual work (ugh).
// It’s real easy, find out how many friends you have (login, then go to: http://m.facebook.com/friends.php?a), and
// divide the number by 10! Easy, see? now input the number here:
$num_pageflips = 54;
// I have 532 “friends” at the moment, so expect 54 pages of friends and set $num_pageflips = 54
for ($page_counter = 1; $page_counter <= $num_pageflips; $page_counter++) {
//head over to our friend page, note the first page is &p=1
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, “http://m.facebook.com/friends.php?a&p=$page_counter”);
$page = curl_exec($ch);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$html= curl_exec($ch);
if (!$html) {
echo “<br />cURL error number:” .curl_errno($ch);
echo “<br />cURL error:” . curl_error($ch);
exit;
}
// parse the html into a DOMDocument
$dom = new DOMDocument();
@$dom->loadHTML($html);
// grab all the links on the page
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate(”/html/body//a”);
//now iterate through the whole HTML to grab what we need
for ($i = 0; $i < $hrefs->length; $i++) {
$href = $hrefs->item($i);
$profile_url = $href->getAttribute(’href’);
//filter out only the profile links and names!
if((strpos($profile_url,”/profile.php?id=”) !== false) && strpos($profile_url,”http://m.facebook.com/”) === false){
//get the actual person’s name (from the link as well), and store it on the db. also, let me know how it’s going
$profile_name = $href->nodeValue;
storeLink($profile_url,$profile_name);
echo “<br />Profile URL Stored: $profile_name ($profile_url)”;
} //end filter
}//end single page reading
}//end pageflips
?>
Bien ejecutado, este script les debe de dejar una base de datos con un listado de todos los contactos, mas las URL que refieren a su pagina de perfil. Como si no fuera suficiente, aca va el SQL que genera la tabla referente al paso 1:
CREATE TABLE `fb_profiles_list` (
`id` int(11) NOT NULL auto_increment,
`profile_url` varchar(255) default NULL,
`profile_name` varchar(255) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Paso 2:
Bueno, ya tenemos ahora una lista larga de URLs, no? ahora la estrategia es la siguiente. Vamos a iterar y pasar por cada uno de estos URL (usando la estructura del paso 1 para hacer “login”), y de este; leer el HTML que nos de items de interes. Voy a preparar una funcion en PHP que me rebote todo el texto en un string entre un punto de inicio y un final:
// Funcion para extraer algo atrapado entre dos strings definidas por el usuario.
// Ejemplo: $string = “<div style=’blablabla’>texto</div>”
// get_string_between($string,”<div style=’”,”‘>texto”) –> entrega blablabla
//
function get_string_between($string, $start, $end){
$string = ” “.$string;
$ini = strpos($string,$start);
if ($ini == 0) return “”;
$ini += strlen($start);
$len = strpos($string,$end,$ini) - $ini;
return substr($string,$ini,$len);
}
Listo? bueno, ahora esta facil, repito la estructura del script del paso 1, solo que ahora mirando a una pagina de perfil: http://m.facebook.com/profile.php?id=12345&full (y ojo a incluir la variable &full!)
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, “http://m.facebook.com/profile.php?id=”.$profile_id.”&full”);
$page = curl_exec($ch);
y estando adentro del perfil, no es sino identificar que item queremos enviar a la base de datos, generamos una variable que lo archive, y al final hacemos un “mega”llamado a store, ejemplo:
//AIM
$aim = get_string_between($page, ‘AIM: ‘, ‘<br />’);
echo “AIM: “.$aim.”<br />”;
//Yahoo
$yahoo = get_string_between($page, ‘Yahoo: ‘, ‘<br />’);
echo “Yahoo: “.$yahoo.”<br />”;
y al final:
storeProfileData($first_name, $last_name, $website, $aim, $yahoo, $windows_live, $skype, $tel, $current_address, $current_town, $home_town, $birthday, $work_info, $position);
donde:
function storeProfileData($first_name, $last_name, $website, $aim, $yahoo, $windows_live, $skype, $tel, $current_address, $current_town, $home_town, $birthday, $work_info, $position){
global $db;
$query = “INSERT INTO fb_specific_profiles (first_name, last_name, website, aim, yahoo, windows_live, skype, tel, current_address, current_town, home_town, birthday, work_info, position) VALUES (’$first_name’, ‘$last_name’, ‘$website’, ‘$aim’, ‘$yahoo’, ‘$windows_live’, ‘$skype’, ‘$tel’, ‘$current_address’, ‘$current_town’, ‘$home_town’, ‘$birthday’, ‘$work_info’, ‘$position’)”;
$insert = $db->Execute($query);
}
LISTOS! Ahora iteramos por todo el data set del paso 1, para generar el del paso 2!
Ya a estas alturas creo, no hay nadie conmigo. … pero si tuvieron la paciencia, acá esta el script entero de la parte 2:
<?
/*******************************
* Facebook Downloader (to MySQL)
* Mauricio Pastrana
* http://www.via-the-internet.com
* January 2008
*
* Many Thanks to: Christian Flickinger (http://nexdot.net/blog) and (http://textsnippets.com/posts/show/1204)
* Justin Laing (http://www.merchantos.com/makebeta/php/scraping-links-with-php/)
*
* **DONT RUN BLINDLY, DONT DISTRIBUTE SO FREELY, NOTE YOU NEED TO RUN THE FIRST SCRAPER FIRST
*
*******************************/
//get our database (using ADODB: http://adodb.sourceforge.net/)
require(’includes/database/connection.inc’);
//a function to write to the database
function storeProfileData($first_name, $last_name, $website, $aim, $yahoo, $windows_live, $skype, $tel, $current_address, $current_town, $home_town, $birthday, $work_info, $position){
global $db;
$query = “INSERT INTO fb_specific_profiles (first_name, last_name, website, aim, yahoo, windows_live, skype, tel, current_address, current_town, home_town, birthday, work_info, position) VALUES (’$first_name’, ‘$last_name’, ‘$website’, ‘$aim’, ‘$yahoo’, ‘$windows_live’, ‘$skype’, ‘$tel’, ‘$current_address’, ‘$current_town’, ‘$home_town’, ‘$birthday’, ‘$work_info’, ‘$position’)”;
$insert = $db->Execute($query);
}
//a function to get the text between to user defined strings
function get_string_between($string, $start, $end){
$string = ” “.$string;
$ini = strpos($string,$start);
if ($ini == 0) return “”;
$ini += strlen($start);
$len = strpos($string,$end,$ini) - $ini;
return substr($string,$ini,$len);
}
//login to fb
$login_email = ‘FACEBOOK@EMAIL.COM’;
$login_pass = ‘PASSWORD’;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ‘https://login.facebook.com/login.php?m&next=http%3A%2F%2Fm.facebook.com%2Fhome.php’);
curl_setopt($ch, CURLOPT_POSTFIELDS,’email=’.urlencode($login_email).’&pass=’.urlencode($login_pass).’&login=Login’);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR, “myCookieFile.txt”);
curl_setopt($ch, CURLOPT_COOKIEFILE, “myCookieFile.txt”);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_exec($ch);
//need to test this? comment the uncomment this, comment everything else below it and browse to the script, you should get the m.facebook.com home page
/*curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, ‘http://m.facebook.com/home.php’);
$page = curl_exec($ch);
print_r($page);
*/
//ok, we’re in! now head over to each specific profile page, we’re going to have to loop through the whole dataset and use a LOT of substring magic
//first, we find out where we are as far as id’s in the db (if you’re lucky, yours starts at 1, i did some testing, so my first profile begins at id=127!)
echo “profiles found in db: “.$num_profiles = $db->GetOne(”SELECT COUNT(*) FROM fb_profiles_list”).”<br />”;
echo “first profile id: “.$first_profile_id = $db->GetOne(”SELECT id FROM fb_profiles_list”).”<br />”;
for ($profile_counter = 0; $profile_counter < $num_profiles; $profile_counter++) {
//be a little verbose
echo $profile_counter.”<br /><br />”;
$profile_id = get_string_between($db->GetOne(”SELECT profile_url FROM fb_profiles_list WHERE id=”.($first_profile_id+$profile_counter)), ‘/profile.php?id=’, ‘&r’);
echo “Now Trying: ” .
$db->GetOne(”SELECT profile_name FROM fb_profiles_list WHERE id=”.($first_profile_id+$profile_counter)) . //profile_name
” (” . $profile_id . “) <br />”; // profile_id
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, “http://m.facebook.com/profile.php?id=”.$profile_id.”&full”);
$page = curl_exec($ch);
//print_r($page);
//Name
$name = explode(” “,get_string_between($page, ‘<title>Facebook | ‘, ‘\’s Profile</title>’));
$first_name = $name[0];
$last_name = $name[1];
echo “First Name :$first_name <br />”;
echo “Last Name :$last_name <br />”;
//Website
$website = get_string_between($page, ‘Website: <a href=”‘, ‘?refid=17″>’);
echo “Website: “.$website.”<br />”;
//AIM
$aim = get_string_between($page, ‘AIM: ‘, ‘<br />’);
echo “AIM: “.$aim.”<br />”;
//Yahoo
$yahoo = get_string_between($page, ‘Yahoo: ‘, ‘<br />’);
echo “Yahoo: “.$yahoo.”<br />”;
//Windows Live
$windows_live = get_string_between($page, ‘Windows Live: ‘, ‘<br />’);
echo “Windows Live: “.$windows_live.”<br />”;
//Skype
$skype = get_string_between($page, ‘Skype: ‘, ‘<br />’);
echo “Skype: “.$skype.”<br />”;
//Tel
$tel = get_string_between($page, ‘<a href=”tel:’, ‘”>’);
echo “Tel: “.$tel.”<br />”;
//Current Address
$current_address = get_string_between($page, ‘Current Address: ‘, ‘<br />’);
echo “Current Address: “.$current_address.”<br />”;
//Current Town
$current_town = get_string_between($page, ‘Current Town: ‘, ‘<br />’);
echo “Current Town: “.$current_town.”<br />”;
//Home Town
$home_town = get_string_between($page, ‘Hometown: ‘, ‘<br />’);
echo “Home Town: “.$home_town.”<br />”;
//Birthday
$birthday = get_string_between($page, ‘Birthday: ‘, ‘<br />’);
echo “Birthday: “.$birthday.”<br />”;
//Work Info
$work_info = get_string_between($page, ‘Company: ‘, ‘<br />’);
echo “Work Info: “.$work_info.”<br />”;
//Position
$position = get_string_between($page, ‘Position: ‘, ‘<br />’);
echo “Position: “.$position.”<br />”;
storeProfileData($first_name, $last_name, $website, $aim, $yahoo, $windows_live, $skype, $tel, $current_address, $current_town, $home_town, $birthday, $work_info, $position);
echo “<hr>”;
}//end pageflips
?>
Ojo con Facebook!
Tengan cuidado, hay que tener en cuenta que cuando llaman este script, lo hacen desde su propia cuenta de FaceBook. Si hacen algo muy dañino (como, golpear los servidores con miles de hits de una sentada), los pueden rastrear! Ya hay mas de un caso donde Facebook tumba scripts de usuarios propagando otros “facebook downloaders.
Acá de paso dejo los archivos fuente que use, ojo a los comentarios; ahí les incluyo el paso 3, que es un script extra para extraer la informacion de la base de datos a vcards (que lee outlook). Otra sugerencia? Busquense algun app de facebook que coordine las fotos de los contactos online con las offline. Y estamos!
Tiempo total de desarrollo: 20 horas-hombre. Wow! Que lastima no poder hacer un servicio web fuera de este.




May 10th, 2008 a las 11:19 am
tengo problemas con mi facebook ,ha sido desactivada mi cuenta por un administrador del facebook y me eliminaron totalmente ,nose cual fue elmotivo de mi suspension,pero necesito que me ayuden a recuperar mi perfil ,mis amigos , mis fotos y mi cuenta ,estoy en Venezuela y mi nombre es salvatore schiera ,muchas gracias y ayudenme
May 14th, 2008 a las 5:48 am
Muchas gracias Mauricio por el script!!!
Me has ahorrado hacerlo yo mismo