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.
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.
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:
Struktura HTML Google News pozostaje spójna na różnych stronach, zapewniając, że określone elementy XPath mają uniwersalne zastosowanie.
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.
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)
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.
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,
})
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
})
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.
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.
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)
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