python regex screen-scraping

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