Przewodnik po skrobaniu dynamicznych stron internetowych za pomocą Pythona

Komentarze: 0

Ważną umiejętnością pozyskiwania danych ze stron internetowych jest web scraping. Przykładami tego typu stron są Pinterest i Instagram, które dynamicznie ładują zawartość poprzez interakcję z użytkownikiem. Zwykłe metody skrobania są niewystarczające w przypadku obsługi materiałów opartych na JavaScript. W tym artykule omówimy Playwright jako narzędzie do automatyzacji, podczas gdy lxml będzie używany do ekstrakcji danych z takich dynamicznych witryn, które wymagają Javascript do prawidłowego działania. W tej notatce możemy omówić wykorzystanie serwerów proxy w Playwright, aby uniknąć wykrycia jako boty. W tym samouczku zeskrobujemy profil Instagrama, aby pobrać wszystkie adresy URL postów, symulując zachowanie użytkownika, takie jak przewijanie i oczekiwanie na załadowanie postów.

Narzędzia, których będziemy używać w tym przewodniku:

  • Playwright (do automatyzacji przeglądarki);
  • lxml (do ekstrakcji danych przy użyciu XPath);
  • Python (jako nasz język programowania).

Przewodnik krok po kroku dotyczący skrobania postów na Instagramie

Zilustrujemy ten proces na przykładzie skrobania profilu na Instagramie w celu wyodrębnienia adresów URL postów, symulując działania użytkownika, takie jak przewijanie strony i oczekiwanie na załadowanie nowych danych. Dynamiczne strony internetowe asynchronicznie ładują swoją zawartość za pomocą żądań AJAX, co oznacza, że nie cała zawartość strony jest natychmiast dostępna.

Krok 1. Zainstaluj wymagane biblioteki

Zanim zaczniemy, zainstaluj niezbędne pakiety:


pip install playwright
pip install lxml

Konieczne będzie również zainstalowanie przeglądarki Playwright:


playwright install

Krok 2. Konfiguracja Playwright do dynamicznego skrobania stron internetowych

Użyjemy Playwright, aby zautomatyzować przeglądarkę, załadować dynamiczną zawartość Instagrama i przewinąć stronę, aby załadować więcej postów. Stwórzmy podstawowy skrypt automatyzacji:

Skrypt automatyzacji (przeglądarka bezgłowa):


import asyncio
from playwright.async_api import async_playwright

async def scrape_instagram():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)  # Headless mode No visual feedback
        page = await browser.new_page()
        
        # Odwiedź adres URL profilu
        await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")

        # Kliknij przycisk, aby załadować więcej postów
        await page.get_by_role("button", name="Show more posts from").click()
        
        # Przewijanie strony w celu załadowania zawartości dynamicznej
        scroll_count = 5  # Dostosuj to na podstawie tego, ile razy chcesz przewijać.
        for _ in range(scroll_count):
            await page.evaluate('window.scrollBy(0, 700);')
            await page.wait_for_timeout(3000)  # Wait for posts to load
            await page.wait_for_load_state("networkidle")
        
        # Pobierz zawartość strony
        content = await page.content()
        await browser.close()
        
        return content

# Uruchom funkcję asynchroniczną
asyncio.run(scrape_instagram())

Krok 3. Parsowanie strony za pomocą lxml i XPath

Po załadowaniu zawartości możemy użyć lxml do przeanalizowania HTML i wyodrębnienia danych za pomocą XPath. W tym przypadku wyodrębniamy adresy URL wszystkich postów z profilu.

Parsowanie zawartości strony i wyodrębnianie adresów URL postów:


from lxml import html
import json

def extract_post_urls(page_content):
    # Parsowanie zawartości HTML przy użyciu lxml
    tree = html.fromstring(page_content)
    
    # XPath do wyodrębniania adresów URL postów
    post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
    
    # Wyodrębnianie adresów URL
    post_urls = tree.xpath(post_urls_xpath)
    
    # Konwertowanie względnych adresów URL na bezwzględne
    base_url = "https://www.instagram.com"
    post_urls = [f"{base_url}{url}" for url in post_urls]
    
    return post_urls

