Permalänk
Medlem

Facebook-API

Hallå!

Har funnits några apps på Facebook för att hålla reda på när folk unfriendar en men de har tagits bort, misstänker att Facebook inte riktigt vill att såna ska finnas. Hade därför planer på att skapa ett lokalt PHP-skript som hämtar ens vänner, lägger in det i en databas, kollar om en vän i nuvarande vännerslistan inte finns i databasen -> ny vän, och ifall någon vän i databasen inte finns i den nuvarande vännerslistan -> unfriended.

Problemet är att man måste ha en APP ID och APP SECRET, alltså måste man registrera en ny app på Facebook.
Får man göra det ifall man endast vill ha det för privat/lokal utveckling som man inte vill ge ut publikt?

Finns det något sätt att få hem ens vännerslista UTAN att behöva ha en app registrerad? T.ex. om det finns någon publik allmän app id man kan använda eller om det går att göra utan Facebook-API'n?

Delar gärna med mig av skriptet sen för er som också vill hålla reda på vilka vänner som tagits bort eller lagts till i din vännerslista.

Permalänk
Medlem

Jag har en del fb-script, fast när jag gjorde dessa hade inte api:t de funktioner jag ville ha (har nog inte det än heller). Det jag gjorde istälelt var att parsa mobilsidan och göra det jag ville. Jag gjorde det dock i python, med det fungerar ju utmärkt i php också.
Det fungerar ju helt klart sämre än api-funktionerna, men det är alltid en sista lösning.

Visa signatur

citera!

Permalänk
Medlem
Skrivet av Dosshell:

Jag har en del fb-script, fast när jag gjorde dessa hade inte api:t de funktioner jag ville ha (har nog inte det än heller). Det jag gjorde istälelt var att parsa mobilsidan och göra det jag ville. Jag gjorde det dock i python, med det fungerar ju utmärkt i php också.
Det fungerar ju helt klart sämre än api-funktionerna, men det är alltid en sista lösning.

Har funderat på det också men hur får jag en sida som listar ALLA vänner? Såvitt jag vet så listar den bara i intervaller. Går ju iofs också bara att man får det tusen gånger jobbigare. Ska kolla upp det.

Vore trevligt dock med en "guest" API-key.

Permalänk
Inaktiv

Använd php simple html parser för att hämta vännerna. Jag vet dock inte hur man får fram alla vänner, men man kan ju bjuda in alla vänner via något javascript, kan vara värt att kolla upp hur det scriptet sköter facebooks "pagination".

Edit: om du gör ett script kan du väl publicera det här? Eller skicka ett pm, för jag vill gjärna testa det!

Permalänk
Medlem
Skrivet av anon133239:

Använd php simplehtml parsercför att hämta vännerna. Jag vet dock inte hur man får fram alla vänner, men man kan ju bjuda in alla vänner via något javascript, kan vara värt att kolla upp hur det scriptet sköter facebooks "pagination".

Edit: om du gör ett script kan du väl publicera det här? Eller skicka ett pm, för jag vill gjärna testa det!

Ska kolla upp det där!
Vad menar du med "bjuda in"? Vill inte bjuda in några. Vill enbart hämta de personer jag redan har som vänner.

Och som jag skrev i första posten så tänkte jag lägga upp skriptet här om jag får det att funka!

Permalänk
Inaktiv
Skrivet av Tanax:

Ska kolla upp det där!
Vad menar du med "bjuda in"? Vill inte bjuda in några. Vill enbart hämta de personer jag redan har som vänner.

Och som jag skrev i första posten så tänkte jag lägga upp skriptet här om jag får det att funka!

Detjag menade var att det finns ett script som väljer alla dina vänner nät du t.ex. Bjuder in dina vänner till bågot event. I javascript tror jag. Du borde kunna använda bitar av det för att välja alla dina vänner. Det var så jag tänkte

Permalänk
Medlem

Har gjort några framsteg vad gäller skriptet!
Ett problem jag stötte på när jag använde cURL från localhost var att den inte verkade känna av att jag redan var inloggad så den returnerade bara en inloggningssida. Nu funkar det så att den loggar in och redirectar till http://www.facebook.com/friends/?everyone&ref=tn. Tyvärr verkar den inte lista alla vänner utan enbart "Recently Interacted".

