Przewodnik po skrobaniu Google News za pomocą Pythona

Komentarze: 0

W gromadzeniu najnowszych nagłówków wiadomości, monitorowaniu trendów w wiadomościach i przeprowadzaniu analizy nastrojów w bieżących sprawach, skrobanie Google News okazuje się być nieocenionym narzędziem. W tym artykule przeprowadzimy Cię przez proces skrobania Google News za pomocą Pythona. Wykorzystamy bibliotekę żądań do uzyskania zawartości strony; lxml do analizowania dokumentów HTML i wyodrębniania potrzebnych danych. Pod koniec tego samouczka dowiesz się, jak wyodrębnić nagłówki wiadomości i odpowiednie linki z Google News do ustrukturyzowanego formatu JSON.

Krok 1: Konfiguracja środowiska

Zanim zaczniemy, upewnij się, że masz zainstalowany Python w swoim systemie. Wymagane biblioteki można zainstalować, uruchamiając następujące polecenia:

pip install requests 
pip install lxml

Biblioteki te pozwolą nam wykonywać żądania HTTP i analizować zawartość HTML strony internetowej.

Krok 2: Zrozumienie docelowego adresu URL i struktury XPath

Będziemy skrobać stronę Google News pod następującym adresem URL:

URL = "https://news.google.com/topics/CAAqKggKIiRDQkFTRlFvSUwyMHZNRGRqTVhZU0JXVnVMVWRDR2dKSlRpZ0FQAQ?hl=en-US&gl=US&ceid=US%3Aen"

Ta strona zawiera wiele wiadomości, każda z głównym nagłówkiem i powiązanymi artykułami. Struktura XPath dla tych elementów jest następująca:

  • Główny pojemnik na wiadomości: //c-wiz[@jsrenderer="ARwRbe"]
  • Główny tytuł wiadomości: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/article/a/text()
  • Główny link do wiadomości: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/article/a/@href
  • Powiązany pojemnik na wiadomości: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/div/article/
  • Tytuł powiązanej wiadomości: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/div/article/a/text()
  • Powiązany link do wiadomości: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/div/article/a/@href

Struktura HTML Google News pozostaje spójna na różnych stronach, zapewniając, że określone elementy XPath mają uniwersalne zastosowanie.

Krok 3: Pobieranie treści Google News

Zaczniemy od pobrania zawartości strony Google News za pomocą biblioteki żądań. Oto kod pobierający zawartość strony:

import requests

url = "https://news.google.com/topics/CAAqKggKIiRDQkFTRlFvSUwyMHZNRGRqTVhZU0JXVnVMVWRDR2dKSlRpZ0FQAQ?hl=en-US&gl=US&ceid=US%3Aen"
response = requests.get(url)

if response.status_code == 200:
    page_content = response.content
else:
    print(f"Failed to retrieve the page. Status code: {response.status_code}")

Ten kod wysyła żądanie GET do adresu URL Google News i przechowuje zawartość HTML strony w zmiennej page_content.

Krok 4: Parsowanie zawartości HTML za pomocą lxml

Mając w ręku zawartość HTML, możemy użyć lxml do przeanalizowania strony i wyodrębnienia nagłówków wiadomości i linków.

from lxml import html

# Parsowanie zawartości HTML
parser = html.fromstring(page_content)

Krok 5: Wyodrębnianie danych wiadomości

Google News organizuje swoje artykuły w określone kontenery. Najpierw wyodrębnimy te kontenery za pomocą ich XPath, a następnie przejdziemy przez nie, aby wyodrębnić poszczególne nagłówki wiadomości i linki.

Wyodrębnianie głównych artykułów wiadomości

Główne artykuły wiadomości znajdują się pod następującym XPath:

main_news_elements = parser.xpath('//c-wiz[@jsrenderer="ARwRbe"]')

Możemy teraz przejść przez pierwsze 10 ważnych elementów i wyodrębnić tytuły i linki:

