javascript tartalom megkeresése böngészőben

(Lehet a cím rossz, mert lehet a megközelítés is, javítsatok ki nyugodtan.)

Feladat:

Instagram galéria oldalán a képek linkjének, vagy azonosítójának kibányászása (linkből azonosító kinyerhető).

Példa galéria linkre:
https://www.instagram.com/humansfurryfriends/

Példa linkre és azonosítóra:
https://www.instagram.com/p/BoT_NcbDQ99/?taken-by=humansfurryfriends
BoT_NcbDQ99

--- --- --- --- --- --- --- --- --- --- --- ---

Megközelítéseim és bukásaim:

- A html tartalom feldolgozásánál a következő hibába futottam: görgetéskor tölti be a további képeket, DE közben kiveszi az előzőeket is, html-ben csak a galéria egy része van jelen.

- Készítettem programot, ami görget, és közben kiolvas, viszont ez csak workaround lett, a célom az lenne, hogy tanuljak, ne csak megoldjam.

- Network traffic-et néztem, görgetés közben nyilván tölti is le a tartalmat, nekem nem ez a lényeges viszont, hanem a már letöltött tartalom nyomon követése, tehát ahova az ajax-on keresztül letöltött adatokból kerülnek.

- Localstorage-ban nincs, window változóban böngésztem körbe csak.

- Csak az oldal betöltésekor látható alapeset képeit találtam, a továbbiakat nem:

window._sharedData.entry_data.ProfilePage[0].graphql.user.edge_owner_to_timeline_media.edges

window.__initialData.data.entry_data.ProfilePage[0].graphql.user.edge_owner_to_timeline_media.edges

- Mélyebben nem tudtam kutatni, mert elveszetettem a fonalat, nem tudtam a teljes js kód átnézése nélkül megtalálni, hogy a network traffic-ból jövő adatok hova kerülnek.

(Nem elsődlegesen JS programozó vagyok. Firefox-ban dolgoztam, ha esetleg számít, beépített developer tool-t használtam. Kerestem userscript-eket, de csak html feldolgozást találtam.)

Hozzászólások

Én nagyjából a következőket szedtem össze:

  • Az Instagram egy React app, a Vendor.js alapján Redux store-t használnak. Van extension, amivel bele lehet nézni a store-ba, de nem biztos, hogy egy production buildben ez működik. Az sem biztos, hogy a window-on keresztül el lehet jutni a store állapotáig, elvégre nem túl jó ötlet globális változókat használni.
  • Alkalmaznak szerveroldali renderelést, a window-ra az initial state kerül amiből a kliens oldali kód inicializálja magát.
  • Az oldal GraphQL alapú API-t használ, görgetéskor egy kérés így néz ki:
    https://www.instagram.com/graphql/query/?query_hash=<valami hash>&variables={"id":"6000449194","first":12,"after":"<valami token>"}
    • A hash valószínűleg a kérésből és egyéb információkból számolt hash, ezzel védekezve valamennyire a botok ellen, forráskód tanulmányozásából kideríthető, hogyan számolják.
    • Az id a user id
    • A first a válaszban várt elemek száma
    • Az after az utolsó kéréssel kapott token értéke, ez először az initial state-ben kell, hogy legyen. Láthatóan ez utóbbi egy base64 encoded string, de nincs sok értelme dekódolni.
  • A válaszban a a data.user.edge_owner_to_timeline_media alatt a következők hasznos információk:
    • count: hány elem van összesen
    • page_info.has_next_page: van-e következő oldal
    • page_info.end_cursor: a következő kérésben elküldendő after token
    • edges[i].shortcode: ezt keresed :)
  • Az egyetlen nehézséget a hash kiszámolásában látom, ha csak simán átírom az after paramétert de nem módosítom a hash-t 403 Forbidden-t kapok. Ennek kitúrására most nem vállalkozok.

A graphql-től kapott adatokat a react app-ok átalakítják html kimenetté, majd törlik is az adatot a memóriából? Több olyan változót láttam, ami "loading data" jellegű névvel rendelkezik, de nem tudtam elkapni a változásait.

JS-ben van olyan event egy-egy változóra, ami értesít az értékének változásáról? Nekem az is elég lenne, ha egy event-em lenne, ami görgetéskori letöltéskor elsül.

Hülyeséget írtam, valahol meg kell maradnia memóriában a már letöltött tartalomnak, mert visszafelé görgetéskor (régi tartalom megjelenítésekor) is változik a html tartalma, viszont nincs network forgalom, graphql nem kerül lekérdezésre. Emiatt gondoltam, hogy kell lennie valahol egy objektumnak, ami hízik.

Igen, ahogy írtam erre való a Redux store. Nagy vonalakban ez úgy működik, hogy a görgetés hatására keletkezik egy esemény, ami következtében lekérésre kerülnek a következő elemek. Amikor a válasz megérkezik, frissül a store állapota az új elemekkel. Azok a React komponensek, amik függnek ettől az állapotról, össze vannak kötve a store-ral. Amikor frissüla store állapota újrarenderelődnek az új állapottal.

Redux store az extension-el nem elérhető, vagy csak "nem jól tartom", semmit nem mutatott az extension.

A forrásokban kerestem a createStore-t, hátha egyszerű módon van létrehozva, de csak elég nehezen követhető részeket találtam.

Más megközelítés? Rosszul tudom, hogy ennek is ott kéne lennie a window object-ben?

Teljesen jogos felvetés, nem írtam a témanyitóba: nem publikus galériáról van szó, nem is galériáról, hanem az adott user saját mentett, mások által készített bejegyzéseiről. Bejelentkezés után elérhető a felületen, ugyan ez a listázó listázza, mint ami a publikus oldalakat, és nincs hozzá api. Vagy, nem találtam meg, a user saját adatainak lekérését még most megpróbálom, hátha.