Friend Carpet
Idee und Motivation
Social Networks erfreuen sich immer größerer Beliebtheit. Je nach Region, Hobbies, Popularität, Beruf oder Karriere kann man das für sich passende Netzwerk auswählen. Dabei komm es häufig vor, dass Freunde oder Bekannte andere Netzwerke bevorzugen als man selbst, was oft dazu führt das man in mehreren Social Networks anmeldet und nicht überall die selben Freunde hat. Bei der Webanwendung "Friend Carpet" geht es zum einen darum eine Brücke zwischen diesen verschiedenen Netzwerken zu schlagen, indem ein virtueller Teppich dessen Flicken Bilder von Freunden aus Netzwerken verschiedener Accounts bestehen. Zum anderen geht es um eine andere Art seine Freundeskreis zu betrachten und spielerisch zu entdecken.
Aufbau
Der Grundlegende Ablauf:
- Login Daten für 1-n Accounts in 1-m Netzwerken abfragen
- es können sich auch mehrere Accounts im selben Netzwerk befinden
- einen Account auswählen und dessen Freunde crawlen
- für jeden ermittelten Freund Profil-Link und Profilbild URL extrahieren
- eventuell Qualität der Bilder anpassen
- Div-Container mit Bild,Link und sonstigen Informationen generieren und ausgeben
- 1-4 solange wiederholen bis alle Accounts abgearbeitet sind
Technologien
- HTML4.1
- PHP (crawlen der Netzwerke und generieren des Teppichs)
- JavaScript (auf Usereingaben zu reagieren)
- Lampp (Apache Webserver mit PHP)
- phpThumb (PHP Library zur Bildmanipulation)
- cURL Unterstützung für PHP(umfangreiche HTTP Anfragen zum crawlen + CookieJar)
Login
Der Nutzer wird begrüßt mit dem "Friend Carpet"-Logo und einer Login Box. Dort kann er für ein bestimmtes Netzwerk(im momment Facebook oder StudiVZ) seine Login-Daten eingeben und per "add"-Button in eine Liste einfügen. Dies kann beliebig oft wiederholt werden um mehrere Accounts und Netzwerke in die Erstellung des Teppichs einfließen zu lassen. Ist der Nutzer zufrieden mit der Zusammenstellung kann er mit "Create Carpet" seinen persöhnlich Teppich erstellen lassen.
Carpet und Interaktion
Der Nutzer kann den direkten Aufbau des Carpets(je nach Internetverbindung nun miterleben). Sollten die Login-Daten nicht korrekt sein, wird der Nutzer darauf hingewiesen, sind in der Liste aber korrekte Daten neben inkorrekten enthalten werden die korrekten trotzdem verarbeitet und angezeigt. Nach dem Aufbau stehen dem Nutzer einige Interaktionsmöglichkeiten zur Verfügung. Bei einem Mouseover über ein Profilbild erhält er zusätzliche Information zur Person(Name, Netzwerk, Account unter dem er gefunden wurde). Bei einen Klick auf ein Pofilbild wird die entsprechende Profilseite des zugehörigen Netzwerkes in einer neuen Browserseite bzw. Tab aufgerufen. Weiterhin ist es möglich die Größe der Profilbilder zu ändern. Die Profilbilder werden auf ein bestimmtes Format "zugeschnitten", was manchmal dazu führt, dass man nicht das komplette Bild sieht, deshalb gibt es die Option das originale Bildverhältnis für alle Bilder anzuzeigen. Weiterhin gibt es ein Suchfeld, welches die Bilder während der Eingabe filtern kann. Der Teppich reduziert sich auf die Profilnamen die Teile der Eingabe enthalten.
Friend Carptet auf mobilen Geräten
Auf mobilen Geräten läuft "Friend Carpet" ohne Probleme. Getestet wurde mit einem Motorola Defy(Display 480x854) und mit dem Emulator aus dem Android SDK. CSS wurde mit @media only screen and (max-device-width: 480px) angepasst. Das Login-Feld sowie der Carpet selbst werden auf komplette Breite des mobilen Geräts angeglichen. Das Einzige was nicht funktioniert ist die Anzeige der Infobox bei einem Mouseover.
Erfahrungen und Fazit
"Friend Carpet" habe ich einigen Leuten vorgeführt und die meisten fanden die Idee cool und haben einige Zeit mit dem erkunden des Carpets verbracht.Ich denke mit vielleicht noch ein paar mehr Features könnte man es so ins Netz stellen. Nur leider wäre das dass Problem mit den Nutzungsbedingungen der Betreiber der sozialen Netzwerke, die i.d.R. verbieten nämlich die automatische Durchsuchung ihrer Seiten. Manche bieten zwar APIs an, aber man ist dann gezwungen deren Interfaces zu benutzen, die nicht unbedingt das tun was man möchte. Einzige Möglichkeit wäre eine Art Lizenz für diese Art der Nutzung zu bekommen, ich fürchte aber so etwas wird sehr teuer oder garnicht erst angeboten. Was mich noch gestört hat, ist dass man an der Uni zwar relativ einfach PHP-Unterstützung bekommt, aber keine speziellen Apache-Module oder Apache-Versionen. So musste ich das Projekt privat hosten, was schade ist, weil ich es gerne als Anregung präsentiert hätte.
Anhang: Crawling Magic
Für interessierte hier einmal wie ich StudiVZ crawle. Facebook funktioniert ziemlich analog, davon findet man auch genug wenn man mal danach googelt. Bei Facebook crawle ich übrigens die Mobile-Version, weil ich kein Javascript unterstützen kann. Es gibt zwar eine Art "noscript-Flag" als GET-Request, nur das funktioniert nicht mehr allzu gut. Außerdem ist die Mobile Seite wesentlich schneller abzufragen.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://secure.studivz.net/Login');
curl_setopt($ch, CURLOPT_POSTFIELDS,'email='.urlencode($login_email).'&password='.urlencode($login_pass).'&ipRestriction=1&login=Einloggen&jsEnabled=true&formkey=156b5e49efad4132cbe29d20939778376b0a44edc7d74fac47862a82338411a65dc24b586321a542bf7f95592a0371913275f9ceb9708e99bff5c0192f70bfaeccd6cd59c304bda62e9cd2a835ff7786a5ac330bc6a74baa9a177ce9ee6f2cad&iv=8419a4452f139ba570dd856be3b1c522');
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, str_replace('\\','/',dirname(__FILE__)).'/sv_cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, str_replace('\\','/',dirname(__FILE__)).'/sv_cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6 (.NET CLR 3.5.30729)");
$html = curl_exec($ch);
$err = 0;
$err = curl_errno($ch);
curl_close($ch);
if ($err == 0){
sleep(2);
//Get Friend Link
$dom = new DOMDocument();
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$links = $xpath->query("/html/body//a[@title='Meine Freunde']");
if(($links->length) > 0) {
$hash = $links->item(0)->getAttribute("href");
preg_match("/\/Friends\/All\/(.*)\/tid\/103/", $hash, $matches);
$hash = $matches[1];
$logout = $xpath->query("//a[text()='Raus hier']");
//get Friends
for ($j = 1; $j < $limit; $j++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.studivz.net/Friends/All/'.$hash.'/p/'.$j);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR, str_replace('\\','/',dirname(__FILE__)).'/sv_cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, str_replace('\\','/',dirname(__FILE__)).'/sv_cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6 (.NET CLR 3.5.30729)");
$html = curl_exec($ch);
curl_close($ch);
//create DOM object
$dom = new DOMDocument();
@$dom->loadHTML($html);
//use xpath to find stuff
$xpath = new DOMXPath($dom);
$imgs = $xpath->query("/html/body//img");
//create img tags
for ($i = 0; $i < $imgs->length; $i++) {
$img = $imgs->item($i);
$img_str = "<img src='../phpthumb/phpThumb.php?src=".substr_replace($img->getAttribute("src"), ".jpg", -6)."&w=170&h=170&zc=1' ";
if(strpos($img_str,"imagevz.net")){
$name = $img->getAttribute("alt");
$profileLink = $img->parentNode->getAttribute("href");
echo "<div class='friend'><a href='http://www.studivz.net".$profileLink."' target=”_blank”>
".$img_str."alt='".$name."'></a>
<div class='friend_txt'>
<p>".$name."<br>StudiVZ<br>".$login_email."</p>
</div>
</div>";
}
}
}
if(($logout->length) > 0){
$logout = $logout->item(0)->getAttribute("href");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.studivz.net'.$logout);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEFILE, str_replace('\\','/',dirname(__FILE__)).'/fb_cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, str_replace('\\','/',dirname(__FILE__)).'/fb_cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6 (.NET CLR 3.5.30729)");
curl_exec($ch);
curl_close($ch);
}
}
else{
//if no links found
echo "<p>Could not find any friends for ".$login_email.", maybe wrong password or email!<p>";
}
}
Das Ausloggen am Ende ist sehr wichtig, andernfalls kann es dazu führen dass bei schnellen wiederholten Anfragen StudiVZ einem Captchas wesentlich schneller aufzwingt und man dadurch nicht richtig angemeldet wird.