repat / Grafari

Facebook Scraping Tool
8 stars 2 forks source link

Scrolling in ZombieJS implementieren (Mehr Daten nachladen) #18

Closed lSoleyl closed 9 years ago

lSoleyl commented 9 years ago

Hi, ich hab mal ein neues Label erstellt, da die anderen iwie nicht so recht passen. Hierzu würde ich jemanden bitten, sich dieses Issue zuzuweisen, wenn er meint, er würde sich damit beschäftigen.

Wir haben momentan das Problem, dass bei ZombieJS die Ergebnisseite mit 7 Ergebnissen aufgebaut wird und 7 Ergebnisse sind etwas wenig, um damit zu arbeiten. Für einen ersten Prototypen ist das okay, aber wir müssen das unbedingt angehen.

Facebook lädt die Ergebnisse asynchron nach, wenn man auf der Seite runterscrollt und das müssen wir irgendwie mit ZombieJS emulieren. Ich weiß, dass @thinking-aloud sich damit bereits etwas beschäftigt hat und ich habe mir das auch kurz angesehen, bin aber zu keiner Lösung gekommen.

Es wäre cool, wenn wir so 30-50 Ergebnisse von einer Suchanfrage zurückbekommen könnten. 7 ist einfach zu wenig.

repat commented 9 years ago
Remote Address:31.13.93.3:443

Request URL:https://www.facebook.com/ajax/pagelet/generic.php/BrowseScrollingSetPagelet?data=%7B%22view%22%3A%22list%22%2C%22encoded_query%22%3A%22%7B%5C%22bqf%5C%22%3A%5C%22present(residents(115351105145884))%5C%22%2C%5C%22vertical%5C%22%3Anull%7D%22%2C%22encoded_title%22%3A%22WyJQZW9wbGUrd2hvK2xpdmUraW4rIix7InRleHQiOiJDYWlyb1x1MDAyNTJDK0VneXB0IiwidWlkIjoxMTUzNTExMDUxNDU4ODQsInR5cGUiOiJjaXR5In1d%22%2C%22ref%22%3A%22unknown%22%2C%22logger_source%22%3A%22www_main%22%2C%22typeahead_sid%22%3A%22%22%2C%22tl_log%22%3Afalse%2C%22impression_id%22%3A%22396476ae%22%2C%22filter_ids%22%3A%7B%22516668296%22%3A516668296%2C%22837337242%22%3A837337242%7D%2C%22experience_type%22%3A%22grammar%22%2C%22exclude_ids%22%3Anull%2C%22browse_location%22%3A%22%22%2C%22trending_source%22%3Anull%2C%22ref_path%22%3A%22%2Fsearch%2F115351105145884%2Fresidents%2Fpresent%22%2C%22is_trending%22%3Afalse%2C%22topic_id%22%3Anull%2C%22story_id%22%3Anull%2C%22cursor%22%3A%22AbpSThUuzHM_30IZrUPeuoZSRl9RXJEVg7DpOHg4DPB1JSyHeJpMUykC-SEf1L3cv26VNAU9SCsaEmYLVfifOhAhfnGtc_z8UkuIngcVlSAsmtPIiPMQ7PXj84TpPFH7X14LcZInS1XW713WdNUWR1rN0skmdlegqS9JJACZaTPxuA%22%2C%22page_number%22%3A7%7D&__user=1827642261&__a=1&__dyn=7n8ajEyl35zoSt2u6aWizGomyp9Esx6bF3pqzCC-C26m6oKexm48jhHximmey8szoyfw&__req=o&__rev=1507751

Request Method:GET
[...]
referer:https://www.facebook.com/search/115351105145884/residents/present

Ich glaube das hier ist die Anfrage("People living in Cairo").

Abundzu kommt nochmal eine GET Anfrage mit pull, das scheint aber ein heartbeat für den Chat auf der rechten Seite zu sein.

lSoleyl commented 9 years ago

Die Frage ist, was bedeuten die einzelnen Parameter?

repat commented 9 years ago

Bin ich gerade am rumbasteln...