Przykładowa funkcja zapisująca wyodrębnione dane w formacie JSON:


def save_data(profile_url, post_urls):
    data = {profile_url: post_urls}
    with open('instagram_posts.json', 'w') as json_file:
        json.dump(data, json_file, indent=4)

# Skrobanie i wyodrębnianie adresów URL
page_content = asyncio.run(scrape_instagram())
post_urls = extract_post_urls(page_content)

# Zapisz wyodrębnione adresy URL w pliku JSON
save_data("https://www.instagram.com/profile name/", post_urls)

Krok 4. Obsługa nieskończonego przewijania za pomocą Playwright

Aby skrobać dynamiczne strony internetowe, często trzeba symulować nieskończone przewijanie. W naszym skrypcie przewijamy stronę za pomocą JavaScript:


(window.scrollBy(0, 700))

I poczekać na załadowanie nowej zawartości za pomocą tego polecenia:


 wait_for_load_state("networkidle")

Krok 5. Używanie proxy z Playwright

Instagram ma ścisłe limity szybkości i środki zapobiegające botom. Aby uniknąć zablokowania, można użyć serwerów proxy do rotacji adresów IP i dystrybucji żądań. Playwright ułatwia integrację serwerów proxy z automatyzacją skrobania.

Wdrażanie serwerów proxy w Playwright:


async def scrape_with_proxy():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=False, 
            proxy={"server": "http://your-proxy-server:port"}
        )
        page = await browser.new_page()
        await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
        # Kontynuować skrobanie jak poprzednio...

Playwright obsługuje również proxy przekazywane jako nazwa użytkownika, hasło i przykład serwera podany poniżej.


async def scrape_with_proxy():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=False, 
            proxy={"server": "http://your-proxy-server:port", "username": "username", "password": "password"}
        )
        page = await browser.new_page()
        await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
        # Kontynuować skrobanie jak poprzednio...

Serwery proxy pomagają uniknąć zakazów IP, wyzwań CAPTCHA i zapewniają płynne pobieranie danych z witryn z dużą ilością danych lub witryn z ograniczeniami, takich jak Instagram.

Kompletny kod


import asyncio
from playwright.async_api import async_playwright
from lxml import html
import json

# Funkcja automatyzacji przeglądarki i skrobania dynamicznej zawartości za pomocą serwerów proxy
async def scrape_instagram(profile_url, proxy=None):
    async with async_playwright() as p:
        # Skonfiguruj przeglądarkę z serwerem proxy, jeśli jest dostępny
        browser_options = {
            'headless': True,  # Użyj przeglądarki z nagłówkiem, aby zobaczyć akcję (można ustawić na True dla trybu bezgłowego)
        }
        if proxy:
            browser_options['proxy'] = proxy

        # Uruchom przeglądarkę
        browser = await p.chromium.launch(**browser_options)
        page = await browser.new_page()

        # Odwiedź stronę profilu na Instagramie
        await page.goto(profile_url, wait_until="networkidle")
        
        # Spróbuj kliknąć przycisk "Pokaż więcej postów" (opcjonalnie, może się nie udać, jeśli przycisk nie zostanie znaleziony).
        try:
           await page.click('button:has-text("Show more posts from")')
        except Exception as e:
           print(f"No 'Show more posts' button found: {e}")


        # Przewiń stronę, aby załadować więcej postów
        scroll_count = 5  # Liczba przewinięć do załadowania postów
        for _ in range(scroll_count):
            await page.evaluate('window.scrollBy(0, 500);')
            await page.wait_for_timeout(3000)  # Wait for new posts to load
            await page.wait_for_load_state("networkidle")

        # Uzyskaj pełną zawartość strony po przewinięciu
        content = await page.content()
        await browser.close()  # Po zakończeniu zamknij przeglądarkę
        
        return content

