2012-08-03 14 views
13

Potrzebuję uzyskać tekst wewnątrz dwóch elementów w ciąg:analizowaniem HTML, aby uzyskać tekst wewnątrz elementu

source_code = """<span class="UserName"><a href="#">Martin Elias</a></span>""" 

>>> text 
'Martin Elias' 

Jak można to osiągnąć?

+0

tam kilka sposobów na skórę kota tutaj. Jaki jest wynik końcowy? Możesz zrobić javascript lub trochę parsowania po stronie serwera. –

Odpowiedz

26

Szukałem "python parsującej html" i był to pierwszy wynik: https://docs.python.org/2/library/htmlparser.html

Ten kod jest pobierana z docs Pythona

from HTMLParser import HTMLParser 

    # create a subclass and override the handler methods 
    class MyHTMLParser(HTMLParser): 
     def handle_starttag(self, tag, attrs): 
      print "Encountered a start tag:", tag 
     def handle_endtag(self, tag): 
      print "Encountered an end tag :", tag 
     def handle_data(self, data): 
      print "Encountered some data :", data 

    # instantiate the parser and fed it some HTML 
    parser = MyHTMLParser() 
    parser.feed('<html><head><title>Test</title></head>' 
       '<body><h1>Parse me!</h1></body></html>') 

Oto wynik:

Encountered a start tag: html 
Encountered a start tag: head 
Encountered a start tag: title 
Encountered some data : Test 
Encountered an end tag : title 
Encountered an end tag : head 
Encountered a start tag: body 
Encountered a start tag: h1 
Encountered some data : Parse me! 
Encountered an end tag : h1 
Encountered an end tag : body 
Encountered an end tag : html 

Używając tego i patrząc na kod w HTMLParser wymyśliłem:

class myhtmlparser(HTMLParser): 
    def __init__(self): 
     self.reset() 
     self.NEWTAGS = [] 
     self.NEWATTRS = [] 
     self.HTMLDATA = [] 
    def handle_starttag(self, tag, attrs): 
     self.NEWTAGS.append(tag) 
     self.NEWATTRS.append(attrs) 
    def handle_data(self, data): 
     self.HTMLDATA.append(data) 
    def clean(self): 
     self.NEWTAGS = [] 
     self.NEWATTRS = [] 
     self.HTMLDATA = [] 

Można go używać tak:

from HTMLParser import HTMLParser 

pstring = source_code = """<span class="UserName"><a href="#">Martin Elias</a></span>""" 


class myhtmlparser(HTMLParser): 
    def __init__(self): 
     self.reset() 
     self.NEWTAGS = [] 
     self.NEWATTRS = [] 
     self.HTMLDATA = [] 
    def handle_starttag(self, tag, attrs): 
     self.NEWTAGS.append(tag) 
     self.NEWATTRS.append(attrs) 
    def handle_data(self, data): 
     self.HTMLDATA.append(data) 
    def clean(self): 
     self.NEWTAGS = [] 
     self.NEWATTRS = [] 
     self.HTMLDATA = [] 

parser = myhtmlparser() 
parser.feed(pstring) 

# Extract data from parser 
tags = parser.NEWTAGS 
attrs = parser.NEWATTRS 
data = parser.HTMLDATA 

# Clean the parser 
parser.clean() 

# Print out our data 
print tags 
print attrs 
print data 

Teraz powinieneś być w stanie łatwo wyodrębnić dane z tych list. Mam nadzieję, że to pomogło!

+0

To jest piękne :) – AsheKetchum

18

Polecam korzystanie z biblioteki Python Beautiful Soup 4.

pip install beautifulsoup4 

Sprawia, że ​​parsowanie HTML jest naprawdę łatwe.

from bs4 import BeautifulSoup 
source_code = """<span class="UserName"><a href="#">Martin Elias</a></span>""" 
soup = BeautifulSoup(source_code) 
print soup.a.string 
>>> 'Martin Elias' 
+0

Wiem, że pytanie jest oznaczone python-2.x, ale myślę, że należy zauważyć, że beautifulsoup działa tylko na python 2.x. – LJNielsenDk

+3

Piękna Zupa 4 działa zarówno w wersji 2.7, jak i 3. –

+0

Gdzie znajduje się dobra dokumentacja API dla pięknej zupy? –

0

Można również spróbować użyć html5lib i XPath, there is a good question about it here, że odpowiedź ma istotny szczegół (namespaceHTMLElements) do zapamiętania, aby html5lib zachowują się zgodnie z oczekiwaniami. Zmarnowałem tak wiele czasu, próbując zmusić go do pracy, ponieważ przeoczyłem, że muszę to zmienić.

2

Install BeautifulSoup i Można zrobić tak:

from BeautifulSoup import BeautifulSoup 
source_code = '"""<span class="UserName"><a href="#">Martin Elias</a></span>"""' 
soup = BeautifulSoup(source_code) 
print soup.find('span',{'class':'UserName'}).text 
Powiązane problemy