Uzyskanie dostępu do danych na Instagramie może być trudne ze względu na różne mechanizmy antybotowe, wymagania dotyczące logowania i limity szybkości. Można jednak wyodrębnić przydatne informacje z publicznych profili za pomocą odpowiednich narzędzi i technik. W tym artykule dowiesz się, jak skrobać dane użytkowników Instagrama za pomocą Pythona, wysyłając żądania API do zaplecza Instagrama, wyodrębniając informacje z zwróconych danych JSON i zapisując je w pliku JSON.
Zanim przejdziemy do kodu, upewnij się, że zainstalowałeś wymagane biblioteki Pythona.
pip install requests python-box
Podzielimy kod na różne sekcje dla lepszego zrozumienia, w tym wysyłanie żądania, uzyskiwanie i analizowanie danych, korzystanie z serwerów proxy w celu uniknięcia wykrycia oraz uproszczenie analizowania JSON za pomocą biblioteki Box.
Frontend Instagrama jest silnie zabezpieczony, ale backend oferuje punkty końcowe API, które mogą być używane bez uwierzytelniania. Będziemy używać jednego z tych punktów w przyszłości.
Ten interfejs API zapewnia szczegółowe informacje o profilu użytkownika, w tym jego opis, liczbę obserwujących i posty. Sprawdźmy, jak zażądać danych za pomocą biblioteki żądań w Pythonie.
Wyjaśnienie:
import requests
# Zdefiniuj nagłówki, aby naśladować prawdziwe żądanie przeglądarki
headers = {
"x-ig-app-id": "936619743392459", # Identyfikator aplikacji Instagram do uwierzytelniania żądania
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9,ru;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Accept": "*/*",
}
# Zastąp to nazwą użytkownika, którą chcesz zeskrobać
username = 'testtest'
# Wyślij żądanie API, aby uzyskać dane profilu
response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', headers=headers)
response_json = response.json() # Parsowanie odpowiedzi do obiektu JSON
Ponieważ Instagram ogranicza powtarzające się żądania z tego samego adresu IP, korzystanie z serwerów proxy jest niezbędne do skrobania na dużą skalę. Serwer proxy kieruje żądania przez różne adresy IP, pomagając uniknąć wykrycia.
Aby skonfigurować serwer proxy, potrzebny będzie adres IP, numer portu oraz, w razie potrzeby, nazwa użytkownika i hasło do uwierzytelniania.
proxies = {
'http': 'http://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
'https': 'https://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
}
response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', headers=headers, proxies=proxies)
API Instagrama zwraca złożoną, zagnieżdżoną strukturę JSON, która może być trudna w nawigacji przy użyciu tradycyjnego dostępu opartego na słownikach. Aby ułatwić analizowanie, możemy użyć biblioteki Box, która umożliwia dostęp do danych JSON przy użyciu notacji kropkowej zamiast kluczy słownikowych.
Wyjaśnienie:
from box import Box
response_json = Box(response.json())
# Wyodrębnianie danych profilu użytkownika
user_data = {
'full name': response_json.data.user.full_name,
'id': response_json.data.user.id,
'biography': response_json.data.user.biography,
'business account': response_json.data.user.is_business_account,
'professional account': response_json.data.user.is_professional_account,
'category name': response_json.data.user.category_name,
'is verified': response_json.data.user.is_verified,
'profile pic url': response_json.data.user.profile_pic_url_hd,
'followers': response_json.data.user.edge_followed_by.count,
'following': response_json.data.user.edge_follow.count,
}
Po wyodrębnieniu danych profilu możemy również zeskrobać dane z osi czasu wideo użytkownika i zwykłych postów.
Wyjaśnienie:
# Wyodrębnianie danych wideo
profile_video_data = []
for element in response_json.data.user.edge_felix_video_timeline.edges:
video_data = {
'id': element.node.id,
'short code': element.node.shortcode,
'video url': element.node.video_url,
'view count': element.node.video_view_count,
'comment count': element.node.edge_media_to_comment.count,
'like count': element.node.edge_liked_by.count,
'duration': element.node.video_duration,
}
profile_video_data.append(video_data)
# Wyodrębnianie danych multimedialnych osi czasu (zdjęć i filmów)
profile_timeline_media_data = []
for element in response_json.data.user.edge_owner_to_timeline_media.edges:
media_data = {
'id': element.node.id,
'short code': element.node.shortcode,
'media url': element.node.display_url,
'comment count': element.node.edge_media_to_comment.count,
'like count': element.node.edge_liked_by.count,
}
profile_timeline_media_data.append(media_data)
Po wyodrębnieniu wszystkich danych, następnym krokiem jest zapisanie ich do pliku JSON w celu dalszej analizy lub przechowywania. Używamy modułu json Pythona do zapisywania wyodrębnionych danych do plików JSON. Każdy plik będzie starannie sformatowany dzięki parametrowi indent=4, co ułatwia odczyt i przetwarzanie danych.
import json
# Zapisz dane użytkownika w pliku JSON
with open(f'{username}_profile_data.json', 'w') as file:
json.dump(user_data, file, indent=4)
# Zapisz dane wideo do pliku JSON
with open(f'{username}_video_data.json', 'w') as file:
json.dump(profile_video_data, file, indent=4)
# Zapisz dane multimedialne osi czasu do pliku JSON
with open(f'{username}_timeline_media_data.json', 'w') as file:
json.dump(profile_timeline_media_data, file, indent=4)
Oto kompletny skrypt Pythona, który łączy wszystkie wcześniej omówione sekcje. Kod ten pobiera dane profilu użytkownika, dane wideo i dane mediów na osi czasu z Instagrama, obsługuje niezbędne nagłówki i serwery proxy oraz zapisuje wyodrębnione informacje w plikach JSON.
import requests
from box import Box
import json
# Nagłówki naśladujące prawdziwe żądanie przeglądarki do backendowego API Instagrama
headers = {
"x-ig-app-id": "936619743392459",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9,ru;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Accept": "*/*",
}
# Ustawienie serwera proxy w celu uniknięcia ograniczania szybkości i wykrywania (opcjonalnie)
proxies = {
'http': 'http://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
'https': 'https://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
}
# Nazwa użytkownika na Instagramie do zeskrobania
username = 'testtest'
# Wysłanie żądania do backendowego API Instagrama w celu uzyskania danych profilu.
response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}',
headers=headers, proxies=proxies)
response_json = Box(response.json()) # Skonwertuj odpowiedź na obiekt Box, aby ułatwić nawigację
# Wyodrębnianie danych profilu użytkownika
user_data = {
'full name': response_json.data.user.full_name,
'id': response_json.data.user.id,
'biography': response_json.data.user.biography,
'business account': response_json.data.user.is_business_account,
'professional account': response_json.data.user.is_professional_account,
'category name': response_json.data.user.category_name,
'is verified': response_json.data.user.is_verified,
'profile pic url': response_json.data.user.profile_pic_url_hd,
'followers': response_json.data.user.edge_followed_by.count,
'following': response_json.data.user.edge_follow.count,
}
# Wyodrębnianie danych wideo z osi czasu wideo użytkownika
profile_video_data = []
for element in response_json.data.user.edge_felix_video_timeline.edges:
video_data = {
'id': element.node.id,
'short code': element.node.shortcode,
'video url': element.node.video_url,
'view count': element.node.video_view_count,
'comment count': element.node.edge_media_to_comment.count,
'like count': element.node.edge_liked_by.count,
'duration': element.node.video_duration,
}
profile_video_data.append(video_data)
# Wyodrębnianie danych multimedialnych osi czasu (zdjęć i filmów)
profile_timeline_media_data = []
for element in response_json.data.user.edge_owner_to_timeline_media.edges:
media_data = {
'id': element.node.id,
'short code': element.node.shortcode,
'media url': element.node.display_url,
'comment count': element.node.edge_media_to_comment.count,
'like count': element.node.edge_liked_by.count,
}
profile_timeline_media_data.append(media_data)
# Zapisywanie danych profilu użytkownika w pliku JSON
with open(f'{username}_profile_data.json', 'w') as file:
json.dump(user_data, file, indent=4)
print(f'saved json: {username}_profile_data.json')
# Zapisywanie danych wideo do pliku JSON
with open(f'{username}_video_data.json', 'w') as file:
json.dump(profile_video_data, file, indent=4)
print(f'saved json: {username}_video_data.json')
# Zapisywanie danych multimedialnych osi czasu w pliku JSON
with open(f'{username}_timeline_media_data.json', 'w') as file:
json.dump(profile_timeline_media_data, file, indent=4)
print(f'saved json: {username}_timeline_media_data.json')
Skrobanie danych z Instagrama za pomocą Pythona można wykonać, wykorzystując zaplecze API dostarczone przez Instagram, co pomaga ominąć niektóre ograniczenia front-endu. Używanie odpowiednich nagłówków do naśladowania zachowania przeglądarki i stosowanie serwerów proxy w celu uniknięcia ograniczenia szybkości to krytyczne kroki. Biblioteka Box dodatkowo upraszcza proces, czyniąc analizowanie JSON bardziej intuicyjnym dzięki notacji kropkowej. Zanim zaczniesz skrobać Instagram na dużą skalę, pamiętaj o przestrzeganiu warunków korzystania z usługi Instagram i upewnij się, że Twoje wysiłki w zakresie skrobania nie naruszają ich zasad.
Komentarze: 0