Para los buscadores de empleo, los empleadores o cualquier persona que siga las tendencias del mercado laboral, el raspado de la lista de empleos disponibles de Indeed podría proporcionar información útil. En este tutorial en particular, combinaremos Playwright para el raspado web y lxml para el análisis de contenido HTML con el fin de recopilar los detalles del trabajo, incluyendo su título, el nombre de la empresa de contratación, la ubicación, la descripción del trabajo, el enlace de publicación del trabajo y, finalmente, presentaremos los hallazgos guardando la información en un archivo CSV.
Para realizar con éxito el scraping es necesario tener instaladas las siguientes librerías de Python.
Playwright para la automatización del navegador:
pip install playwright
lxml para analizar HTML:
pip install lxml
pandas para guardar datos en un archivo CSV:
pip install pandas
Instalar navegadores Playwright:
Después de instalar Playwright, ejecute este comando para instalar los binarios necesarios del navegador:
playwright install
Playwright permite automatizar e interactuar con navegadores web. Comenzamos configurando Playwright para lanzar un navegador Chromium, visitar una página web y extraer su contenido. Aquí también podemos pasar proxies a través del playwright.
¿Por qué usar proxies?
Los sitios web suelen tener medidas de limitación de velocidad o anti-scraping para bloquear las peticiones repetidas desde la misma dirección IP. Los proxies te permiten:
import asyncio
from playwright.async_api import async_playwright
async def get_page_content(url):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False,
proxy = {
'server': '',
'username': '',
'password': ''
}
) # Navegador encabezado
page = await browser.new_page()
await page.goto(url)
# Extraer el contenido de la página
content = await page.content()
await browser.close() # Cierre el navegador cuando haya terminado
return content
En este código, async_playwright inicia un navegador encabezado, navega hasta la URL especificada y obtiene el contenido de la página.
A continuación, analizaremos el contenido de la página para extraer datos significativos. lxml se utiliza para este propósito porque proporciona un soporte robusto para analizar y consultar contenido HTML utilizando XPath.
from lxml import html
def parse_job_listings(content):
# Analizar contenido HTML
parser = html.fromstring(content)
# Extraer cada oferta de empleo mediante XPath
job_posting = parser.xpath('//ul[@class="css-zu9cdh eu4oa1w0"]/li')
jobs_data = []
for element in job_posting[:-1]: # Omitir el último elemento si es un anuncio o irrelevante
title = ''.join(element.xpath('.//h2/a/span/@title'))
if title:
link = ''.join(element.xpath('.//h2/a/@href'))
location = ''.join(element.xpath('.//div[@data-testid="text-location"]/text()'))
description = ', '.join(element.xpath('.//div[@class="css-9446fg eu4oa1w0"]/ul//li/text()'))
company_name = ''.join(element.xpath('.//span[@data-testid="company-name"]/text()'))
# Añadir los datos extraídos a la lista jobs_data
jobs_data.append({
'Title': title,
'Link': f"https://www.indeed.com{link}",
'Location': location,
'Description': description,
'Company': company_name
})
return jobs_data
Ahora que tenemos tanto la automatización del navegador como los pasos de parseo configurados, vamos a combinarlos para scrapear listados de empleo de la página de Indeed.
Explicación:
import pandas as pd
async def scrape_indeed_jobs(url):
# Paso 1: Obtener el contenido de la página con Playwright
content = await get_page_content(url)
# Paso 2: Parsear el HTML y extraer los detalles del trabajo
jobs_data = parse_job_listings(content)
return jobs_data
# URL que se va a raspar
url = 'https://www.indeed.com/q-usa-jobs.html'
# Extracción y almacenamiento de datos
async def main():
# Extraer datos de trabajo de la URL especificada
jobs = await scrape_indeed_jobs(url)
# Paso 3: Guardar los datos en CSV utilizando pandas
df = pd.DataFrame(jobs)
df.to_csv('indeed_jobs.csv', index=False)
print("Data saved to indeed_jobs.csv")
# Ejecutar la función principal
asyncio.run(main())
Indeed pagina sus listados de empleo, y puedes extender fácilmente el scraper para manejar múltiples páginas. La URL de la página se ajusta usando un parámetro de consulta start, que se incrementa en 10 por cada nueva página.
Para mejorar la funcionalidad de su scraper para recopilar datos de múltiples páginas, puede implementar una función llamada scrape_multiple_pages. Esta función modificará la URL base ajustando de forma incremental el parámetro de inicio, permitiendo el acceso a las páginas posteriores. Al progresar sistemáticamente a través de cada página, puede ampliar el alcance y la cantidad de datos recopilados, como las vacantes, lo que garantiza un conjunto de datos más completo.
async def scrape_multiple_pages(base_url, pages=3):
all_jobs = []
for page_num in range(pages):
# Actualizar URL para paginación
url = f"{base_url}&start={page_num * 10}"
print(f"Scraping page: {url}")
# Extraer datos de trabajo de cada página
jobs = await scrape_indeed_jobs(url)
all_jobs.extend(jobs)
# Guardar todos los trabajos en CSV
df = pd.DataFrame(all_jobs)
df.to_csv('indeed_jobs_all_pages.csv', index=False)
print("Data saved to indeed_jobs_all_pages.csv")
# Recoger varias páginas de ofertas de empleo
asyncio.run(scrape_multiple_pages('https://www.indeed.com/jobs?q=usa', pages=3))
Para apuntar a títulos de empleo o palabras clave específicos en sus esfuerzos de raspado, necesitará configurar el parámetro de búsqueda de consulta en la URL utilizada por Indeed. Esta personalización permite que el scraper recopile datos específicos de determinados empleos o sectores. Por ejemplo, si estás buscando puestos de desarrollador de Python en http://www.indeed.com, ajustarías el parámetro de consulta para incluir "Python+desarrollador" o palabras clave relevantes.
query = "python+developer"
base_url = f"https://www.indeed.com/jobs?q={query}"
asyncio.run(scrape_multiple_pages(base_url, pages=3))
Modificando este parámetro en función de sus necesidades de recopilación de datos, puede centrar su raspado en empleos específicos, mejorando la flexibilidad y la eficacia de su proceso de recopilación de datos. Este enfoque es especialmente útil para adaptarse a las demandas dinámicas del mercado laboral.
import asyncio
from playwright.async_api import async_playwright
from lxml import html
import pandas as pd
# Paso 1: Obtener el contenido de la página con Playwright
async def get_page_content(url):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False
proxy = {
'server': '',
'username': '',
'password': ''
}
) # Ejecutar el navegador en modo encabezado
page = await browser.new_page()
await page.goto(url, wait_until='networkidle')
# Extraer el contenido de la página
content = await page.content()
await browser.close() # Cerrar el navegador después de usarlo
return content
# Paso 2: Analizar el contenido HTML mediante lxml
def parse_job_listings(content):
# Analiza el HTML con lxml
parser = html.fromstring(content)
# Seleccionar ofertas de empleo individuales mediante XPath
job_posting = parser.xpath('//ul[@class="css-zu9cdh eu4oa1w0"]/li')
# Extraer datos de trabajo
jobs_data = []
for element in job_posting[:-1]:
title = ''.join(element.xpath('.//h2/a/span/@title'))
if title:
link = ''.join(element.xpath('.//h2/a/@href'))
location = ''.join(element.xpath('.//div[@data-testid="text-location"]/text()'))
description = ', '.join(element.xpath('.//div[@class="css-9446fg eu4oa1w0"]/ul//li/text()'))
company_name = ''.join(element.xpath('.//span[@data-testid="company-name"]/text()'))
# Añadir los datos extraídos a la lista jobs_data
jobs_data.append({
'Title': title,
'Link': f"https://www.indeed.com{link}",
'Location': location,
'Description': description,
'Company': company_name
})
return jobs_data
# Paso 3: Recopilar ofertas de empleo de Indeed para una sola página
async def scrape_indeed_jobs(url):
# Obtener el contenido de la página con Playwright
content = await get_page_content(url)
# Análisis de HTML y extracción de datos de trabajo
jobs_data = parse_job_listings(content)
return jobs_data
# Paso 4: Gestión de la paginación y raspado de varias páginas
async def scrape_multiple_pages(base_url, query, pages=3):
all_jobs = []
for page_num in range(pages):
# Actualice la URL para gestionar la paginación y añada la consulta de búsqueda
url = f"{base_url}?q={query}&start={page_num * 10}"
print(f"Scraping page: {url}")
# Trabajos de raspado para la página actual
jobs = await scrape_indeed_jobs(url)
all_jobs.extend(jobs)
# Guardar todos los trabajos en un archivo CSV
df = pd.DataFrame(all_jobs)
df.to_csv(f'indeed_jobs_{query}.csv', index=False)
print(f"Data saved to indeed_jobs_{query}.csv")
# Función para ejecutar el scraper con entrada de consulta dinámica
async def run_scraper():
# Paso 5: Pedir al usuario que introduzca la consulta y el número de páginas que desea raspar.
query = input("Enter the job title or keywords to search (e.g., python+developer): ")
pages = int(input("Enter the number of pages to scrape: "))
# Trabajos de raspado en varias páginas en función de la consulta
base_url = 'https://www.indeed.com/jobs'
await scrape_multiple_pages(base_url, query, pages)
# Ejecutar el rascador
asyncio.run(run_scraper())
Para garantizar un proceso de scraping sin problemas y reducir el riesgo de bloqueos y apariciones de CAPTCHA, es crucial elegir el servidor proxy adecuado. La opción más óptima para el scraping son los proxies ISP, que proporcionan alta velocidad y estabilidad de conexión, así como un alto factor de confianza, lo que hace que rara vez sean bloqueados por las plataformas. Este tipo de proxy es estático, por lo que para el scraping a gran escala, es necesario crear un grupo de proxies ISP y configurar la rotación de IP para su cambio regular. Una opción alternativa serían los proxies residenciales, que son dinámicos y tienen la cobertura geográfica más amplia en comparación con otros tipos de servidores proxy.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.ru!
Comentarios: 0