(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.)
- 1029 megtekintés
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 hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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?
- A hozzászóláshoz be kell jelentkezni
elnézést ha ezt a kört már megfutottad, de estleg az official API-n keresztül?
https://developers.facebook.com/docs/instagram-api/reference/media/chil…
már persze ha publikus az említett galéria
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
UP
- A hozzászóláshoz be kell jelentkezni