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.

Error HTTP 403 al extraer enlaces completos de páginas web con urllib.request.urlopen(url)

Estoy tratando de descargar todos los enlaces completos de una lista de sitios web. El código es el siguiente:

def get_links(url):
html_page = urllib.request.urlopen(url)
soup = BeautifulSoup(html_page)

all_links = [url]

for link in soup.find_all('a'):
    out=urljoin(url, link.get('href'))
    if out not in all_links:
        all_links.append(out)
return all_links

Funciona bien para la mayoría de los sitios web, pero no funciona en algunos sitios, como http://my.clevelandclinic.org/locations/akron-general. El mensaje de error es “649 raise HTTPError(req.full_url, code, msg, hdrs, fp) HTTPError: HTTP Error 403: Forbidden”.

He leído muchos mensajes y he intentado solucionarlo o evitarlo. Intenté agregar el encabezado y usar la declaración try/except, pero ninguno funciona. El sitio es accesible. Cuando utilicé otro código, como el siguiente, pude descargar dos enlaces, pero no todos.

def get_links(url):
all_links = [url]

req = requests.get(url,headers=headers)
soup = BeautifulSoup(req.text,'html.parser')
for link in soup.find_all('a'):
    out=urljoin(url, link.get('href'))
    if out not in all_links:
        all_links.append(out)
    return all_links

El segundo código no puede descargar todos los enlaces completos. Cualquier sugerencia sería muy apreciada. Gracias.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Parece que el sitio web http://my.clevelandclinic.org/locations/akron-general está bloqueando la solicitud realizada por urrlib.request.urlopen() con un error HTTP 403 Forbidden. Esto se hace generalmente para evitar el rastreo web o el scraping.

    El segundo código que intentaste usando la biblioteca requests y un encabezado funciona parcialmente, pero también tiene una sentencia de retorno dentro del ciclo for, lo que significa que retorna después de la primera iteración, sin permitir descargar todos los enlaces. Necesitas mover la sentencia de retorno después del ciclo.

    Aquí tienes una versión actualizada del segundo código que utiliza un encabezado y mueve la sentencia de retorno:

    import requests
    
    def get_links(url):
        all_links = [url]
    
        headers = {'User-Agent': 'Mozilla/5.0'}
        req = requests.get(url, headers=headers)
        soup = BeautifulSoup(req.text, 'html.parser')
    
        for link in soup.find_all('a'):
            out = urljoin(url, link.get('href'))
            if out not in all_links:
                all_links.append(out)
    
        return all_links
    

    Esto debería hacer que el código funcione para la mayoría de los sitios web, incluyendo aquellos que causan el error. Sin embargo, ten en cuenta que algunos sitios web pueden tener medidas para evitar el scraping y siempre debes respetar los términos de servicio y políticas del sitio web.

Comments are closed.