Para recopilar los titulares de las noticias más recientes, monitorizar las tendencias de las noticias y realizar análisis de sentimiento sobre temas de actualidad, el scraping de Google News demuestra ser una herramienta inestimable. En este artículo, te guiaremos a través del proceso de scraping de Google News mediante Python. Emplearemos una biblioteca de peticiones para obtener el contenido de las páginas; lxml para analizar los documentos HTML y extraer los datos necesarios. Al final de este tutorial, aprenderás a extraer titulares de noticias y sus respectivos enlaces de Google News en formato JSON estructurado.
Antes de empezar, asegúrate de que tienes Python instalado en tu sistema. Puedes instalar las librerías necesarias ejecutando los siguientes comandos:
pip install requests
pip install lxml
Estas librerías nos permitirán realizar peticiones HTTP y parsear el contenido HTML de la página web.
Vamos a scrapear la página de Google News en la siguiente URL:
URL = "https://news.google.com/topics/CAAqKggKIiRDQkFTRlFvSUwyMHZNRGRqTVhZU0JXVnVMVWRDR2dKSlRpZ0FQAQ?hl=en-US&gl=US&ceid=US%3Aen"
Esta página contiene múltiples noticias, cada una con un titular principal y artículos relacionados. La estructura XPath para estos artículos es la siguiente:
La estructura HTML de Google Noticias se mantiene coherente en las distintas páginas, lo que garantiza que los elementos XPath especificados sean aplicables universalmente.
Empezaremos obteniendo el contenido de la página de Google News utilizando la biblioteca de peticiones. Aquí está el código para obtener el contenido de la página:
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}")
Este código envía una solicitud GET a la URL de Google Noticias y almacena el contenido HTML de la página en la variable page_content.
Con el contenido HTML en la mano, podemos utilizar lxml para analizar la página y extraer los titulares de las noticias y los enlaces.
from lxml import html
# Analizar el contenido HTML
parser = html.fromstring(page_content)
Google Noticias organiza sus artículos en contenedores específicos. Primero extraeremos estos contenedores usando su XPath y luego iteraremos a través de ellos para extraer los titulares y enlaces individuales de las noticias.
Los principales artículos de noticias se encuentran bajo el siguiente XPath:
main_news_elements = parser.xpath('//c-wiz[@jsrenderer="ARwRbe"]')
Ahora podemos recorrer los 10 primeros elementos válidos y extraer los títulos y enlaces:
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:]
# Asegurarse de que los datos existen antes de añadirlos a la lista
if title and link:
news_data.append({
"main_title": title,
"main_link": link,
})
El elemento principal de noticias tiene subsecciones donde hay noticias relacionadas. Podemos extraerlas utilizando un enfoque similar:
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
})
Después de extraer los datos, podemos guardarlos en un archivo JSON para su uso posterior.
import json
with open('google_news_data.json', 'w') as f:
json.dump(news_data, f, indent=4)
Este código creará un archivo llamado google_news_data.json que contendrá todos los titulares de noticias raspados y sus enlaces correspondientes.
Al raspar grandes cantidades de datos, especialmente de sitios con mucho tráfico como Google News, puedes encontrarte con problemas como el bloqueo de IP o la limitación de velocidad. Para evitarlo, puedes utilizar proxies. Los proxies te permiten dirigir tus solicitudes a través de diferentes direcciones IP, lo que dificulta que el sitio web detecte y bloquee tus actividades de scraping.
Para este tutorial, puedes utilizar un proxy modificando la llamada requests.get:
proxies = {
"http": "http://your_proxy_ip:port",
"https": "https://your_proxy_ip:port",
}
response = requests.get(url, proxies=proxies)
Si está trabajando con un proveedor de servicios que gestiona la rotación de proxy, sólo tiene que configurar el servicio en sus solicitudes. El proveedor se encargará de la rotación y la gestión del grupo de IP en su extremo.
A veces, los sitios web pueden bloquear las solicitudes que no tienen las cabeceras adecuadas, como una cadena de agente de usuario que identifica la solicitud como procedente de un navegador. Puedes personalizar tus cabeceras para evitar ser detectado:
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)
Aquí tienes el código completo, combinando todos los pasos:
import requests
import urllib3
from lxml import html
import json
urllib3.disable_warnings()
# URL y cabeceras
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',
}
# Configuración de proxies (sustitúyalo por los datos de su proxy)
proxy = 'ip:port'
proxies = {
"http": f"http://{proxy}",
"https": f"https://{proxy}",
}
# Obtener el contenido de la página con los encabezados y proxies especificados
response = requests.get(url, headers=headers, proxies=proxies, verify=False)
# Comprobar si la solicitud se ha realizado correctamente
if response.status_code == 200:
page_content = response.content
else:
print(f"Failed to retrieve the page. Status code: {response.status_code}")
exit()
# Analiza el contenido HTML con lxml
parser = html.fromstring(page_content)
# Extraer las principales noticias y artículos relacionados
main_news_elements = parser.xpath('//*[@id="i10-panel"]/c-wiz/c-wiz')
# Inicializar una lista para almacenar los datos de noticias extraídos
news_data = []
# Recorrer en bucle cada elemento principal de las noticias
for element in main_news_elements[:10]:
# Extraer el título y el enlace de la noticia principal
title = element.xpath('.//c-wiz/div/article/a/text()')
link = element.xpath('.//c-wiz/div/article/a/@href')
# Inicializar una lista para almacenar los artículos relacionados con esta noticia principal
related_articles = []
# Extraer elementos de noticias relacionados dentro del mismo bloque
related_news_elements = element.xpath('.//c-wiz/div/div/article')
# Recorre en bucle cada elemento de noticia relacionado y extrae el título y el enlace
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})
# Añade la noticia principal y sus artículos relacionados a la lista 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
# Guardar los datos extraídos en un archivo 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')
El scraping de Google News mediante Python, junto con las bibliotecas requests y lxml, facilita el análisis detallado de las tendencias de las noticias. Implementar proxies y configurar las cabeceras de las peticiones es crucial para evitar bloqueos y mantener la estabilidad del scraper. Los proxies ideales para este fin incluyen proxies de centros de datos IPv4 e IPv6 y proxies ISP, que ofrecen altas velocidades y bajo ping. Además, los proxies residenciales dinámicos son muy eficaces debido a su factor de confianza superior.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.com!
Comentarios: 0