Guide pour le scraping de Google News avec Python

Commentaires: 0

Pour recueillir les titres les plus récents, suivre les tendances de l'actualité et effectuer une analyse des sentiments sur des sujets d'actualité, le scraping de Google News s'avère être un outil inestimable. Dans cet article, nous allons vous guider à travers le processus de scraping de Google News à l'aide de Python. Nous utiliserons une bibliothèque de requêtes pour obtenir le contenu des pages ; lxml pour analyser les documents HTML et extraire les données nécessaires. À la fin de ce tutoriel, vous apprendrez comment extraire les titres des nouvelles et leurs liens respectifs de Google News dans un format JSON structuré.

Étape 1: configuration de l'environnement

Avant de commencer, assurez-vous que Python est installé sur votre système. Vous pouvez installer les bibliothèques nécessaires en exécutant les commandes suivantes :

pip install requests 
pip install lxml

Ces bibliothèques nous permettront d'effectuer des requêtes HTTP et d'analyser le contenu HTML de la page web.

Étape 2: comprendre l'URL cible et la structure XPath

Nous allons récupérer la page Google News à l'URL suivante :

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

Cette page contient plusieurs nouvelles, chacune avec un titre principal et des articles connexes. La structure XPath de ces articles est la suivante:

  • Conteneur de nouvelles principales: //c-wiz[@jsrenderer="ARwRbe"]
  • Titre de l'actualité principale: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/article/a/text()
  • Lien principal d'information: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/article/a/@href
  • Conteneur de nouvelles connexes: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/div/article/
  • Titre d'actualité connexe: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/div/article/a/text()
  • Lien d'actualité connexe: //c-wiz[@jsrenderer="ARwRbe"]/c-wiz/div/div/article/a/@href

La structure HTML de Google Actualités reste cohérente d'une page à l'autre, ce qui garantit que les éléments XPath spécifiés sont applicables de manière universelle.

Étape 3: récupération du contenu de Google Actualités

Nous allons commencer par récupérer le contenu de la page Google News à l'aide de la bibliothèque de requêtes. Voici le code permettant de récupérer le contenu de la page :

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}")

Ce code envoie une requête GET à l'URL de Google News et stocke le contenu HTML de la page dans la variable page_content.

Etape 4: Analyse du contenu HTML avec lxml

Avec le contenu HTML en main, nous pouvons utiliser lxml pour analyser la page et extraire les titres et les liens des actualités.

from lxml import html

# Analyse du contenu HTML
parser = html.fromstring(page_content)

Etape 5: Extraction des données d'actualités

Google News organise ses articles dans des conteneurs spécifiques. Nous allons d'abord extraire ces conteneurs à l'aide de leur XPath, puis itérer à travers eux pour extraire les titres et les liens individuels des actualités.

Extraction des principaux articles

Les principaux articles d'actualité se trouvent sous le XPath suivant :

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

Nous pouvons maintenant parcourir les 10 premiers éléments valides et extraire les titres et les liens :

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:]

    
    # S'assurer que les données existent avant de les ajouter à la liste
    if title and link:
        news_data.append({
        "main_title": title,
        "main_link": link,
    })

Extraction d'articles connexes à l'intérieur de chaque nouvel élément principal

L'élément principal des nouvelles comporte des sous-sections dans lesquelles se trouvent des nouvelles connexes. Nous pouvons les extraire en utilisant une approche similaire :

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
})

Etape 6: Enregistrement des données sous forme de JSON

Après avoir extrait les données, nous pouvons les enregistrer dans un fichier JSON pour une utilisation ultérieure.

import json

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

Ce code créera un fichier nommé google_news_data.json contenant tous les titres d'actualités récupérés et leurs liens correspondants.

Utilisation de proxys

Lorsque vous récupérez de grandes quantités de données, en particulier à partir de sites à fort trafic comme Google News, vous pouvez rencontrer des problèmes tels que le blocage d'IP ou la limitation de débit. Pour éviter cela, vous pouvez utiliser des proxys. Les proxys vous permettent d'acheminer vos demandes via différentes adresses IP, ce qui complique la détection et le blocage de vos activités de scraping par le site web.

Pour ce tutoriel, vous pouvez utiliser un proxy en modifiant l'appel requests.get :

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

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

Si vous travaillez avec un fournisseur de services qui gère la rotation des proxy, vous n'avez qu'à configurer le service dans vos demandes. Le fournisseur s'occupera de la rotation et de la gestion du pool d'IP de son côté.

Personnaliser les en-têtes de requête

Il arrive que les sites web bloquent les requêtes qui ne comportent pas les en-têtes appropriés, tels que la chaîne user-agent qui identifie la requête comme provenant d'un navigateur. Vous pouvez personnaliser vos en-têtes pour éviter d'être détecté :

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)

Exemple complet de code

Voici le code complet, combinant toutes les étapes :

import requests
import urllib3
from lxml import html
import json

urllib3.disable_warnings()

# URL et en-têtes
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',
}

# Configuration des proxy (remplacer par les détails de votre proxy)
proxy = 'ip:port'
proxies = {
   "http": f"http://{proxy}",
   "https": f"https://{proxy}",
}

# Récupérer le contenu de la page avec les en-têtes et les mandataires spécifiés
response = requests.get(url, headers=headers, proxies=proxies, verify=False)

# Vérifier si la demande a abouti
if response.status_code == 200:
   page_content = response.content
else:
   print(f"Failed to retrieve the page. Status code: {response.status_code}")
   exit()

# Analyse du contenu HTML à l'aide de lxml
parser = html.fromstring(page_content)

# Extraire les principales nouvelles et les articles connexes
main_news_elements = parser.xpath('//*[@id="i10-panel"]/c-wiz/c-wiz')

# Initialiser une liste pour stocker les données d'actualité extraites
news_data = []

# Passer en boucle sur chaque élément principal de l'actualité
for element in main_news_elements[:10]:
   # Extraire le titre et le lien de la nouvelle principale
   title = element.xpath('.//c-wiz/div/article/a/text()')
   link = element.xpath('.//c-wiz/div/article/a/@href')

   # Initialisation d'une liste pour stocker les articles liés à cette actualité principale
   related_articles = []

   # Extraire des éléments d'information connexes au sein d'un même bloc
   related_news_elements = element.xpath('.//c-wiz/div/div/article')

   # Passer en revue chaque élément d'information connexe et en extraire le titre et le lien.
   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})

   # Ajouter la nouvelle principale et ses articles connexes à la liste 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


# Enregistrer les données extraites dans un fichier 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')

Le scrapping de Google News à l'aide de Python, ainsi que des bibliothèques requests et lxml, facilite l'analyse détaillée des tendances de l'actualité. La mise en œuvre de proxys et la configuration des en-têtes de requête sont cruciales pour éviter les blocages et maintenir la stabilité du scraper. Les proxys idéaux à cette fin sont les proxys IPv4 et IPv6 des centres de données et les proxys des fournisseurs d'accès à Internet, qui offrent des vitesses élevées et un faible ping. En outre, les proxys résidentiels dynamiques sont très efficaces en raison de leur facteur de confiance supérieur.

Commentaires:

0 Commentaires