Przewodnik po skrobaniu stron internetowych w Python dla początkujących

Komentarze: 0

Python wyróżnia się jako najlepszy wybór do skrobania stron internetowych ze względu na solidne biblioteki i prostą składnię. W tym artykule zbadamy podstawy skrobania stron internetowych i poprowadzimy Cię przez konfigurację środowiska Python, aby stworzyć swój pierwszy skrobak internetowy. Przedstawimy kluczowe biblioteki Pythona odpowiednie do zadań skrobania, w tym Beautiful Soup, Playwright i lxml.

Biblioteki Pythona do skrobania stron internetowych

Python udostępnia kilka bibliotek ułatwiających skrobanie stron internetowych. Oto niektóre z najczęściej używanych:

  • requests: prosta i elegancka biblioteka HTTP dla Pythona, używana do wysyłania żądań HTTP w celu pobierania stron internetowych.
  • Beautiful Soup: świetnie nadaje się do analizowania dokumentów HTML i XML. Tworzy drzewa parsowania z kodu źródłowego strony, które ułatwiają wyodrębnianie danych.
  • lxml: lxml, znany ze swojej szybkości i wydajności, doskonale nadaje się do analizowania dokumentów XML i HTML.
  • Playwright: solidne narzędzie do dynamicznego skrobania treści i interakcji ze stronami internetowymi.

Wprowadzenie do żądań HTTP

HTTP (HyperText Transfer Protocol) to protokół warstwy aplikacji służący do przesyłania danych w sieci. Użytkownik wpisuje adres URL w przeglądarce, która generuje żądanie HTTP i wysyła je do serwera WWW. Serwer WWW odsyła następnie odpowiedź HTTP do przeglądarki, która jest renderowana jako strona HTML. W przypadku skrobania stron internetowych należy naśladować ten proces i generować żądania HTTP ze skryptu, aby programowo uzyskać zawartość HTTP stron internetowych.

Konfiguracja środowiska

Po pierwsze, upewnij się, że Python jest zainstalowany w systemie. Można go pobrać z oficjalnej strony Pythona.

Środowisko wirtualne pomaga zarządzać zależnościami. Użyj tych poleceń, aby utworzyć i aktywować środowisko wirtualne:


python -m venv scraping_env
source scraping_env/bin/activate

Następnie zainstaluj wymagane pakiety za pomocą poniższych poleceń:


pip install requests
pip install beautifulsoup4 
pip install lxml

Budowanie web scrapera za pomocą Beautiful Soup

Zacznijmy od prostego skrobaka internetowego wykorzystującego żądanie do skrobania statycznej zawartości HTML.

Wykonywanie żądania HTTP GET

Najpopularniejszym typem żądania HTTP jest żądanie GET, które służy do pobierania danych z określonego adresu URL. Oto podstawowy przykład wykonania żądania GET do http://example.com.


import requests
url = 'http://example.com'
response = requests.get(url)

Obsługa odpowiedzi HTTP

Biblioteka żądań zapewnia kilka sposobów obsługi i przetwarzania odpowiedzi:

Sprawdź kod statusu: upewnij się, że żądanie powiodło się.


if response.status_code == 200:
    print('Request was successful!')
else:
    print('Request failed with status code:', response.status_code)

Wyodrębnianie zawartości: wyodrębnianie zawartości tekstowej lub JSON z odpowiedzi.


# Pobierz treść odpowiedzi jako tekst
page_content = response.text
print(page_content)

# Pobierz zawartość odpowiedzi jako JSON (jeśli odpowiedź jest w formacie JSON)
json_content = response.json()
print(json_content)

Obsługa błędów HTTP i błędów sieciowych

Błędy HTTP i sieciowe mogą wystąpić, gdy zasób nie jest osiągalny, żądanie przekroczyło limit czasu lub serwer zwrócił błędny status HTTP (np. 404 Not Found, 500 Internal Server Error). Do obsługi takich sytuacji możemy użyć obiektów wyjątków zgłaszanych przez żądania.