# Funkcja analizująca zawartość strony i wyodrębniająca adresy URL postów.
def extract_post_urls(page_content):
    # Parsowanie zawartości HTML przy użyciu lxml
    tree = html.fromstring(page_content)
    
    # XPath do wyodrębniania adresów URL postów
    post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
    
    # Wyodrębnianie adresów URL postów przy użyciu XPath
    post_urls = tree.xpath(post_urls_xpath)
    
    # Konwersja względnych adresów URL na bezwzględne adresy URL
    base_url = "https://www.instagram.com"
    post_urls = [f"{base_url}{url}" for url in post_urls]
    
    return post_urls

# Funkcja zapisująca wyodrębnione adresy URL postów w pliku JSON
def save_data(profile_url, post_urls):
    # Struktura danych w formacie JSON
    data = {profile_url: post_urls}
    
    # Zapisywanie danych do pliku
    with open('instagram_posts.json', 'w') as json_file:
        json.dump(data, json_file, indent=4)
    print(f"Data saved to instagram_posts.json")

# Główna funkcja do uruchamiania scrapera i zapisywania danych
async def main():
    # Zdefiniuj adres URL profilu na Instagramie
    profile_url = "https://www.instagram.com/profile name/"
    
    # Opcjonalnie można skonfigurować serwer proxy
    proxy = {"server": "server", "username": "username", "password": "password"}  # Use None if no proxy is required
    
    # Scrape'owanie strony na Instagramie za pomocą serwerów proxy
    page_content = await scrape_instagram(profile_url, proxy=proxy)
    
    # Wyodrębnij adresy URL postów z treści zeskrobanej strony
    post_urls = extract_post_urls(page_content)
    
    # Zapisz wyodrębnione adresy URL postów w pliku JSON
    save_data(profile_url, post_urls)

if __name__ == '__main__':
   asyncio.run(main())

Alternatywne narzędzia do automatyzacji web scrapingu

Podczas gdy Playwright jest doskonałym wyborem do skrobania dynamicznych stron internetowych, inne narzędzia mogą być odpowiednie dla różnych scenariuszy:

  1. Selenium: Selenium jest jednym z najstarszych frameworków do automatyzacji przeglądarek i działa podobnie do Playwright. Jest bardzo wszechstronny, ale brakuje mu niektórych nowoczesnych możliwości, które oferuje Playwright, takich jak obsługa wielu przeglądarek za pomocą jednego interfejsu API;
  2. Puppeteer: Puppeteer to kolejne popularne narzędzie do automatyzacji przeglądarek, zwłaszcza do skrobania stron internetowych z dużą ilością JavaScript. Podobnie jak Playwright, kontroluje przeglądarki bezgłowe i umożliwia interakcję z dynamiczną zawartością;
  3. Requests + BeautifulSoup: dla prostszych stron internetowych, które nie wymagają JavaScript do ładowania treści, biblioteka Requests w połączeniu z BeautifulSoup jest lekką alternatywą. Nie radzi sobie jednak dobrze z dynamiczną zawartością.

Każde narzędzie oferuje unikalne zalety i może być wybrane w oparciu o konkretne potrzeby i warunki projektu.

Do skutecznego skrobania dynamicznych stron internetowych, które aktywnie wykorzystują JavaScript i żądania AJAX, niezbędne są potężne narzędzia zdolne do wydajnej obsługi nieskończonego przewijania i złożonych elementów interaktywnych. Jednym z takich rozwiązań jest Playwright - narzędzie firmy Microsoft, które zapewnia pełną automatyzację przeglądarki, dzięki czemu jest idealnym wyborem dla platform takich jak Instagram. W połączeniu z biblioteką lxml do parsowania HTML, Playwright znacznie upraszcza ekstrakcję danych, pozwalając na automatyzację interakcji z elementami strony i proces parsowania bez ręcznej interwencji. Dodatkowo, wykorzystanie serwerów proxy pomaga obejść ochronę przed botami i zapobiega blokowaniu IP, zapewniając stabilne i nieprzerwane operacje skrobania.

Komentarze:

0 komentarze