es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Lista de lectura de URL desde un archivo .csv para el raspado con Python, BeautifulSoup y Pandas.

Este era parte de otra pregunta (https://stackoverflow.com/questions/70128790/reading-urls-from-csv-and-appending-scrape-results-below-previous-with-python ) que fue generosamente respondida por @HedgeHog y contribuida por @QHarr. Ahora publico esta parte como una pregunta separada.

En el código a continuación, pego 3 URLs de ejemplo en el código y funciona. Pero tengo una larga lista de URLs (1000+) para raspar y se almacenan en una única primera columna de un archivo .csv (llamémoslo ‘urls.csv’). Preferiría leer directamente desde ese archivo.

Creo que conozco la estructura básica de ‘with open’ (por ejemplo, la forma en que @bguest la respondió a continuación), pero tengo problemas para vincularla al resto del código, para que el resto continúe funcionando. ¿Cómo puedo reemplazar la lista de URLs con una lectura iterativa de .csv, para que esté pasando las URLs correctamente al código?

import requests
from bs4 import BeautifulSoup
import pandas as pd

with open('urls.csv', 'r') as f:
    urls = [line.strip() for line in f]

data = []

for url in urls:
    page = requests.get(url)
    soup = BeautifulSoup(page.text, 'html.parser')
    toc = soup.find("div", id="toc")

    def get_drivers():
        data.append({
            'url': url,
            'type': 'driver',
            'list': [x.get_text(strip=True) for x in toc.select('li:-soup-contains-own("Market drivers") li')]
        })

    get_drivers()

    def get_challenges():
        data.append({
            'url': url,
            'type': 'challenges',
            'list': [x.get_text(strip=True) for x in toc.select('li:-soup-contains-own("Market challenges") ul li') if 'Table Impact of drivers and challenges' not in x.get_text(strip=True)]
        })

    get_challenges()

pd.concat([pd.DataFrame(data)[['url', 'type']], pd.DataFrame(pd.DataFrame(data).list.tolist())],
          axis=1).to_csv('output.csv')
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para leer las URLs de un archivo CSV, puedes usar la función read_csv de la librería pandas para leer las URLs en un dataframe. Luego, puedes iterar a través de las filas del dataframe y extraer la URL de la primera columna de cada fila. Aquí está una versión actualizada del código que hace esto:

    import requests
    from bs4 import BeautifulSoup
    import pandas as pd
    
    data = []
    
    # Leer las URLs desde el archivo CSV
    df = pd.read_csv("urls.csv", header=None)
    
    # Iterar a través de las filas del dataframe y extraer la URL de cada fila
    for index, row in df.iterrows():
        url = row[0]
        page = requests.get(url)
        soup = BeautifulSoup(page.text, 'html.parser')
        toc = soup.find("div", id="toc")
    
        def get_drivers():
            data.append({
                'url': url,
                'type': 'driver',
                'list': [x.get_text(strip=True) for x in toc.select('li:-soup-contains-own("Market drivers") li')]
            })
    
        get_drivers()
    
        def get_challenges():
            data.append({
                'url': url,
                'type': 'challenges',
                'list': [x.get_text(strip=True) for x in toc.select('li:-soup-contains-own("Market challenges") ul li') if
                         'Table Impact of drivers and challenges' not in x.get_text(strip=True)]
            })
    
        get_challenges()
    
    pd.concat([pd.DataFrame(data)[['url', 'type']], pd.DataFrame(pd.DataFrame(data).list.tolist())],
              axis=1).to_csv('output.csv', index=False)
    

    En esta versión actualizada del código, primero leemos el archivo CSV usando la función pd.read_csv y lo almacenamos en un dataframe llamado df. Luego, iteramos a través de cada fila del dataframe usando df.iterrows() y extraemos la URL de la primera columna de cada fila (url = row[0]). Entonces procedemos a raspár cada URL de la misma manera que antes.

    Finalmente, concatenamos los datos en un solo dataframe como antes, y lo escribimos en un archivo CSV con index=False agregado para evitar que pandas escriba el índice antiguo como una columna.

Comments are closed.