2010-06-19 5 views

Répondre

66

Essayez avec 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') 

Si vous voulez simplement des liens commençant par http://, vous devez utiliser:

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

BeautifulSoup ne peut pas fermer automatiquement les balises 'meta', par exemple.Le modèle DOM n'est pas valide et il n'y a aucune garantie que vous trouviez ce que vous cherchez. – Antonio

+0

un autre problème avec bsoup est, le format du lien changera de son original. Donc, si vous voulez changer le lien d'origine pour pointer vers une autre ressource, pour l'instant, je n'ai toujours aucune idée de la façon de le faire avec bsoup. Toute suggestion? – swdev

+0

Tous les liens ne contiennent pas http. Par exemple, si vous codez votre site pour supprimer le protocole, les liens commenceront par '//'. Cela signifie simplement utiliser le protocole avec lequel le site est chargé (soit http: 'ou' https: '). – reubano

23

Vous pouvez utiliser le module HTMLParser.

Le code ressemblerait probablement quelque chose comme ceci:

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) 

Note: Le module HTMLParser a été renommé html.parser en Python 3.0. L'outil 2to3 adaptera automatiquement les importations lors de la conversion de vos sources vers la version 3.0.

+0

Je viens de réaliser que, si un lien contient le caractère HTML spécial tel que '&', il est converti en sa représentation textuelle, comme '&' dans ce cas. Comment préservez-vous la chaîne d'origine? – swdev

+1

Je préfère cette solution, car elle n'a pas besoin de dépendances externes – DomTomCat

9

Regardez en utilisant la belle bibliothèque de l'analyse syntaxique HTML soupe.

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

Vous allez faire quelque chose comme ceci:

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

Merci! Mais utilisez 'link' à la place de' a'. – Evgenii

6

Ma réponse suce probablement par rapport aux véritables gourous là-bas, mais en utilisant quelques calculs simples, découpage en tranches de chaîne, trouver et urllib, ce petit Le script créera une liste contenant les éléments de lien. Je teste google et ma sortie semble correcte. J'espère que cela aide!

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

est ici une version paresseuse de @ réponse 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 

Utilisez comme si:

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

En utilisant BS4 pour cette tâche spécifique semble exagéré.

Essayez plutôt:

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)) 

J'ai trouvé ce morceau astucieux de code sur http://www.pythonforbeginners.com/code/regular-expression-re-findall et travaille pour moi très bien.

Je l'ai testé que sur mon scénario d'extraire une liste de fichiers à partir d'un dossier Web qui expose les fichiers \ dossier en elle, par exemple:

enter image description here

et moi avons une liste triée des fichiers \ dossiers sous l'URL

Questions connexes