repat commented 9 years ago

Ich habe das fb-uid-scraper Plugin mal installiert(Chrome Extension). Der lädt das per AJAX nach. Es geht also und irgendwo in 3. Link von eben steckt die Antwort ^^

repat commented 9 years ago

Ergebnisse unser post-GSM Session:

Wir haben mal runtergescrollt und im Chrome dann in der Konsole die BrowseScrollingSetPagelet angeguckt. Da fanden wir folgendes:

["BrowseScrollingPager", "pageletComplete", [],
                [{
                    "cursor": "AbrVG-hr0AUw643VH60I_cLxWFwwsYpzLl2GPEnsC86RoFNfKGSPVd_aLOuSZ6KlDOPRXf0T7bYrZyTAVOTt6EBjW0OLKi-_z0kgUZpS3DhuC2A1wlP4v5IoWDqN8T-Nfec7uDoCBvPI9cHmr5KotHvSYtjEGlbtYisrhisBUKzMrCfj8DPHXyOzfIuViGoTNpo",
                    "page_number": 5
                }]
            ],

SubstringFooterNext() extrahiert hier cursor und page_number mit Hilfe der Funktion SubString, die als Parameter ein JSON Objekt dieser Struktur enthält

{
    "invl": "htmlreload",
    "startvl": '"cursor":',
    "addstartindex": 0,
    "endvl": '}',
    "addendindex": 1
}