Någon som vet hur man kan få cURL att selektera någonting från en dropdown-lista?

Sen behöver jag all hjälp jag kan få med regex. Än så länge har jag:

preg_match_all( '@profile\.php\?id\=(.*?)\">(.*?)<@i', $line, $matches );

men det ger lite konstiga resultat. Vore schysst om någon kunde gå igenom ifall den stämmer?
Sen undrar jag också hur man kan få den att matcha mot alla ID'n _FÖRUTOM_ ett förbestämt ID med hjälp av regex?

Permalänk
Medlem

Tanax, vad gör du nu? Jag hoppas verkligen inte att du använder regexp för att parsa html? Använd t.ex. simple_html_dom istället.

Visa signatur

citera!

Permalänk
Inaktiv

Gör det inte med regex, mycket lättare och framtidssäkrare med simple html dom, http://simplehtmldom.sourceforge.net/

Jag vet inte riktigt hur facebooks källkod ser ut, men om du postar källkoden till dina vänner-sidan så kan jag kanske hjälpa dig lite.

Edit: såg nu att alla vänner inte listas på en sida. De visas genom en så kallad "pagination". Det verkar intesom det görs via urlen, men den kanske skrivs om. Kopiera hela källkoden, och ändranamn och annat känsligt så jag har någotatt suga på.

Permalänk
Medlem

Använder regex för att matcha de länkar på sidan så att dom verkligen är profile-links.
Men jag kollade upp simple_html_dom. Såg väldigt nice ut så jag använder det nu istället.

$html = file_get_html("example.html"); $count = 0; $found = 0; foreach( $html->find('a') as $link ) { $count++; // Check if it's a profile-link, if it's not the same as currently logged in user and make sure it's not an image if( strpos( $link, 'profile.php?id=' ) && !strpos( $link, $user_id ) && !strpos( $link->innertext, 'img' ) ) { $found++; echo 'Link #' . $found . ': ' . $link->innertext; echo '<br />'; } } echo $count . ' links found where ' . $found . ' links matched profile-links';

Skriver ut alla namnen helt perfekt!

Dock fortfarande problemet med att den bara får fram de namn som är "Recently Interacted". Källkoden är lång. Du får PHP-skriptet som det ser ut än så länge så kan du prova själv. Kom ihåg att 1) tanka ner simple_html_dom.php, 2) skapa example.html(kan vara tom) och 3) skapa cookie.txt som också kan vara tom.