news_data = []

for element in main_news_elements[:10]:
    title = element.xpath('.//c-wiz/div/article/a/text()')[0]
    link = "https://news.google.com" + element.xpath('.//c-wiz/div/article/a/@href')[0][1:]

    
    # Upewnij się, że dane istnieją przed dodaniem ich do listy.
    if title and link:
        news_data.append({
        "main_title": title,
        "main_link": link,
    })

Wyodrębnianie powiązanych artykułów w każdym nowym elemencie głównym

Główny element wiadomości ma podsekcje, w których znajdują się powiązane wiadomości. Możemy je wyodrębnić przy użyciu podobnego podejścia:

related_articles = []
related_news_elements = element.xpath('.//c-wiz/div/div/article')

for related_element in related_news_elements:
    related_title = related_element.xpath('.//a/text()')[0]
    related_link = "https://news.google.com" + related_element.xpath('.//a/@href')[0][1:]
    related_articles.append({"title": related_title, "link": related_link})

news_data.append({
    "main_title": title,
    "main_link": link,
    "related_articles": related_articles
})

Krok 6: Zapisywanie danych jako JSON

Po wyodrębnieniu danych możemy zapisać je w pliku JSON do późniejszego wykorzystania.

import json

with open('google_news_data.json', 'w') as f:
    json.dump(news_data, f, indent=4)

Ten kod utworzy plik o nazwie google_news_data.json zawierający wszystkie zeskrobane nagłówki wiadomości i odpowiadające im linki.

Używanie serwerów proxy

Podczas skrobania dużych ilości danych, zwłaszcza z witryn o dużym natężeniu ruchu, takich jak Google News, można napotkać problemy, takie jak blokowanie adresów IP lub ograniczanie szybkości. Aby tego uniknąć, można skorzystać z serwerów proxy. Serwery proxy umożliwiają kierowanie żądań przez różne adresy IP, utrudniając witrynie wykrycie i zablokowanie działań związanych ze skrobaniem.

W tym samouczku można użyć serwera proxy, modyfikując wywołanie requests.get:

proxies = {
    "http": "http://your_proxy_ip:port",
    "https": "https://your_proxy_ip:port",
}

response = requests.get(url, proxies=proxies)

Jeśli pracujesz z dostawcą usług, który zarządza rotacją proxy, musisz tylko skonfigurować usługę w swoich żądaniach. Dostawca zajmie się rotacją i zarządzaniem pulą IP po swojej stronie.

Dostosowywanie nagłówków żądań

Czasami strony internetowe mogą blokować żądania, które nie mają odpowiednich nagłówków, takich jak ciąg agenta użytkownika, który identyfikuje żądanie jako pochodzące z przeglądarki. Możesz dostosować nagłówki, aby uniknąć wykrycia:

headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'priority': 'u=0, i',
    'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
    'sec-ch-ua-arch': '"x86"',
    'sec-ch-ua-bitness': '"64"',
    'sec-ch-ua-full-version-list': '"Not)A;Brand";v="99.0.0.0", "Google Chrome";v="127.0.6533.72", "Chromium";v="127.0.6533.72"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-model': '""',
    'sec-ch-ua-platform': '"Linux"',
    'sec-ch-ua-platform-version': '"6.5.0"',
    'sec-ch-ua-wow64': '?0',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}

response = requests.get(url, headers=headers)

Pełny przykład kodu

Oto pełny kod, łączący wszystkie kroki:

import requests
import urllib3
from lxml import html
import json

urllib3.disable_warnings()

