2008-09-10 14 views
10

Chcę pobrać wartość ukrytego pola wejściowego w HTML.Wyrażenie regularne Python do parsowania HTML (BeautifulSoup)

<input type="hidden" name="fooId" value="12-3456789-1111111111" /> 

Chcę napisać wyrażenie regularne w Pythonie, która zwraca wartość fooId, biorąc pod uwagę, że wiem linię w kodzie HTML następujący format

<input type="hidden" name="fooId" value="**[id is here]**" /> 

Może ktoś podać przykład w Pythonie parsować HTML dla wartości?

Odpowiedz

27

W tym konkretnym przypadku, BeautifulSoup trudniej jest pisać niż regex, ale jest o wiele bardziej wytrzymałe ... Ja tylko przyczynia się do przykładu BeautifulSoup, biorąc pod uwagę, że już wiesz, który regexp używać: -)

from BeautifulSoup import BeautifulSoup 

#Or retrieve it from the web, etc. 
html_data = open('/yourwebsite/page.html','r').read() 

#Create the soup object from the HTML data 
soup = BeautifulSoup(html_data) 
fooId = soup.find('input',name='fooId',type='hidden') #Find the proper tag 
value = fooId.attrs[2][1] #The value of the third attribute of the desired tag 
          #or index it directly via fooId['value'] 
+0

Myślę, że "nowe" słowo kluczowe to niedopasowanie. –

0
/<input type="hidden" name="fooId" value="([\d-]+)" \/>/ 
5

analizowaniem jest jednym z tych obszarów, gdzie naprawdę nie chcą toczyć własną rękę, czy można go uniknąć, jak będziesz gonić dół krawędziowe przypadków i błędów na lata mijają się

Polecam używanie BeautifulSoup. Ma bardzo dobrą reputację i wygląda z dokumentów, jak to jest dość łatwe w użyciu.

+1

Zgadzam się na ogólny przypadek, ale jeśli robisz jednorazowy skrypt, aby przetworzyć jedną lub dwie bardzo konkretne rzeczy, regex może po prostu ułatwić życie. Oczywiście bardziej kruche, ale jeśli łatwość konserwacji nie jest problemem, to nie jest to problemem. To powiedziawszy, BeautifulSoup jest fantastyczny. –

+0

Uwielbiam regex, ale muszę się z tym zgodzić z Orionem. To jest jeden z czasów, gdy przychodzi mi na myśl słynny cytat z Jamie Zawinskiego: "Teraz masz dwa problemy" –

8
import re 
reg = re.compile('<input type="hidden" name="([^"]*)" value="<id>" />') 
value = reg.search(inputHTML).group(1) 
print 'Value is', value 
0
/<input\s+type="hidden"\s+name="([A-Za-z0-9_]+)"\s+value="([A-Za-z0-9_\-]*)"\s*/>/ 

>>> import re 
>>> s = '<input type="hidden" name="fooId" value="12-3456789-1111111111" />' 
>>> re.match('<input\s+type="hidden"\s+name="([A-Za-z0-9_]+)"\s+value="([A-Za-z0-9_\-]*)"\s*/>', s).groups() 
('fooId', '12-3456789-1111111111') 
18

zgadzam się z Vinko BeautifulSoup jest droga. Sugeruję jednak używanie fooId['value'] do get the attribute zamiast polegania na wartości będącej trzecim atrybutem.

from BeautifulSoup import BeautifulSoup 
#Or retrieve it from the web, etc. 
html_data = open('/yourwebsite/page.html','r').read() 
#Create the soup object from the HTML data 
soup = BeautifulSoup(html_data) 
fooId = soup.find('input',name='fooId',type='hidden') #Find the proper tag 
value = fooId['value'] #The value attribute 
+0

"nowy"? To nie jest pyton! – habnabit

1

Pyparsing to dobry krok pośredni między BeautifulSoup i regex. Jest bardziej niezawodny niż tylko regexes, ponieważ analiza tagów HTML obejmuje warianty przypadków, białych znaków, atrybutów obecności/braku/porządku, ale prostsze jest przeprowadzanie tego rodzaju podstawowej ekstrakcji tagów niż przy użyciu BS.

Twój przykład jest szczególnie prosty, ponieważ wszystko, czego szukasz, znajduje się w atrybutach otwierającego tagu "input". Oto pyparsing przykład pokazujący kilka wariacji na temat tagu wejściowego, który dałby regexes napady, a także pokazuje, jak nie pasuje tag jeśli jest to w komentarzu:

html = """<html><body> 
<input type="hidden" name="fooId" value="**[id is here]**" /> 
<blah> 
<input name="fooId" type="hidden" value="**[id is here too]**" /> 
<input NAME="fooId" type="hidden" value="**[id is HERE too]**" /> 
<INPUT NAME="fooId" type="hidden" value="**[and id is even here TOO]**" /> 
<!-- 
<input type="hidden" name="fooId" value="**[don't report this id]**" /> 
--> 
<foo> 
</body></html>""" 

from pyparsing import makeHTMLTags, withAttribute, htmlComment 

# use makeHTMLTags to create tag expression - makeHTMLTags returns expressions for 
# opening and closing tags, we're only interested in the opening tag 
inputTag = makeHTMLTags("input")[0] 

# only want input tags with special attributes 
inputTag.setParseAction(withAttribute(type="hidden", name="fooId")) 

# don't report tags that are commented out 
inputTag.ignore(htmlComment) 

# use searchString to skip through the input 
foundTags = inputTag.searchString(html) 

# dump out first result to show all returned tags and attributes 
print foundTags[0].dump() 
print 

# print out the value attribute for all matched tags 
for inpTag in foundTags: 
    print inpTag.value 

Prints:

['input', ['type', 'hidden'], ['name', 'fooId'], ['value', '**[id is here]**'], True] 
- empty: True 
- name: fooId 
- startInput: ['input', ['type', 'hidden'], ['name', 'fooId'], ['value', '**[id is here]**'], True] 
    - empty: True 
    - name: fooId 
    - type: hidden 
    - value: **[id is here]** 
- type: hidden 
- value: **[id is here]** 

**[id is here]** 
**[id is here too]** 
**[id is HERE too]** 
**[and id is even here TOO]** 

Widać, że nie tylko pyparsing pasuje do tych nieprzewidywalnych odmian, ale zwraca dane w obiekcie, który ułatwia odczytanie poszczególnych atrybutów znaczników i ich wartości.