import requests

url = 'http://example.com'

try:
    response = requests.get(url, timeout=10)  # Set a timeout for the request
    response.raise_for_status()  # Raises an HTTPError for bad responses
except requests.exceptions.HTTPError as http_err:
    print(f'HTTP error occurred: {http_err}')
except requests.exceptions.ConnectionError:
    print('Failed to connect to the server.')
except requests.exceptions.Timeout:
    print('The request timed out.')
except requests.exceptions.RequestException as req_err:
    print(f'Request error: {req_err}')
else:
    print('Request was successful!')

Wyodrębnianie danych z elementów HTML

W przypadku skrobania stron internetowych często musimy wyodrębnić dane z treści HTML. W tej części omówimy, jak zlokalizować i wyodrębnić dane z elementów HTML za pomocą niektórych bibliotek, takich jak Beautiful Soup lub lxml.

HTML (HyperText Markup Language) jest standardowym językiem znaczników służącym do tworzenia stron internetowych. Składa się z zagnieżdżonych elementów reprezentowanych przez znaczniki, takie jak <div>, <p>, <a> itp. Każdy znacznik może mieć atrybuty i zawierać tekst, inne znaczniki lub jedno i drugie.

Selektory XPath i CSS zapewniają wszechstronny sposób wybierania elementów HTML na podstawie ich atrybutów lub pozycji w dokumencie.

Znajdowanie selektorów XPath i CSS

Podczas skrobania stron internetowych, wyodrębnianie określonych danych ze stron internetowych często wymaga zidentyfikowania poprawnych selektorów XPath lub CSS do kierowania elementów HTML. Oto jak skutecznie znaleźć te selektory:

Większość nowoczesnych przeglądarek internetowych posiada wbudowane narzędzia programistyczne, które umożliwiają sprawdzenie struktury HTML stron internetowych. Oto przewodnik krok po kroku, jak korzystać z tych narzędzi:

  1. Otwarte narzędzia deweloperskie:
    • W przeglądarce Chrome: Kliknij stronę prawym przyciskiem myszy i wybierz "Sprawdź" lub naciśnij Ctrl+Shift+I (Windows/Linux) lub Cmd+Opt+I (Mac).
    • W przeglądarce Firefox: Kliknij prawym przyciskiem myszy na stronie i wybierz "Inspect Element" lub naciśnij Ctrl+Shift+I (Windows/Linux) lub Cmd+Opt+I (Mac).
  2. Sprawdź element:
    • Użyj narzędzia inspekcji (ikona kursora), aby najechać kursorem i kliknąć element, który chcesz zeskrobać. Spowoduje to podświetlenie elementu w widoku struktury HTML.
  3. Kopiuj XPath lub selektor CSS:
    • Kliknij prawym przyciskiem myszy podświetlony element HTML w panelu narzędzi deweloperskich.
    • Wybierz "Kopiuj", a następnie "Kopiuj XPath" lub "Kopiuj selektor" (selektor CSS).

1n.png

XPath: /html/body/div/h1

CSS Selector: body > div > h1

Ekstrakcja przy użyciu Beautiful Soup

Beautiful Soup to biblioteka Pythona do analizowania dokumentów HTML i XML. Zapewnia proste metody i atrybuty do nawigacji i przeszukiwania struktury HTML.


from bs4 import BeautifulSoup
import requests

# Adres URL strony internetowej do zeskrobania
url = 'https://example.com'

# Wyślij żądanie HTTP GET do adresu URL
response = requests.get(url)

# Przeanalizuj zawartość HTML odpowiedzi za pomocą Beautiful Soup
soup = BeautifulSoup(response.content, 'html.parser')

# Użyj selektora CSS, aby znaleźć wszystkie znaczniki <h1>, które znajdują się wewnątrz znaczników <div>
# które są bezpośrednimi dziećmi znacznika <body>.
h1_tags = soup.select('body > div > h1')