<?php include_once('simple_html_dom.php'); $user_id = ''; $user_email = ""; $user_pass = ""; $fp = fopen("example.html", "w"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://login.facebook.com/login.php?&next=http://www.faceboo...'); curl_setopt($ch, CURLOPT_POSTFIELDS,'email='.urlencode($user_email).'&pass='.urlencode($user_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, "cookie.txt"); curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3"); curl_exec($ch); // So we can view the facebook-page include('example.html'); $html = file_get_html("example.html"); $count = 0; $found = 0; foreach( $html->find('a') as $link ) { $count++; if( strpos( $link, 'profile.php?id=' ) && !strpos( $link, $user_id ) && !strpos( $link->innertext, 'img' ) ) { $found++; echo 'Link #' . $found . ': ' . $link->innertext; echo '<br />'; } } echo $count . ' links found where ' . $found . ' links matched profile-links';

Permalänk
Inaktiv

Ok, ska kolla på det när jag sitter vid min dator, tyvärr om c:a 10 dagar...

Permalänk
Medlem
Skrivet av anon133239:

Ok, ska kolla på det när jag sitter vid min dator, tyvärr om c:a 10 dagar...

Lugnt! Ingen brådska

Permalänk
Medlem

Slängde ihop ett strax efter min förra post, men då jag precis hade varit ute när jag gjorde det föll det liksom lite i glömska... såg nu att jag inte kör urlencode() o.s.v. så ta det för vad det är.
Tada: http://pastebin.com/ABW5kTg7
Den dumpar till en fil för att kunna spara skillnaderna.
EDIT: Såg nu också att jag glömt curl_exec för att logga ut... var som sagt inte helt nykter.. hihi...

Visa signatur

citera!

Permalänk
Inaktiv
Skrivet av Dosshell:

Slängde ihop ett strax efter min förra post, men då jag precis hade varit ute när jag gjorde det föll det liksom lite i glömska... såg nu att jag inte kör urlencode() o.s.v. så ta det för vad det är.
Tada: http://pastebin.com/ABW5kTg7
Den dumpar till en fil för att kunna spara skillnaderna.
EDIT: Såg nu också att jag glömt curl_exec för att logga ut... var som sagt inte helt nykter.. hihi...

Fyllegris!

Skall testas senare.

Permalänk
Medlem
Skrivet av Dosshell:

Slängde ihop ett strax efter min förra post, men då jag precis hade varit ute när jag gjorde det föll det liksom lite i glömska... såg nu att jag inte kör urlencode() o.s.v. så ta det för vad det är.
Tada: http://pastebin.com/ABW5kTg7
Den dumpar till en fil för att kunna spara skillnaderna.
EDIT: Såg nu också att jag glömt curl_exec för att logga ut... var som sagt inte helt nykter.. hihi...

Oh, du körde via mobilsidan istället!
Såg faktiskt riktigt snyggt ut!

Testkörde skriptet, dock så får den bara fram 208 vänner när jag skriver en count($friends) och jag har 580~ vänner. Kom fram till att den när den kollar t.ex. mellan A-A så får den bara fram 10 resultat(för det är max antal per sida), sedan går den till B-B. Man måste alltså köra en jäkla massa flera for-loopar för att få fram till exempel Ad-Ad för att få fram alla Adam -- säg att man har 10 Adam, då täcker det hela sidan på Ad-Ad och man får därför inte med några flera, t.ex. Adrian. Värst är An och Am då man har en massa Anna, Ann-sofie, Anna-karin, Angelica, Anders, etc. Säkrast bör vara att köra på 3 bokstäver - alltså 3 for-loopar i varandra

Aaa - Aaa
Aab - Aab
Aac - Aac
..
Aaz - Aaz
Aba - Aba
Abb - Abb
..
etc

Finns det något smidigt sätt att göra detta resurs- och tidseffektivt? Eller behöver man köra 3 for-loopar i varandra?
Kan jag ändra din range() till range('Aaa', 'Zzz') ?

Permalänk
Medlem
Skrivet av Tanax:

Oh, du körde via mobilsidan istället!
Såg faktiskt riktigt snyggt ut!

Testkörde skriptet, dock så får den bara fram 208 vänner när jag skriver en count($friends) och jag har 580~ vänner. Kom fram till att den när den kollar t.ex. mellan A-A så får den bara fram 10 resultat(för det är max antal per sida), sedan går den till B-B. Man måste alltså köra en jäkla massa flera for-loopar för att få fram till exempel Ad-Ad för att få fram alla Adam -- säg att man har 10 Adam, då täcker det hela sidan på Ad-Ad och man får därför inte med några flera, t.ex. Adrian. Värst är An och Am då man har en massa Anna, Ann-sofie, Anna-karin, Angelica, Anders, etc. Säkrast bör vara att köra på 3 bokstäver - alltså 3 for-loopar i varandra

Aaa - Aaa
Aab - Aab
Aac - Aac
..
Aaz - Aaz
Aba - Aba
Abb - Abb
..
etc

Finns det något smidigt sätt att göra detta resurs- och tidseffektivt? Eller behöver man köra 3 for-loopar i varandra?
Kan jag ändra din range() till range('Aaa', 'Zzz') ?

Oj! Det är ett problem som inte jag märker av och att ha 4 nestlade foreach är nog ingen bra idé. I så fall kan man ju försöka göra en multicurl och begära alla sidor samtidigt, det borde fungera men jag tror det är bättre att köra lite dynamiskt och endast hämta de sidor som behövs.
Typ så här http://pastebin.com/C8NAy33a

EDIT: Kommentarfel i koden

Visa signatur

citera!

Permalänk
Medlem
Skrivet av Dosshell:

Oj! Det är ett problem som inte jag märker av och att ha 4 nestlade foreach är nog ingen bra idé. I så fall kan man ju försöka göra en multicurl och begära alla sidor samtidigt, det borde fungera men jag tror det är bättre att köra lite dynamiskt och endast hämta de sidor som behövs.
Typ så här http://pastebin.com/C8NAy33a

EDIT: Kommentarfel i koden

Har inte testat men hängde inte med på den rekursiva metoden. Vad exakt är det vi nästlar oss ner i för varje rekursivt anrop??
Ska testa koden!

Permalänk
Medlem
Skrivet av Tanax:

Har inte testat men hängde inte med på den rekursiva metoden. Vad exakt är det vi nästlar oss ner i för varje rekursivt anrop??
Ska testa koden!

Vi nästlar ner oss i vän-länkarna* och sedan när det inte finns några länkar kvar så är den på "botten nivån" och då lägger vi till vännerna i den kategorin. Rekrusiva funktioner kan vara lite jobbiga att läsa om man är ovan (det är därför jag inte tycker om dem) men i det här fallet är en av få gånger som jag tycker det är "rätt".
Du kan ju slänga in en echo $url."\n"; innan rad 20 så ser du hur den besöker alla vänsidor.

* (A–B)-> (A)-> (Ad–An)-> (Ad–Am)-> [Ad–Am] (An)-> [An] (Ar–Au)-> [Ar–Au] (B)-> [B] (C–E)-> (C–D)-> [C-D] (E)-> [E] o.s.v. [] = Djupaste nivån, lägg till vänner ()-> = länk, anropa sig själv fast med länken som utgångspunkt

Visa signatur

citera!

Permalänk
Medlem
Skrivet av Dosshell:

Vi nästlar ner oss i vän-länkarna* och sedan när det inte finns några länkar kvar så är den på "botten nivån" och då lägger vi till vännerna i den kategorin. Rekrusiva funktioner kan vara lite jobbiga att läsa om man är ovan (det är därför jag inte tycker om dem) men i det här fallet är en av få gånger som jag tycker det är "rätt".
Du kan ju slänga in en echo $url."\n"; innan rad 20 så ser du hur den besöker alla vänsidor.

* (A–B)-> (A)-> (Ad–An)-> (Ad–Am)-> [Ad–Am] (An)-> [An] (Ar–Au)-> [Ar–Au] (B)-> [B] (C–E)-> (C–D)-> [C-D] (E)-> [E] o.s.v. [] = Djupaste nivån, lägg till vänner ()-> = länk, anropa sig själv fast med länken som utgångspunkt

Problemet var nog att jag inte riktigt hade kollat igenom källkoden för facebook-sidan så visste inte riktigt vad allting gjorde.
Förstår mycket bättre nu!

Har fortfarande inte provat skriptet än då jag sitter på en annan dator för tillfället - är bortrest - men kommer det inte uppstå vissa problem med skriptet i vissa lägen? Om jag nästlar mig ner, manuellt på mobila sidan, enligt denna:

A-C -> A -> Am-An. Då finns det 2 alternativ att välja mellan att nästla sig djupare. Antingen An eller Anton T-An. Enligt skriptet kommer den försöka nästla sig ner i An(eftersom den hämtar de 2 länkarna och lägger det i en array(), tar första länken först och följer den), problemet är att den går till exakt samma sida, dvs An-An och jag kommer fortfarande ha 2 alternativ att nästla mig därifrån, antingen An(igen) eller Anton T-An. Alltså borde det bli en evighetsloop, eller?

Det den borde göra är att hämta alla vänner på den sidan och sedan gå till Anton T-An och hämta alla vänner därifrån, men det gör den inte eftersom den alltid kommer hitta länkar på An-An sidan, varav den ena länken leder till samma sida.

Eller funkar det ändå? Önskar jag kunde testa >.<
Tackar för all hjälp för övrigt hittills, riktigt schysst!

Permalänk
Medlem
Skrivet av Tanax:

A-C -> A -> Am-An. Då finns det 2 alternativ att välja mellan att nästla sig djupare. Antingen An eller Anton T-An. Enligt skriptet kommer den försöka nästla sig ner i An(eftersom den hämtar de 2 länkarna och lägger det i en array(), tar första länken först och följer den), problemet är att den går till exakt samma sida, dvs An-An och jag kommer fortfarande ha 2 alternativ att nästla mig därifrån, antingen An(igen) eller Anton T-An. Alltså borde det bli en evighetsloop, eller?

Det den borde göra är att hämta alla vänner på den sidan och sedan gå till Anton T-An och hämta alla vänner därifrån, men det gör den inte eftersom den alltid kommer hitta länkar på An-An sidan, varav den ena länken leder till samma sida.

Eller funkar det ändå? Önskar jag kunde testa >.<
Tackar för all hjälp för övrigt hittills, riktigt schysst!

Inga problem, använder ju det själv så det blir ju inget extra jobb

Eh? Hur ser din struktur ut för vännersidan igentligen? Det är inget vanligt binarytree alltså, för det har jag? Jag har tydligen helt klart för få vänner för att kunna undersöka den saken. Men om det är som du säger att två noder länkar till varandra blir det helt klart ett problem.

Visa signatur

citera!

Permalänk
Medlem
Skrivet av Dosshell:

Inga problem, använder ju det själv så det blir ju inget extra jobb

Eh? Hur ser din struktur ut för vännersidan igentligen? Det är inget vanligt binarytree alltså, för det har jag? Jag har tydligen helt klart för få vänner för att kunna undersöka den saken. Men om det är som du säger att två noder länkar till varandra blir det helt klart ett problem.

Är fortfarande bortrest men jag ska testa lite. Får sätta in en koll på vad vi i senaste rekursionen gick ned i och om den hittar samma så är vi längst ned.. typ? Låter bra i teorin iaf xd

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av Tanax:

Är fortfarande bortrest men jag ska testa lite. Får sätta in en koll på vad vi i senaste rekursionen gick ned i och om den hittar samma så är vi längst ned.. typ? Låter bra i teorin iaf xd

Skickades från m.sweclockers.com

Jag förstår inte riktigt hur din vän struktur ser ut för dig, så jag kan inte svara på om det låter bra. Men om det är ett binary tree, som det är för mig, så ska koden fungera bra. Om du är orolig för att den ska fastna i en loop kan man ju alltid lägga till besökta adresser till en lista och kolla mot den.

Visa signatur

citera!

Permalänk
Medlem
Skrivet av Dosshell:

Jag förstår inte riktigt hur din vän struktur ser ut för dig, så jag kan inte svara på om det låter bra. Men om det är ett binary tree, som det är för mig, så ska koden fungera bra. Om du är orolig för att den ska fastna i en loop kan man ju alltid lägga till besökta adresser till en lista och kolla mot den.

Ja alltså, jag kollar bara hur länkarna ser ut om jag manuellt går in på http://m.facebook.com/friends.php så ser jag A-C(bland andra). Går jag in där så kommer den första vara A. Går jag in där ser jag A-Al. Går jag in där ser jag A-Ad och Al. Går jag in på A-Ad kommer jag till ett "slut" och jag ser inga flera länkar. Går jag upp en och istället går in på Al så kommer jag ha 2 länkar, Al och Alicia C-Al. Den första är alltså Al, fast den är vi ju redan nere i, den länkar alltså till samma sida. Förstår inte riktigt hur jag ska förklara det på ett bättre sätt?

Så tror nog en besökta-lista är det enda raka. Får försöka lite.

Permalänk
Medlem
Skrivet av Tanax:

Ja alltså, jag kollar bara hur länkarna ser ut om jag manuellt går in på http://m.facebook.com/friends.php så ser jag A-C(bland andra). Går jag in där så kommer den första vara A. Går jag in där ser jag A-Al. Går jag in där ser jag A-Ad och Al. Går jag in på A-Ad kommer jag till ett "slut" och jag ser inga flera länkar. Går jag upp en och istället går in på Al så kommer jag ha 2 länkar, Al och Alicia C-Al. Den första är alltså Al, fast den är vi ju redan nere i, den länkar alltså till samma sida. Förstår inte riktigt hur jag ska förklara det på ett bättre sätt?

Så tror nog en besökta-lista är det enda raka. Får försöka lite.

Varför har dom en länk till sidan man redan är på!? Dumma Facebook!
Jo, en besökslista skulle lösa problemet.

Visa signatur

citera!

Permalänk
Medlem
Skrivet av Dosshell:

Varför har dom en länk till sidan man redan är på!? Dumma Facebook!
Jo, en besökslista skulle lösa problemet.

Dom är lite roliga dom..
I vilket fall, nu när jag är hemma igen och kunnat leka runt lite så har jag stött på ett problem. Har gjort en egen klass som heter FBUnfriended.

Får detta fel:

Fatal error: Maximum execution time of 30 seconds exceeded in E:\Program\wamp\www\unfriended2\FBUnfriended.php on line 90 Call Stack # Time Memory Function Location 1 0.0003 671944 {main}( ) ..\index2.php:0 2 2.5986 2874952 FBUnfriended->GetFriends( ) ..\index2.php:9 3 2.5986 2874952 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:77 4 25.6513 11758192 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:123 5 28.8955 9497936 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:123 6 29.7819 11222760 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:123

Line 90:

$html = str_get_html( curl_exec( $this->ch ) );

Ibland lyckas den köra flera iterationer och ibland färre, helt olika alltså.
Dessutom, ibland när jag kör skriptet får jag felmeddelande att "Du har överskridit antalet felaktiga inloggningar, försök igen senare!" även fast jag använder samma lösen som jag alltid gjort, har alltså inte rört det. Har Facebook en spärr på hur många requests man kan skicka per minut eller något dylikt?

Här är hela klassen:

<?php if( !file_exists( 'simple_html_dom.php' ) ) die("Cannot find Simple HTML DOM file"); include_once('simple_html_dom.php'); class FBUnfriended { private $ch; private $user_conf; private $login_html; private $friends = array(); private $memory = array(); public function __construct() { if( !file_exists( 'config.php' ) ) die("Cannot find configuration file, aborting!"); include_once('config.php'); $this->user_conf = $config; } public function Login() { $this->ch = curl_init(); curl_setopt( $this->ch, CURLOPT_URL, $this->user_conf['url_main'] . $this->user_conf['url_login'] ); curl_setopt( $this->ch, CURLOPT_FOLLOWLOCATION, 1 ); curl_setopt( $this->ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt( $this->ch, CURLOPT_POST, 1 ); curl_setopt( $this->ch, CURLOPT_POSTFIELDS, $this->user_conf['postfields'] ); curl_setopt( $this->ch, CURLOPT_COOKIEFILE, 1 ); curl_setopt( $this->ch, CURLOPT_FOLLOWLOCATION, 1 ); $this->login_html = str_get_html( curl_exec($this->ch) ); $this->_validateLogin(); return $this; } private function _validateLogin() { $logout_link = $this->login_html->find( 'a[data-sigil=logout]' ); if( empty( $logout_link ) ) { echo date( 'Y-m-d H:i:s' ) . ': Error has occured!<br />'; echo $this->login_html->find( 'div[id="rootContent"]', 0 ) ->children(0)->children(0) ->children(0)->innertext . '<br />'; die(); } } public function GetFriends() { empty( $this->friends ); empty( $this->memory ); $this->_getFriendsRecursive( $this->user_conf['url_friends'] ); return $this->friends; } private function _getFriendsRecursive( $url ) { //echo 'Checking url: ' . $url . '<br />'; //echo 'Count of memory: ' . count($this->memory) . '<br />'; // Follow the URL curl_setopt( $this->ch, CURLOPT_URL, $this->user_conf['url_main'] . $url ); // Get the HTML of the new page $html = str_get_html( curl_exec( $this->ch ) ); // Get the list of friend-pagination links $links = $html->find('div[id="sections"]',0)->find('div[class=acw apm]',0)->find('a[class="sec"]'); //echo 'Found links: ' . count($links) . '<br />'; // If the list is empty, we have reached an end-point if( empty( $links ) ) { //echo 'There are no links, getting friends on the current page!<br />'; $this->_getFriendsOnPage( $html ); } // Else we have to try to go further down else { // Loop through the links //echo 'Looping through the links..<br />'; foreach( $links as $link ) { //echo 'Checking link: ' . $link->href . '<br />'; // Check if we've already visited the page if( array_search( htmlspecialchars_decode( $link->href ), $this->memory ) == false ) { //echo 'We have not visited this page before! Adding it to the memory<br />'; // If we haven't, add the page to the memory $this->memory[] = htmlspecialchars_decode( $link->href ); // And follow the page //echo 'Calling method recursivly with url: ' . $link->href . '<br />'; $this->_getFriendsRecursive( htmlspecialchars_decode( $link->href ) ); } else { //echo 'We have visited this page before, getting friends on the current page!<br />'; $this->_getFriendsOnPage( $html ); } } } } private function _getFriendsOnPage( $html ) { // Loop through all the friends on the current page foreach( $html->find('div[class="ib"]') as $friendholder ) { // Add to list of all friends $this->friends[] = htmlspecialchars_decode( $friendholder->children(1)->children(0)->name, ENT_QUOTES ); //kovertera också om någon använder cituationstecken i namnet } } public function Logout() { $logout_link = 'http://m.facebook.com' . $this->login_html->find( 'a[data-sigil=logout]', 0 )->href; curl_setopt( $this->ch, CURLOPT_URL, htmlspecialchars_decode( $logout_link ) ); curl_exec( $this->ch ); } public function Close() { if( isset( $this->ch ) ) { curl_close( $this->ch ); $this->ch = null; } } public function __destruct() { $this->Close(); } }

Config.php

<?php $config['user_mail'] = ''; $config['user_pass'] = ''; $config['url_main'] = 'http://m.facebook.com'; $config['url_login'] = '/login.php'; $config['url_friends'] = '/friends.php?pa'; $config['postfields'] = 'email=' . $config['user_mail'] . '&pass=' . $config['user_pass'];

index.php

<?php include_once('FBUnfriended.php'); date_default_timezone_set('Europe/Stockholm'); $fb = new FBUnfriended(); $fb->Login(); $friends = $fb->GetFriends(); echo '<h2>Printing list..</h2>'; echo count($friends); $fb->Logout();

Permalänk
Medlem

Okej, gjorde lite mera testning och det är detta som tar längre tid än 30 sekunder:

curl_exec( $this->ch );

Jag undrar varför dock. Om man kollar Call Stack så visar den:

Call Stack # Time Memory Function Location 1 0.0005 671944 {main}( ) ..\index2.php:0 2 1.7273 3071736 FBUnfriended->GetFriends( ) ..\index2.php:9 3 1.7273 3071736 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:77 4 22.3406 11960960 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:127 5 25.4342 9712264 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:127 6 26.2831 11447568 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:127 7 28.4434 10085056 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:127 8 29.5425 11578520 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:127 9 29.9657 12480472 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:127

Första gången vi kallar på den tar den bara 1.7, andra gången tar den hela 22(!!)

3 1.7273 3071736 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:77 4 22.3406 11960960 FBUnfriended->_getFriendsRecursive( ) ..\FBUnfriended.php:127

EDIT: Oh! Kan det vara array_search som tar tid? Eftersom memory hela tiden blir större blir det mera att söka igenom tills det till slut tar längre tid än 30..?

Hur löser jag det med en besök-lista i så fall? För jag måste ju på något sätt söka igenom den listan.. Om det är det dvs?
Inser att man säkert kan lösa det genom att bara höja nån inställning i php.ini men man vill ju gärna att det ska vara så optimerat som möjligt..

Permalänk
Medlem

Bara för att säkerställa att det inte blev något knas pga att jag använde klassvariabler så körde jag även ditt skript(fast la till memory variabel) och får error på exakt samma grej.

<?php include_once('simple_html_dom.php'); $email = ''; $password = ''; $datafile = 'fbfriends.data'; //Behövs om man t.ex. bara kör php-cli (som jag alltså) date_default_timezone_set('Europe/Stockholm'); //Skriv ett meddelande (eller lagra i en databas o.s.v. om man hellre vill det) function print_message($typ, $meddelande) { echo(date('Y-m-d H:i:s').": $typ: $meddelande\n"); } //Hitta alla vänsidor och vänner rekursivt (inte ofta jag tycker att man ska använda rekursivt men här blev det enklare) function getFriends($ch, $url, $memory = null) { $friends = Array(); if( $memory == null ) $memory = Array(); curl_setopt($ch, CURLOPT_URL, 'http://m.facebook.com'.$url); $html = str_get_html(curl_exec($ch)); $lista = $html->find('div[id="sections"]',0)->find('div[class=acw apm]',0)->find('a[class="sec"]'); if (empty($lista)) { //Vi är nestlade till djupet, lägg till vännerna foreach($html->find('div[class="ib"]') as $friendholder) $friends[] = htmlspecialchars_decode($friendholder->children(1)->children(0)->name, ENT_QUOTES); //kovertera också om någon använder cituationstecken i namnet return $friends; } else { //Vi är inte nestlade till djupet, bäst att gå djupare in foreach ($lista as $link) { // Kolla om vi hittar den nuvarande länken i minnet - dvs om vi redan gått ner i den if( array_search( htmlspecialchars_decode( $link->href ), $memory ) == false ) { // Om inte, lägg till länken i minnet $memory[] = htmlspecialchars_decode($link->href); // Gå djupare $friends = array_merge($friends, getFriends($ch, htmlspecialchars_decode($link->href), $memory)); } else { // Om den fanns, hitta alla vänner på nuvarande sida foreach($html->find('div[class="ib"]') as $friendholder) $friends[] = htmlspecialchars_decode($friendholder->children(1)->children(0)->name, ENT_QUOTES); // Returnera vännerna return $friends; } } //Inget mer att hämta, gå upp ett steg return $friends; } } //Sätt upp curlen $ch = curl_init(); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, 'email='.urlencode($email).'&pass='.urlencode($password)); curl_setopt($ch, CURLOPT_COOKIEFILE, 1); //Har glömt bort varför jag kör med 1!? Hade säkert någon bra idé och det fungerar ju uppenbart curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); //Logga in curl_setopt($ch, CURLOPT_URL,'http://m.facebook.com/login.php'); $html = str_get_html(curl_exec($ch)); //Kontrollera att du loggades in genom att se om du kan logga ut $loggaut = $html->find('a[data-sigil=logout]'); if (empty($loggaut)) { print_message('Error', $html->find('div[id="rootContent"]',0)->children(0)->children(0)->children(0)->innertext); die(1); } //Hämta alla vänner $friends = getFriends($ch, '/friends.php'); echo count($friends); //Logga ut /* Behövs nog inte igentligen $loggaut = 'http://m.facebook.com'.$html->find('a[data-sigil=logout]',0)->href; curl_setopt($ch, CURLOPT_URL, htmlspecialchars_decode($loggaut)); curl_exec($ch); */ //Ta bort curl curl_close($ch); //Ladda in fil med vänner if (!file_exists($datafile)) { print_message('Info','Hittade ingen gammal data att jämföra med - skapar data för framtida bruk'); touch($datafile); //Skapa filen om den inte finns } $prev_friends = unserialize(file_get_contents($datafile)); if (!empty($prev_friends)) { $diff = array_diff($prev_friends, $friends); if (!empty($diff)) { //Skriv ut skilnaderna... jag kör outputen till en fil i crontab... foreach($diff as $lost_friend) print_message('Förlorad vän', $lost_friend); } } //Spara mina nuvarande vänner för nästa gång file_put_contents($datafile, serialize($friends));

Error på:

$html = str_get_html(curl_exec($ch));

Permalänk
Medlem
Skrivet av Dosshell:

Varför har dom en länk till sidan man redan är på!? Dumma Facebook!
Jo, en besökslista skulle lösa problemet.

Trött man blir på dom, dumma Facebook!
Knåpat lite till och löste problemet med timeout..tror jag. Satte set_time_limit(120). 2 minuter bör ju räcka.. Det funkar nu och genererar en lista utan att ge timeout.

I vilket fall så stöter jag på ytterligare ett problem.. jävla problem asså.. (fast nu är det nära!). Får enligt skriptet fram att jag har 460 vänner. Egentligen har jag 574. Den verkar alltså hoppa över vissa. Hittade ett exempel på detta.

friends.php?pa&start=Al&end=Al&refid=5

Listar 10 personer för mig.

Alessia Alex Alexander A Alexander B Alexander D Alexander T Alexander W Alexander W Alexandra H Alexandra Z

Finns även en länk längst upp till friends.php?pa&start=Alicia+C&end=Al&refid=5

Problemet är att det finns en som heter Alexia i min vännerslista som den verkar hoppa över av någon anledning(fel på deras pagination, hm?!). Alexia kommer ju före Alicia C men efter Alexandra Z. Någon idé hur jag kan komma förbi detta?

Permalänk
Medlem

Förfinade skriptet. Får nu fram 546 vänner av 574. Nu är det jäkligt nära! Snart klart! (för er som bryr er )

Permalänk
Medlem


Tack för hjälpen Dosshell!