Projekte / static-instagram-embed

static-instagram-embed

PythonJavaScriptWeb Components

Hintergrund

Ich war am Aufbau einer Website für das Geschäft eines Freundes beteiligt. Wir wollten Cookie-Banner komplett vermeiden, also nutzten wir Plausible für DSGVO-konforme Analytics, OpenStreetMap statt Google Maps und keine CDNs - alle Assets selbst gehostet. Aber wir wollten auch die neuesten Instagram-Posts auf der Seite zeigen.

Instagrams offizielle Embeds tracken Besucher wahrscheinlich genauso wie Facebook-Like-Buttons, und sie sehen auch nicht gut aus. Also musste eine eigene Lösung her.

Die Embed-Komponente integriert in eine Geschäfts-Website, zeigt aktuelle Instagram-Posts in einem Grid

Wie es funktioniert

Das Projekt besteht aus zwei Teilen:

  1. Ein Python-Skript, das die neuesten Posts eines Instagram-Profils abruft und die Daten auf dem eigenen Server speichert. Es läuft als Cron-Job, um die Daten aktuell zu halten.
  2. Ein Web Component (gebaut mit Stencil), das man in die Seite einbettet. Es lädt die gespeicherten Daten und zeigt die Posts an - der Browser des Besuchers macht nie eine Anfrage an Instagram. Funktioniert in jedem Framework oder ganz ohne.

Die Nutzung ist denkbar einfach: nur ein Script-Tag und ein Custom Element:

<script type="module" src="open-instagram-embed.min.js"></script>

<open-instagram-embed
  datasource="url-to/insta-data"
  count="3"
></open-instagram-embed>

Die Komponente zeigt die Post-Thumbnails in einem Gitter. Beim Hovern erscheint ein Overlay mit der Like-Anzahl und der Kommentar-Anzahl (oder die Aufrufzahl bei Videos). Ein kleines Icon in der oberen Ecke zeigt den Content-Typ (Video oder Multi-Image-Karussell) an. Ein Klick auf einen Post öffnet ihn auf Instagram.

Datenformat

Das Fetch-Skript erzeugt ein insta-data/-Verzeichnis mit einer data.json-Datei und Thumbnail-Bildern für jeden Post. Das JSON ist ein einfaches Array:

type Post = {
  shortcode: string,
  type: "GraphImage" | "GraphSidecar" | "GraphVideo",
  thumbnail_image: string,
  likes: number,
  views: number | null,
  comments: number
}

Dieses Format ist bewusst einfach gehalten. Wenn das mitgelieferte Fetch-Skript nicht funktioniert (Instagram ist aggressiv bei Rate-Limits und IP-Blocks), kann man ein eigenes schreiben oder einen Scraper-Service nutzen - die <open-instagram-embed> Komponente interessiert sich nur für das Ausgabeformat.

Daten abrufen

Das ursprüngliche Skript nutzt instaloader, das gut funktioniert, aber an Instagrams Rate-Limits stoßen kann, besonders von Servern aus.

Beim Schreiben dieser Seite brauchte ich frische Post-Daten für die Screenshots, aber instaloader funktionierte nicht ohne einen Account zum Einloggen. Also setzte ich mich mit einem LLM hin und wir schrieben eine Variante des Fetch-Skripts, die eine populäre Scraper-as-a-Service-Plattform nutzt1. Das ist viel einfacher und zuverlässiger als Instagram selbst zu scrapen. Jeder Scrape kostet zwar etwa einen Cent, aber neue Accounts bekommen typischerweise Gratis-Credits, die für diesen Anwendungsfall lange reichen (gelegentlich eine Handvoll Posts abrufen). Die Komponente kümmert sich nicht darum, woher die Daten kommen, also funktioniert jeder Scraper-Service (oder ein eigenes Skript).

Status

Das Geschäft existiert nicht mehr und ich selbst nutze kein Instagram, daher benutze ich dieses Projekt gerade nicht. Aber ich habe bestätigt, dass das Web Component weiterhin einwandfrei funktioniert. Das Problem, Instagram ohne Tracking einzubetten, ist verbreitet genug, dass es für andere nützlich sein könnte - das Projekt ist auf GitHub verfügbar.


  1. In diesem Fall Apify. Hat bei mir sehr gut funktioniert, allerdings habe ich keine Alternativen verglichen.