# Iteruj po liście znalezionych tagów <h1> i wypisz ich zawartość tekstową
for tag in h1_tags:
    print(tag.text)

Obsługa błędów parsowania

Błędy parsowania występują, gdy struktura HTML lub XML nie jest zgodna z oczekiwaniami, powodując problemy z ekstrakcją danych. Można nimi zarządzać poprzez obsługę wyjątków, takich jak AttributeError.


from bs4 import BeautifulSoup
import requests

# Adres URL strony internetowej do zeskrobania
url = 'https://example.com'

# Wyślij żądanie HTTP GET do adresu URL
response = requests.get(url)

try:
    # Przeanalizuj zawartość HTML odpowiedzi za pomocą Beautiful Soup
    soup = BeautifulSoup(response.content, 'html.parser')

    # Użyj selektora CSS, aby znaleźć wszystkie znaczniki <h1>, które znajdują się wewnątrz znaczników <div>
    # które są bezpośrednimi dziećmi znacznika <body>.
    h1_tags = soup.select('body > div > h1')

    # Iteruj po liście znalezionych tagów <h1> i wypisz ich zawartość tekstową
    for tag in h1_tags:
        print(tag.text)
except AttributeError as attr_err:
    # Obsługa przypadków, w których może wystąpić błąd AttributeError (np. jeśli response.content to None).
    print(f'Attribute error occurred: {attr_err}')
except Exception as parse_err:
    # Obsługuje wszelkie inne wyjątki, które mogą wystąpić podczas parsowania.
    print(f'Error while parsing HTML: {parse_err}')

Ekstrakcja przy użyciu lxml

Oprócz Beautiful Soup, inną popularną biblioteką do parsowania dokumentów HTML i XML w Pythonie jest lxml. Podczas gdy BeautifulSoup koncentruje się na zapewnieniu wygodnego interfejsu do nawigacji i manipulowania przeanalizowanymi danymi, lxml jest znany ze swojej szybkości i elastyczności, co czyni go preferowanym wyborem do zadań o krytycznym znaczeniu dla wydajności.


from lxml.html import fromstring
import requests

# Adres URL strony internetowej do zeskrobania
url = 'https://example.com'

# Wyślij żądanie HTTP GET do adresu URL
response = requests.get(url)

# Parsowanie zawartości HTML odpowiedzi przy użyciu metody fromstring lxml
parser = fromstring(response.text)

# Użyj XPath, aby znaleźć zawartość tekstową pierwszego znacznika <h1>
# który znajduje się wewnątrz znacznika <div>, który jest bezpośrednim dzieckiem znacznika <body>.
title = parser.xpath('/html/body/div/h1/text()')[0]

# Drukuj tytuł
print(title)

Obsługa błędów parsowania

Podobnie jak w przypadku Beautiful Soup, lxml pozwala na sprawną obsługę błędów parsowania poprzez wychwytywanie wyjątków takich jak lxml.etree.XMLSyntaxError.


from lxml.html import fromstring
from lxml import etree
import requests

# Adres URL strony internetowej do zeskrobania
url = 'https://example.com'

# Wyślij żądanie HTTP GET do adresu URL
response = requests.get(url)

try:
    # Parsowanie zawartości HTML odpowiedzi przy użyciu metody fromstring lxml
    parser = fromstring(response.text)

    # Użyj XPath, aby znaleźć zawartość tekstową pierwszego znacznika <h1>
    # który znajduje się wewnątrz znacznika <div>, który jest bezpośrednim dzieckiem znacznika <body>.
    title = parser.xpath('/html/body/div/h1/text()')[0]

    # Drukuj tytuł
    print(title)
except IndexError:
    # Obsługa przypadku, gdy zapytanie XPath nie zwraca żadnych wyników
    print('No <h1> tag found in the specified location.')
