2010-06-19 25 views

Respuesta

66

intento con Beautifulsoup:

from BeautifulSoup import BeautifulSoup 
import urllib2 
import re 

html_page = urllib2.urlopen("http://www.yourwebsite.com") 
soup = BeautifulSoup(html_page) 
for link in soup.findAll('a'): 
    print link.get('href') 

En caso de que sólo quieren enlaces empezando con http://, se deben utilizar:

soup.findAll('a', attrs={'href': re.compile("^http://")}) 
+0

BeautifulSoup no puede cerrar automáticamente las etiquetas 'meta', por ejemplo.El modelo DOM no es válido y no hay garantía de que encuentre lo que está buscando. – Antonio

+0

otro problema con bsoup es que el formato del enlace cambiará de su original. Entonces, si desea cambiar el enlace original para señalar otro recurso, en este momento todavía no tengo idea de cómo hacerlo con bsoup. ¿Cualquier sugerencia? – swdev

+0

No todos los enlaces contienen 'http'. Por ejemplo, si codifica su sitio para eliminar el protocolo, los enlaces comenzarán con '//'. Esto significa simplemente usar cualquier protocolo con el que el sitio esté cargado (ya sea 'http:' o 'https:'). – reubano

23

Puede usar el módulo HTMLParser.

El código probablemente se vería algo como esto:

from HTMLParser import HTMLParser 

class MyHTMLParser(HTMLParser): 

    def handle_starttag(self, tag, attrs): 
     # Only parse the 'anchor' tag. 
     if tag == "a": 
      # Check the list of defined attributes. 
      for name, value in attrs: 
       # If href is defined, print it. 
       if name == "href": 
        print name, "=", value 


parser = MyHTMLParser() 
parser.feed(your_html_string) 

Nota: El módulo HTMLParser ha sido renombrado a html.parser en Python 3.0. La herramienta 2to3 adaptará automáticamente las importaciones al convertir sus fuentes a 3.0.

+0

Me doy cuenta de que, si un enlace contiene el carácter HTML especial como '&', se convierte en su representación textual, como '&' en este caso. ¿Cómo se conserva la cadena original? – swdev

+1

Considero que esta solución es la mejor, ya que no necesita dependencias externas – DomTomCat

9

buscar en el uso de la hermosa html sopa de análisis sintáctico de la biblioteca.

http://www.crummy.com/software/BeautifulSoup/

Va a hacer algo como esto:

import BeautifulSoup 
soup = BeautifulSoup.BeautifulSoup(html) 
for link in soup.findAll("a"): 
    print link.get("href") 
+0

¡Gracias! Pero use 'link' en lugar de' a'. – Evgenii

6

Mi respuesta probablemente chupa en comparación con los verdaderos gurús por ahí, pero usando un poco de matemática simple, corte en rodajas de cuerdas, encontrar y urllib, esta pequeña script creará una lista que contiene elementos de enlace. Pruebo google y mi resultado parece correcto. ¡Espero eso ayude!

import urllib 
test = urllib.urlopen("http://www.google.com").read() 
sane = 0 
needlestack = [] 
while sane == 0: 
    curpos = test.find("href") 
    if curpos >= 0: 
    testlen = len(test) 
    test = test[curpos:testlen] 
    curpos = test.find('"') 
    testlen = len(test) 
    test = test[curpos+1:testlen] 
    curpos = test.find('"') 
    needle = test[0:curpos] 
    if needle.startswith("http" or "www"): 
     needlestack.append(needle) 
    else: 
    sane = 1 
for item in needlestack: 
    print item 
2

Aquí hay una versión lenta de @ respuesta de Stephen

from urllib.request import urlopen 
from itertools import chain 
from html.parser import HTMLParser 

class LinkParser(HTMLParser): 
    def reset(self): 
     HTMLParser.reset(self) 
     self.links = iter([]) 

    def handle_starttag(self, tag, attrs): 
     if tag == 'a': 
      for name, value in attrs: 
       if name == 'href': 
        self.links = chain(self.links, [value]) 


def gen_links(f, parser): 
    encoding = f.headers.get_content_charset() or 'UTF-8' 

    for line in f: 
     parser.feed(line.decode(encoding)) 
     yield from parser.links 

usarlo como así:

>>> parser = LinkParser() 
>>> f = urlopen('http://stackoverflow.com/questions/3075550') 
>>> links = gen_links(f, parser) 
>>> next(links) 
'//stackoverflow.com' 
1

Usando BS4 para esta tarea específica parece un exceso.

Procurad, más bien:

website = urllib2.urlopen('http://10.123.123.5/foo_images/Repo/') 
html = website.read() 
files = re.findall('href="(.*tgz|.*tar.gz)"', html) 
print sorted(x for x in (files)) 

Me encontraron esta ingeniosa pieza de código en http://www.pythonforbeginners.com/code/regular-expression-re-findall y funciona para mí bastante bien.

he comprobado sólo en mi escenario de extraer una lista de archivos de una carpeta web que expone los archivos \ carpeta en la que, por ejemplo:

enter image description here

y me dieron una lista ordenada de los archivos \ carpetas bajo la URL

Cuestiones relacionadas