# Adres URL i nagłówki
url = "https://news.google.com/topics/CAAqKggKIiRDQkFTRlFvSUwyMHZNRGRqTVhZU0JXVnVMVWRDR2dKSlRpZ0FQAQ?hl=en-US&gl=US&ceid=US%3Aen"
headers = {
   'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
   'accept-language': 'en-IN,en;q=0.9',
   'cache-control': 'no-cache',
   'dnt': '1',
   'pragma': 'no-cache',
   'priority': 'u=0, i',
   'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
   'sec-ch-ua-arch': '"x86"',
   'sec-ch-ua-bitness': '"64"',
   'sec-ch-ua-full-version-list': '"Not)A;Brand";v="99.0.0.0", "Google Chrome";v="127.0.6533.72", "Chromium";v="127.0.6533.72"',
   'sec-ch-ua-mobile': '?0',
   'sec-ch-ua-model': '""',
   'sec-ch-ua-platform': '"Linux"',
   'sec-ch-ua-platform-version': '"6.5.0"',
   'sec-ch-ua-wow64': '?0',
   'sec-fetch-dest': 'document',
   'sec-fetch-mode': 'navigate',
   'sec-fetch-site': 'none',
   'sec-fetch-user': '?1',
   'upgrade-insecure-requests': '1',
   'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}

# Konfiguracja serwerów proxy (zastąp danymi serwera proxy)
proxy = 'ip:port'
proxies = {
   "http": f"http://{proxy}",
   "https": f"https://{proxy}",
}

# Pobiera zawartość strony z określonymi nagłówkami i serwerami proxy
response = requests.get(url, headers=headers, proxies=proxies, verify=False)

# Sprawdź, czy żądanie się powiodło
if response.status_code == 200:
   page_content = response.content
else:
   print(f"Failed to retrieve the page. Status code: {response.status_code}")
   exit()

# Parsowanie zawartości HTML przy użyciu lxml
parser = html.fromstring(page_content)

# Wyodrębnij najważniejsze wiadomości i powiązane artykuły
main_news_elements = parser.xpath('//*[@id="i10-panel"]/c-wiz/c-wiz')

# Zainicjuj listę do przechowywania wyodrębnionych danych wiadomości
news_data = []

# Pętla przez każdy główny element wiadomości
for element in main_news_elements[:10]:
   # Wyodrębnij główny tytuł wiadomości i link
   title = element.xpath('.//c-wiz/div/article/a/text()')
   link = element.xpath('.//c-wiz/div/article/a/@href')

   # Zainicjuj listę do przechowywania powiązanych artykułów dla tej głównej wiadomości
   related_articles = []

   # Wyodrębnianie powiązanych elementów wiadomości w tym samym bloku
   related_news_elements = element.xpath('.//c-wiz/div/div/article')

   # Przeprowadź pętlę przez każdy powiązany element wiadomości i wyodrębnij tytuł i link.
   for related_element in related_news_elements:
       related_title = related_element.xpath('.//a/text()')[0]
       related_link = "https://news.google.com" + related_element.xpath('.//a/@href')[0][1:]
       related_articles.append({"title": related_title, "link": related_link})

   # Dodanie głównego newsa i powiązanych z nim artykułów do listy news_data
   if title is not None:
       news_data.append({
           "main_title": title,
           "main_link": f'https://news.google.com{link}',
           "related_articles": related_articles
       })
   else:
       continue


# Zapisz wyodrębnione dane do pliku JSON
with open("google_news_data.json", "w") as json_file:
   json.dump(news_data, json_file, indent=4)

print('Data extraction complete. Saved to google_news_data.json')

Skrobanie Google News za pomocą Pythona, wraz z bibliotekami requests i lxml, ułatwia szczegółową analizę trendów w wiadomościach. Wdrożenie serwerów proxy i skonfigurowanie nagłówków żądań ma kluczowe znaczenie dla uniknięcia blokad i utrzymania stabilności scrapera. Idealne serwery proxy do tego celu obejmują serwery proxy centrów danych IPv4 i IPv6 oraz serwery proxy dostawców usług internetowych, które oferują wysokie prędkości i niski ping. Ponadto, dynamiczne serwery proxy są bardzo skuteczne ze względu na ich wysoki współczynnik zaufania.

Komentarze:

0 komentarze