except etree.XMLSyntaxError as parse_err:
    # Obsługa błędów składni XML podczas parsowania
    print(f'Error while parsing HTML: {parse_err}')
except Exception as e:
    # Obsługa innych wyjątków
    print(f'An unexpected error occurred: {e}')

Zapisywanie wyodrębnionych danych

Po pomyślnym wyodrębnieniu danych z elementów HTML, następnym krokiem jest zapisanie tych danych. Python zapewnia kilka opcji zapisywania wyodrębnionych danych, w tym zapisywanie do plików CSV, plików JSON i baz danych. Oto przegląd sposobów zapisywania wyodrębnionych danych przy użyciu różnych formatów:

Zapisywanie danych do pliku CSV

CSV (Comma-Separated Values) to prosty i szeroko stosowany format przechowywania danych tabelarycznych. Moduł CSV w Pythonie ułatwia zapisywanie danych do plików CSV.


import csv

# Przykładowe dane
data = {
    'title': 'Example Title',
    'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}

# Zapisywanie danych do pliku CSV
with open('scraped_data.csv', mode='w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerow(['Title', 'Paragraph'])
    for paragraph in data['paragraphs']:
        writer.writerow([data['title'], paragraph])

print('Data saved to scraped_data.csv')

Zapisywanie danych do pliku JSON

JSON (JavaScript Object Notation) to lekki format wymiany danych, który jest łatwy do odczytu i zapisu. Moduł JSON w Pythonie zapewnia metody zapisywania danych w formacie JSON.


import json

# Przykładowe dane
data = {
    'title': 'Example Title',
    'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}

# Zapisywanie danych do pliku JSON
with open('scraped_data.json', mode='w', encoding='utf-8') as file:
    json.dump(data, file, ensure_ascii=False, indent=4)

print('Data saved to scraped_data.json')

Zaawansowane techniki skrobania stron internetowych z Playwright

Playwright to potężne narzędzie do skrobania dynamicznej zawartości i interakcji z elementami sieci. Może obsługiwać strony internetowe z dużą ilością skryptów JavaScript, których statyczne parsery HTML nie są w stanie obsłużyć.

Zainstaluj Playwright i skonfiguruj go:


pip install playwright
playwright install

Skrobanie dynamicznej zawartości

Playwright umożliwia interakcję z elementami internetowymi, takimi jak wypełnianie formularzy i klikanie przycisków. Może czekać na zakończenie żądań AJAX przed kontynuowaniem, dzięki czemu idealnie nadaje się do skrobania dynamicznej zawartości.

2n.png

Dostarczony kod wykonuje skrobanie stron internetowych na stronie produktu Amazon przy użyciu Playwright i lxml. Początkowo importowane są niezbędne moduły. Funkcja run jest definiowana w celu hermetyzacji logiki skrobania. Funkcja rozpoczyna się od skonfigurowania serwera proxy i uruchomienia nowej instancji przeglądarki z serwerem proxy i w trybie bezgłowym, co pozwala nam obserwować działania przeglądarki. W kontekście przeglądarki otwierana jest nowa strona i następuje nawigacja do określonego adresu URL produktu Amazon, z limitem czasu wynoszącym 60 sekund, aby zapewnić pełne załadowanie strony.

Następnie skrypt wchodzi w interakcję ze stroną, aby wybrać określony styl produktu z rozwijanego menu i opcję produktu za pomocą lokalizatorów i dopasowywania tekstu. Po upewnieniu się, że te interakcje zostały zakończone, a strona została ponownie w pełni załadowana, zawartość HTML strony jest przechwytywana.

Zawartość HTML jest następnie analizowana przy użyciu metody fromstring lxml w celu utworzenia drzewa elementów. Zapytanie XPath jest używane do wyodrębnienia zawartości tekstowej tytułu produktu z określonego elementu o identyfikatorze productTitle. Skrypt zawiera obsługę błędów w celu zarządzania przypadkami, w których zapytanie XPath nie zwraca wyników, w których występują błędy składni XML podczas parsowania lub inne nieoczekiwane wyjątki. Na koniec wyodrębniony tytuł produktu tlxml jest drukowany, a kontekst przeglądarki i przeglądarka są zamykane w celu zakończenia sesji.

Funkcja run jest wykonywana w ramach sesji Playwright uruchomionej przez sync_playwright, zapewniając, że cały proces jest zarządzany i wykonywany w kontrolowanym środowisku. Struktura ta zapewnia solidność i odporność na błędy podczas wykonywania zadania skrobania stron internetowych.


from playwright.sync_api import Playwright, sync_playwright
from lxml.html import fromstring, etree


def run(playwright: Playwright) -> None:
   # Definiowanie serwera proxy
   proxy = {"server": "https://IP:PORT", "username": "LOGIN", "password": "PASSWORD"}

   # Uruchomienie nowej instancji przeglądarki z określonym proxy i w trybie bezgłowym.
   browser = playwright.chromium.launch(
       headless=False,
       proxy=proxy,
       slow_mo=50,
       args=['--ignore-certificate-errors'],
   )

   # Utwórz nowy kontekst przeglądarki
   context = browser.new_context(ignore_https_errors=True)

   # Otwórz nową stronę w kontekście przeglądarki
   page = context.new_page()

   # Przejście do określonej strony produktu Amazon
   page.goto(
       "https://www.amazon.com/A315-24P-R7VH-Display-Quad-Core-Processor-Graphics/dp/B0BS4BP8FB/",
       timeout=10000,
   )

   # Poczekaj na pełne załadowanie strony
   page.wait_for_load_state("load")

   # Wybierz określony styl produktu z menu rozwijanego
   page.locator("#dropdown_selected_style_name").click()

   # Wybierz konkretną opcję produktu
   page.click('//*[@id="native_dropdown_selected_style_name_1"]')
   page.wait_for_load_state("load")

   # Pobierz zawartość HTML załadowanej strony
   html_content = page.content()

   try:
       # Parsowanie zawartości HTML przy użyciu metody fromstring lxml
       parser = fromstring(html_content)

       # Użyj XPath, aby wyodrębnić zawartość tekstową tytułu produktu
       product_title = parser.xpath('//span[@id="productTitle"]/text()')[0].strip()

       # Drukowanie wyodrębnionego tytułu produktu
       print({"Product Title": product_title})
   except IndexError:
       # Obsługa przypadku, gdy zapytanie XPath nie zwraca żadnych wyników
       print('Product title not found in the specified location.')
   except etree.XMLSyntaxError as parse_err:
       # Obsługa błędów składni XML podczas parsowania
       print(f'Error while parsing HTML: {parse_err}')
   except Exception as e:
       # Obsługa innych wyjątków
       print(f'An unexpected error occurred: {e}')

   # Zamknięcie kontekstu przeglądarki i przeglądarki
   context.close()
   browser.close()


# Użyj sync_playwright, aby uruchomić sesję Playwright i uruchomić skrypt
with sync_playwright() as playwright:
   run(playwright)

Web scraping w Pythonie to potężna metoda pozyskiwania danych ze stron internetowych. Omawiane narzędzia ułatwiają wyodrębnianie, przetwarzanie i przechowywanie danych internetowych do różnych celów. W tym procesie, wykorzystanie serwerów proxy do alternatywnych adresów IP i implementacja opóźnień między żądaniami są kluczowe dla obejścia blokad. Beautiful Soup jest przyjazny dla początkujących użytkowników, podczas gdy lxml nadaje się do obsługi dużych zbiorów danych dzięki swojej wydajności. W przypadku bardziej zaawansowanych potrzeb związanych ze skrobaniem, zwłaszcza w przypadku dynamicznie ładowanych witryn JavaScript, Playwright okazuje się bardzo skuteczny.

Komentarze:

0 komentarze