Expresión regular de Python para el análisis HTML(BeautifulSoup)
regex screen-scraping (7)
El análisis es una de esas áreas en las que realmente no quieres hacer las tuyas si puedes evitarlo, ya que estarás persiguiendo el borde: los casos y errores vienen durante años.
Yo recomendaría usar BeautifulSoup . Tiene una muy buena reputación y se ve desde los documentos como que es bastante fácil de usar.
Quiero tomar el valor de un campo de entrada oculto en HTML.
<input type="hidden" name="fooId" value="12-3456789-1111111111" />
Quiero escribir una expresión regular en Python que devuelva el valor de fooId, dado que sé que la línea en el HTML sigue el formato
<input type="hidden" name="fooId" value="**[id is here]**" />
¿Puede alguien proporcionar un ejemplo en Python para analizar el HTML del valor?
import re
reg = re.compile(''<input type="hidden" name="([^"]*)" value="<id>" />'')
value = reg.search(inputHTML).group(1)
print ''Value is'', value
/<input type="hidden" name="fooId" value="([/d-]+)" //>/
/<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'')
Estoy de acuerdo con Vinko BeautifulSoup es el camino a seguir. Sin embargo, sugiero usar fooId[''value'']
para obtener el atributo en lugar de confiar en que el tercer atributo sea el valor.
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
Pyparsing es un buen paso intermedio entre BeautifulSoup y regex. Es más robusto que solo expresiones regulares, ya que su análisis de etiquetas HTML comprende variaciones en el caso, el espacio en blanco, la presencia / ausencia / orden de atributos, pero es más simple hacer este tipo de extracción de etiqueta básica que usar BS.
Su ejemplo es especialmente simple, ya que todo lo que está buscando se encuentra en los atributos de la etiqueta de "entrada" de apertura. Aquí hay un ejemplo de pyparsing que muestra varias variaciones en su etiqueta de entrada que darían ajustes a las expresiones regulares, y también muestra cómo NO hacer coincidir una etiqueta si está dentro de un comentario:
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
Huellas dactilares:
[''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]**
Puede ver que el pyparsing no solo coincide con estas variaciones impredecibles, sino que también devuelve los datos en un objeto que facilita la lectura de los atributos de etiquetas individuales y sus valores.
Para este caso particular, BeautifulSoup es más difícil de escribir que una expresión regular, pero es mucho más robusto ... Solo estoy contribuyendo con el ejemplo de BeautifulSoup, dado que ya sabes qué expresiones regulares usar :-)
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'']