Für SubstringHeaderNext() sieht der Parameter dann so aus (benutzt dieselbe Substring():

{
    "invl": "htmlreload",
    "startvl": '{"view":"list"',
    "addstartindex": 0,
    "endvl": 'story_id":',
    "addendindex": 0
}

DecodeEncodedNonAsciiCharacters() (ist auch schon in browser.js) wandelt alle Sonderzeichen (den Mittepunkt, < und > der HTML Tags, deutsche Umlaute etc) von der \uXXXX-Darstellung (X Zahlen oder Buchstaben) in richtigen Text um.

cutNextUrl() setzt die Ergebnisse von SubstringHeaderNext() und SubstringFooterNext() zusammen. Das ist die URL die für den Ajax Request benutzt wird.

lSoleyl commented 9 years ago

Hmm bei mir sieht die Anfrage aber verdammt kompliziert aus:

GET https://www.facebook.com/ajax/pagelet/generic.php/BrowseScrollingSetPagelet?data=%7B%22view%22%3A%22list%22%2C%22encoded_query%22%3A%22%7B%5C%22bqf%5C`
%22%3A%5C%22present(residents(108100019211318))%5C%22%2C%5C%22vertical%5C%22%3
A%5C%22content%5C%22%2C%5C%22post_search_vertical%5C%22%3Anull%7D%22%2C%22en
coded_title%22%3A%22WyJQZW9wbGUrd2hvK2xpdmUraW4rIix7InRleHQiOiJHZXJtYW55IiwidWlkIj
oxMDgxMDAwMTkyMTEzMTgsInR5cGUiOiJwYWdlIn1d%22%2C%22ref%22%3A%22typeahead%2
2%2C%22logger_source%22%3A%22www_main%22%2C%22typeahead_sid%22%3A%220.129372
4928982556%22%2C%22tl_log%22%3Afalse%2C%22impression_id%22%3A%2223bc0f05%22%2C
%22filter_ids%22%3A%7B%221232237471%22%3A1232237471%2C%22100000499779073%22%
3A100000499779073%2C%22100000772821904%22%3A100000772821904%2C%221000035261
28492%22%3A100003526128492%7D%2C%22experience_type%22%3A%22grammar%22%2C%2
2exclude_ids%22%3Anull%2C%22browse_location%22%3A%22%22%2C%22trending_source%22
%3Anull%2C%22ref_path%22%3A%22%2Fsearch%2F108100019211318%2Fresidents%2Fpresent
%22%2C%22is_trending%22%3Afalse%2C%22topic_id%22%3Anull%2C%22story_id%22%3Anull%
2C%22cursor%22%3A%22AbrL6Aw2-xNzfTWk1Qd5_fBIWMgPxRixYSuHEK35q07OumrYwG6Ip-
E6EhrzWYMVOm5iB22lHvP9s5ij4GE3weOeb8yhXBsHnQxzTeglAfplLnVV38laNTkzlCbLkmOFFTK-
UnlSJihJtVvDQuUOTUlI%22%2C%22page_number%22%3A4%7D&__user=100007992318218&__a
=1&__dyn=7nmajEyl35zoSt2u6aOGeFxq9ACxO4oKAdBGeqrWo8popyUW5ogxd6K59poW8xOdy8-
&__req=1e&__rev=1529876

Mache ich auf den data-Parameter ein unescape(), dann bekomme ich immernoch den Kram hier:

{
  "view":"list",
  "encoded_query":"{\\"bqf\\":\\"present(residents(108100019211318))\\",\\"vertical\\":\\"content\\",\\"post_search_vertical\\":null}",
  "encoded_title":"WyJQZW9wbGUrd2hvK2xpdmUraW4rIix7InRleHQiOiJHZXJtYW55IiwidWlkIjoxMDgxMDAwMTkyMTEzMTgsInR5cGUiOiJwYWdlIn1d",
  "ref":"typeahead",
  "logger_source":"www_main",
  "typeahead_sid":"0.1293724928982556",
  "tl_log":false,
  "impression_id":"23bc0f05",
  "filter_ids": {
    "1232237471":1232237471,
    "100000499779073":100000499779073,
    "100000772821904":100000772821904,
    "100003526128492":100003526128492
  },
  "experience_type":"grammar",
  "exclude_ids":null,
  "browse_location":"",
  "trending_source":null,
  "ref_path":"/search/108100019211318/residents/present",
  "is_trending":false,
  "topic_id":null,
  "story_id":null,
  "cursor":"AbrL6Aw2-xNzfTWk1Qd5_fBIWMgPxRixYSuHEK35q07OumrYwG6Ip-E6EhrzWYMVOm5iB22lHvP9s5ij4GE3weOeb8yhXBsHnQxzTeglAfplLnVV38laNTkzlCbLkmOFFTK-UnlSJihJtVvDQuUOTUlI",
  "page_number":4
}

Für mich sehen die Parmeter teilweise echt random aus, und ich bezweifle, dass wir die einfach weglassen können. Habt ihr dazu auch was gefunden, die Struktur, die @repat im ersten Schnipsel zeigt ist ja nur ein kleiner Ausschnitt von der Gesamtanfrage.

repat commented 9 years ago

Wie die Parameter von den beiden Substring() Funktionen zeigen, werden die Parameter in Header (startvl = "view":"list" und endvl = story_id) und Footer (startvl = cursor bis page_number, also bis endvl = }) unterteilt, wir würden sie also nicht weglassen(?). Wir haben aber noch nicht so wirklich raus, was das alles bedeutet^^

repat commented 9 years ago

Changes document location, loading a new document if necessary (same as setting window.location). This will also work if you just need to change the hash (Zombie.js will fire a hashchange event), for example:

