Instagram-Sync reparieren: feed/user-Endpunkt als Strategie 1
web_profile_info antwortet seit kurzem mit HTTP 400 und einem
Instagram-internen Schema-Fehler ("Asset asset://laser.provider/
ig_business_category_subvertical has been deleted") — kein IP-Block.
Gleichzeitig enthält das Profil-HTML kein edge_owner_to_timeline_media
mehr, womit auch der zweite Fallback tot war und der Cache seit
20.06. nicht mehr aktualisiert wurde.
api/v1/feed/user/{username}/username/ liefert weiterhin 200 mit den
letzten Posts, nur in anderer Form (items[] mit image_versions2 statt
edges[] mit display_url). Neuer Extractor dafür, eingehängt als
Strategie 1; die bisherigen zwei bleiben als Fallback 2 und 3.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,8 +12,9 @@ declare(strict_types=1);
|
||||
* Cron: 17 6,18 * * * cd /pfad/zur/site && /usr/bin/php bin/instagram-sync.php >> storage/logs/instagram.log 2>&1
|
||||
*
|
||||
* Strategie-Kette (erster Erfolg gewinnt):
|
||||
* 1. web_profile_info-API (JSON, inkl. der letzten 12 Posts)
|
||||
* 2. Profil-HTML nach eingebettetem JSON parsen
|
||||
* 1. feed/user-API (JSON, items[] — antwortet auch dann, wenn web_profile_info 400 wirft)
|
||||
* 2. web_profile_info-API (JSON, edges[])
|
||||
* 3. Profil-HTML nach eingebettetem JSON parsen
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(1);
|
||||
@@ -89,23 +90,68 @@ $extractPosts = static function (array $data) use ($maxPosts): array {
|
||||
return $posts;
|
||||
};
|
||||
|
||||
// --- Strategie 1: web_profile_info-API ---
|
||||
/**
|
||||
* Posts aus der feed/user-Struktur ziehen (items[] mit image_versions2 statt edges[]).
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
$extractFeedItems = static function (array $data) use ($maxPosts): array {
|
||||
$posts = [];
|
||||
foreach (array_slice($data['items'] ?? [], 0, $maxPosts) as $item) {
|
||||
// Größten Bild-Kandidaten nehmen — wird unten ohnehin auf 640x800 gecroppt.
|
||||
$url = '';
|
||||
$bestWidth = 0;
|
||||
foreach ($item['image_versions2']['candidates'] ?? [] as $candidate) {
|
||||
$width = (int) ($candidate['width'] ?? 0);
|
||||
if ($width > $bestWidth && !empty($candidate['url'])) {
|
||||
$bestWidth = $width;
|
||||
$url = (string) $candidate['url'];
|
||||
}
|
||||
}
|
||||
if (empty($item['code']) || $url === '') {
|
||||
continue;
|
||||
}
|
||||
$posts[] = [
|
||||
'shortcode' => (string) $item['code'],
|
||||
'caption' => trim((string) ($item['caption']['text'] ?? '')),
|
||||
'taken_at' => (int) ($item['taken_at'] ?? 0),
|
||||
// media_type: 1 = Bild, 2 = Video/Reel, 8 = Karussell.
|
||||
'is_video' => (int) ($item['media_type'] ?? 1) === 2 || !empty($item['video_versions']),
|
||||
'display_url' => $url,
|
||||
];
|
||||
}
|
||||
return $posts;
|
||||
};
|
||||
|
||||
$apiHeaders = [
|
||||
'x-ig-app-id: 936619743392459',
|
||||
'Accept: application/json',
|
||||
'Referer: https://www.instagram.com/' . $username . '/',
|
||||
];
|
||||
|
||||
// --- Strategie 1: feed/user-API ---
|
||||
$posts = [];
|
||||
$body = $fetch("https://www.instagram.com/api/v1/feed/user/{$username}/username/?count=12", $apiHeaders);
|
||||
if ($body !== false) {
|
||||
$data = json_decode($body, true);
|
||||
if (is_array($data)) {
|
||||
$posts = $extractFeedItems($data);
|
||||
$log('Strategie 1 (feed/user): ' . count($posts) . ' Posts');
|
||||
}
|
||||
}
|
||||
|
||||
// --- Strategie 2: web_profile_info-API ---
|
||||
if ($posts === []) {
|
||||
$body = $fetch("https://www.instagram.com/api/v1/users/web_profile_info/?username={$username}", $apiHeaders);
|
||||
if ($body !== false) {
|
||||
$data = json_decode($body, true);
|
||||
if (is_array($data)) {
|
||||
$posts = $extractPosts($data);
|
||||
$log('Strategie 1 (web_profile_info): ' . count($posts) . ' Posts');
|
||||
$log('Strategie 2 (web_profile_info): ' . count($posts) . ' Posts');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Strategie 2: Profil-HTML nach eingebettetem JSON parsen ---
|
||||
// --- Strategie 3: Profil-HTML nach eingebettetem JSON parsen ---
|
||||
if ($posts === []) {
|
||||
$html = $fetch("https://www.instagram.com/{$username}/");
|
||||
if ($html !== false) {
|
||||
@@ -138,7 +184,7 @@ if ($posts === []) {
|
||||
}
|
||||
}
|
||||
}
|
||||
$log('Strategie 2 (HTML-Parsing): ' . count($posts) . ' Posts');
|
||||
$log('Strategie 3 (HTML-Parsing): ' . count($posts) . ' Posts');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user