2008-09-10 11 views
10

Ich möchte den Wert eines ausgeblendeten Eingabefeldes in HTML erfassen.Python regulärer Ausdruck für HTML-Analyse (BeautifulSoup)

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

Ich möchte einen regulären Ausdruck in Python schreiben, die den Wert von fooId zurückkehren, da ich die Zeile in der HTML-Kenntnisse folgt das Format

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

Kann jemand ein Beispiel in Python zur Verfügung stellen den HTML für den Wert analysieren?

Antwort

27

Für diesen speziellen Fall ist BeautifulSoup härter als ein regex zu schreiben, aber es ist viel robuster ... Ich bin nur mit dem BeautifulSoup Beispiel beitragen, da Sie bereits wissen, welche regexp zu verwenden: -)

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

Ich denke, dass das "neue" Keyword eine Diskrepanz ist. –

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

Parsing ist einer jener Bereiche, in denen Sie wirklich wollen nicht Ihre eigene Rolle, wenn Sie es vermeiden können, wie Sie die Rand-Fälle und Bugs seit Jahren jagen werde

go kommen

Ich würde empfehlen, BeautifulSoup zu verwenden. Es hat einen sehr guten Ruf und sieht aus den Dokumenten so aus, als wäre es ziemlich einfach zu benutzen.

+1

Ich stimme einem allgemeinen Fall zu, aber wenn Sie ein einmaliges Skript machen, um ein oder zwei sehr spezifische Dinge zu analysieren, kann ein Regex das Leben einfach erleichtern. Offensichtlich fragiler, aber wenn Wartbarkeit keine Rolle spielt, dann ist das kein Problem. Das heißt, BeautifulSoup ist fantastisch. –

+0

Ich liebe Regex, aber muss mit Orion auf diesem einen zustimmen. Dies ist eine der Zeiten, als das berühmte Zitat von Jamie Zawinski in den Sinn kommt: "Jetzt haben Sie zwei Probleme" –

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

ich mit Vinko einverstanden BeautifulSoup ist der Weg zu gehen. Jedoch schlage ich vor, fooId['value'] zu get the attribute eher zu verwenden, als darauf zu vertrauen, dass Wert das dritte Attribut ist.

+0

"neu"? Das ist keine Python! – habnabit

1

Pyparsing ist ein guter Zwischenschritt zwischen BeautifulSoup und Regex. Es ist robuster als nur Regexes, da sein HTML-Tag-Parsing Variationen in Fall, Whitespace, Attribut Anwesenheit/Abwesenheit/Ordnung umfasst, aber einfacher ist, diese Art von einfacher Tag-Extraktion als mit BS durchzuführen.

Ihr Beispiel ist besonders einfach, da alles, was Sie suchen, in den Attributen des öffnenden "Eingabe" -Tags ist. Hier ist ein pyparsing Beispiel mehrere Varianten auf Ihrem Input-Tag zeigt, die reguläre Ausdrücke passt geben würde, und zeigt auch, wie NICHT um einen Tag übereinstimmen, wenn es innerhalb eines Kommentars ist:

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 

Drucke:

['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]** 

Sie können sehen, dass das Pyparsen nicht nur mit diesen unvorhersehbaren Variationen übereinstimmt, sondern dass es die Daten in einem Objekt zurückgibt, das es einfach macht, die einzelnen Tag-Attribute und ihre Werte auszulesen.