browser.location = "#bang"; browser.wait(function(e, browser) { // Fired hashchange event and did something cool. ... });

@thinking-aloud, hattest du das ausprobiert?


Ich habe mal den Code von dem Chrome Plugin auseinandergenommen und ein bisschen umgeschrieben, s. commit. Ich bekomme auch etwas zurück, wenn ich das einfach mal aufrufe.

urlNextPage: https://www.facebook.com/ajax/pagelet/generic.php/BrowseScrollingSetPagelet?data={"view":"list","encoded_query":"{\"bqf\":\"present(residents(115735848437200))\",\"vertical\":\"content\",\"post_search_vertical\":null}","encoded_title":"WyJQZW9wbGUrd2hvK2xpdmUraW4rIix7InRleHQiOiJDb2xvZ25lXHUwMDI1MkMrR2VybWFueSIsInVpZCI6MTE1NzM1ODQ4NDM3MjAwLCJ0eXBlIjoiY2l0eSJ9XQ","ref":"unknown","logger_source":"www_main","typeahead_sid":"","tl_log":false,"impression_id":"604de445","filter_ids":{"100001234951662":100001234951662,"1426495361":1426495361,"573334013":573334013,"100000215570978":100000215570978},"experience_type":"grammar","exclude_ids":null,"browse_location":"","trending_source":null,"ref_path":"\/search\/115735848437200\/residents\/present","is_trending":false,"topic_id":null,"story_id":null,"cursor":"Abp5ziz0vlgryDz06AlheA_tL1QvPo6jQAJeL3ERWPQbA4_bEhaHwQX75Rdy-bI7HDBGd_DBCAJtVOGEffT3QhTfhl0w3pecGPZHAS1qf-TVgFBoQ6mVJCfrheH-penm2PUkCFm-JqPleJSgFk_Za0sgMXXoAe4PzhPd-ASJomkGLg","page_number":2}&__a
getData URL: https://www.facebook.com/ajax/pagelet/generic.php/BrowseScrollingSetPagelet?data={"view":"list","encoded_query":"{\"bqf\":\"present(residents(115735848437200))\",\"vertical\":\"content\",\"post_search_vertical\":null}","encoded_title":"WyJQZW9wbGUrd2hvK2xpdmUraW4rIix7InRleHQiOiJDb2xvZ25lXHUwMDI1MkMrR2VybWFueSIsInVpZCI6MTE1NzM1ODQ4NDM3MjAwLCJ0eXBlIjoiY2l0eSJ9XQ","ref":"unknown","logger_source":"www_main","typeahead_sid":"","tl_log":false,"impression_id":"604de445","filter_ids":{"100001234951662":100001234951662,"1426495361":1426495361,"573334013":573334013,"100000215570978":100000215570978},"experience_type":"grammar","exclude_ids":null,"browse_location":"","trending_source":null,"ref_path":"\/search\/115735848437200\/residents\/present","is_trending":false,"topic_id":null,"story_id":null,"cursor":"Abp5ziz0vlgryDz06AlheA_tL1QvPo6jQAJeL3ERWPQbA4_bEhaHwQX75Rdy-bI7HDBGd_DBCAJtVOGEffT3QhTfhl0w3pecGPZHAS1qf-TVgFBoQ6mVJCfrheH-penm2PUkCFm-JqPleJSgFk_Za0sgMXXoAe4PzhPd-ASJomkGLg","page_number":2}&__a

Wir müssen uns da bei Gelegenheit nochmal ransetzen, vielleicht zu dritt, @lSoleyl und @thinking-aloud ?

LennartRoeder commented 9 years ago

@repat ja, mehrmals

lSoleyl commented 9 years ago

browser.location = "#bang"; habe ich bereits ausführlich getestet... löst zumindest kein Nachladen von Ergebnissen aus.

repat commented 9 years ago

Gut, ich auch gestern, dann sind wir uns ja einig^^

Also bleibt uns nur die Möglichkeit, das so zu machen wie dieser vietnamesische Programmieren des Chrome Plugins. Was da genau passiert weiß ich auch noch nicht so ganz aber es scheint zu funktionieren. Ist halt nur die Frage, wie wir das in unser convertPageToJSON() einbinden.

Und das Erstellen der Cookies funktioniert glaube ich auch nicht richtig.

lSoleyl commented 9 years ago

... Oder wir lassen es so mit den 12 Ergebnissen. Der Aufwand jetzt mehr Ergebnisse zu bekommen ist grad nicht wirklich gering, da einfach runterscrollen ja nicht zu funktionieren scheint. Für die Demo kann man einfach ne lange Anfrage mit vielen ORs stellen, dann erhält man auch mehr Ergebnisse

Wir haben auch ohne Nachladen von mehr Ergebnissen ein ganz ordentliches Stück Software hinbekommen und für ne PVL sollte es reichen. Außerdem will sich über Weihnachten sicher keiner wegen MI Nächte um die Ohren schlagen ;P