Мне нужно получить информацию с веб-сайта, который выводит его между <font color="red">needed-info-here</font>
OR <span style="font-weight:bold;">needed-info-here</span>
, случайным образом.
Я могу получить его, когда я использую
start = '<font color="red">'
end = '</font>'
expression = start + '(.*?)' + end
match = re.compile(expression).search(web_source_code)
needed_info = match.group(1)
но тогда мне нужно выбрать, чтобы получить либо <font>
, либо <span>
, при неудаче, когда сайт использует другой тег.
Как изменить регулярное выражение, чтобы оно всегда было успешным?
Вы можете присоединиться к двум альтернативам с вертикальной полосой:
start = '<font color="red">|<span style="font-weight:bold;">'
end = '</font>|</span>'
поскольку вы знаете, что тег шрифта всегда будет закрыт </font>
, тег span всегда на </span>
.
Однако рассмотрите также использование твердого синтаксического анализатора HTML, такого как BeautifulSoup, вместо того, чтобы сворачивать ваши собственные регулярные выражения, для синтаксического анализа HTML, что особенно непригодно в целом для получения синтаксического анализа регулярными выражениями.
Не анализировать HTML с регулярным выражением.
Regex - неправильный инструмент для использования для этой проблемы. Посмотрите BeautifulSoup или lxml.
expression = '(<font color="red">(.*?)</font>|<span style="font-weight:bold;">(.*?)</span>)'
match = re.compile(expression).search(web_source_code)
needed_info = match.group(2)
Это выполнит эту работу, но вы не должны использовать regex для анализа html
Хотя регулярные выражения не являются лучшим выбором для синтаксического анализа HTML.
Для образования, вот возможный ответ на ваш вопрос:
start = '<(?P<tag>font|tag) color="red">'
end = '</(?P=tag)>'
expression = start + '(.*?)' + end
Regex и HTML не так хороши, HTML имеет слишком много потенциальных вариаций, которые будут вызывать ваше регулярное выражение. BeautifulSoup - это стандартный инструмент для использования здесь, но я считаю, что pyparsing может быть столь же эффективным, а иногда даже проще создавать при попытке найти конкретный тег относительно определенного предыдущего тега.
Вот как решить свой вопрос, используя pyparsing:
html = """ need to get info from a website that outputs it between <font color="red">needed-info-here</font> OR <span style="font-weight:bold;">needed-info-here</span>, randomly.
<font color="white">but not this info</font> and
<span style="font-weight:normal;">dont want this either</span>
"""
from pyparsing import *
font,fontEnd = makeHTMLTags("FONT")
# only match <font> tags with color="red"
font.setParseAction(withAttribute(color="red"))
# only match <span> tags with given style
span,spanEnd = makeHTMLTags("SPAN")
span.setParseAction(withAttribute(style="font-weight:bold;"))
# define full match patterns, define "body" results name for easy access
fontpattern = font + SkipTo(fontEnd)("body") + fontEnd
spanpattern = span + SkipTo(spanEnd)("body") + spanEnd
# now create a single pattern, matching either of the other patterns
searchpattern = fontpattern | spanpattern
# call searchString, and extract body element from each match
for text in searchpattern.searchString(html):
print text.body
Печать
needed-info-here
needed-info-here
Я не использовал Python, но если вы делаете выражения равными следующим, он должен работать:
/(?P<open><(font|span)[^>]*>)(?P<info>[^<]+)(?P<close><\/(font|span)>)/gi
Затем просто получите доступ к вашей необходимой информации с именем "info".
PS - Я также соглашаюсь с правилом "не разобрав HTML с регулярным выражением", но если вы знаете, что он появится либо в тегах шрифта, либо в тегах span, то пусть будет так...
Кроме того, зачем использовать тег шрифта? Я не использовал тег шрифта, так как я узнал CSS.