Регулярное выражение Python для разбора HTML (BeautifulSoup) - PullRequest
11 голосов
/ 11 сентября 2008

Я хочу получить значение скрытого поля ввода в HTML.

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

Я хочу написать регулярное выражение в Python, которое будет возвращать значение fooId, учитывая, что я знаю, что строка в HTML соответствует формату

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

Может ли кто-нибудь предоставить в Python пример для анализа HTML-значения?

Ответы [ 7 ]

27 голосов
/ 11 сентября 2008

В этом конкретном случае BeautifulSoup сложнее написать, чем регулярное выражение, но оно гораздо более надежно ... Я просто помогаю примером BeautifulSoup, учитывая, что вы уже знаете, какое регулярное выражение использовать: -)

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']
18 голосов
/ 15 сентября 2008

Я согласен с Винко BeautifulSoup это путь. Однако я предлагаю использовать fooId['value'] до для получения атрибута вместо того, чтобы полагаться на значение, являющееся третьим атрибутом.

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
8 голосов
/ 11 сентября 2008
import re
reg = re.compile('<input type="hidden" name="([^"]*)" value="<id>" />')
value = reg.search(inputHTML).group(1)
print 'Value is', value
5 голосов
/ 11 сентября 2008

Синтаксический анализ - это одна из тех областей, где вы действительно не хотите бросать свои собственные, если можете избежать этого, так как вы будете гоняться за крайними случаями, и ошибки в течение многих лет будут приходить

Я бы рекомендовал использовать BeautifulSoup . У него очень хорошая репутация, и, судя по документам, он довольно прост в использовании.

1 голос
/ 14 сентября 2009

Pyparsing - это хороший промежуточный шаг между BeautifulSoup и regex. Он более надежен, чем просто регулярные выражения, поскольку его разбор HTML-тэга охватывает различия в регистре, пробеле, наличии / отсутствии / порядке атрибута, но проще выполнять этот вид извлечения основных тэгов, чем при использовании BS.

Ваш пример особенно прост, поскольку все, что вы ищете, находится в атрибутах открывающего тега "input". Вот пример pyparsing, показывающий несколько вариантов входного тега, которые бы соответствовали регулярным выражениям, а также показывает, как НЕ соответствовать тегу, если он находится внутри комментария:

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

Печать:

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

Вы можете видеть, что pyparsing не только соответствует этим непредсказуемым вариантам, но и возвращает данные в объекте, что облегчает считывание отдельных атрибутов тега и их значений.

0 голосов
/ 11 сентября 2008
/<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')
0 голосов
/ 11 сентября 2008
/<input type="hidden" name="fooId" value="([\d-]+)" \/>/
...