Как использовать BeautifulSoup, чтобы извлечь из абзаца HTML?
-
02-10-2019 - |
Вопрос
Я использую BeautifulSoup, чтобы сделать несколько Scraphing. Моя проблема в том, что я должен извлечь конкретные вещи из абзаца. Пример:
<p><b><a href="/name/abe">ABE</a></b> <font class="masc">m</font> <font class="info"><a href="/nmc/eng.php" class="usg">English</a>, <a href="/nmc/jew.php" class="usg">Hebrew</a></font><br />Short form of <a href="/name/abraham" class="nl">ABRAHAM</a>
Из этого пункта я могу извлечь имя abe следующим образом:
for pFound in soup.findAll('p'):
print pFound
#will get the names
x = pFound.find('a').renderContents()
print x
Теперь моя проблема заключается в том, чтобы извлечь другое имя, в одном абзаце.
Short form of <a href="/name/abraham" class="nl">ABRAHAM</a>
Мне нужно извлечь это только в том случае, если тег A предшествует текстовой «короткую форму»
Есть идеи, как это сделать? На странице HTML существует много таких пунктов, и не все они имеют текст «короткую форму», они могут содержать какой-то другой текст в этом месте.
Я думаю, что некоторая комбинация Regex и Findnext () может быть полезным, но я не знаком с красивой подвеской. Закончился тратить довольно много времени.
Любая помощь будет оценена. Спасибо.
Решение
Следующее должно работать ...:
htm = '''<p><b><a href="/name/abe">ABE</a></b> <font class="masc">m
</font> <font class="info"><a href="/nmc/eng.php" class="usg">English
</a>, <a href="/nmc/jew.php" class="usg">Hebrew</a></font><br />
Short form of <a href="/name/abraham" class="nl">ABRAHAM</a>'''
import BeautifulSoup
soup = BeautifulSoup.BeautifulSoup(htm)
for p in soup.findAll('p'):
firsta = True
shortf = False
for c in p.recursiveChildGenerator():
if isinstance(c, BeautifulSoup.NavigableString):
if 'Short form of' in str(c):
shortf = True
elif c.name == 'a':
if firsta or shortf:
print c.renderContents()
firsta = shortf = False
Другие советы
Вы можете использовать Pyparding как своего рода «Super-Regex» для анализа через HTML. Вы можете собрать простой образец подходящего шаблона, собрав различные пуски стартовых и окончательных тегов, без отключения типичных подводных подводных камней Regex HTML (непредсказуемые теги / атрибуты письма, непредсказуемые атрибуты, атрибуты из строя, непредсказуемые пробелы). Затем Pattern.ScanString вернет генератор, который сканирует через источник HTML и вернуть кортежи соответствующих токенов, начальных и окончательных мест. Бросьте присвоение имен результатов (аналогично именованным полям в Regex), и доступа к отдельным сферам интереса просты.
html = """<some leading html>
<p><b><a href="/name/abe">ABE</a></b> <font class="masc">m</font>
<font class="info"><a href="/nmc/eng.php" class="usg">English</a>, <a href="/nmc/jew.php" class="usg">
Hebrew</a></font><br />Short form of <a href="/name/abraham" class="nl">ABRAHAM</a>
<some trailing html>"""
from pyparsing import makeHTMLTags, SkipTo, Optional
pTag,pEnd = makeHTMLTags("P")
bTag,bEnd = makeHTMLTags("B")
aTag,aEnd = makeHTMLTags("A")
fontTag,fontEnd = makeHTMLTags("FONT")
brTag = makeHTMLTags("BR")[0]
nbsp = " "
nickEntry = (pTag + bTag + aTag + SkipTo(aEnd)("nickname") + aEnd + bEnd + Optional(nbsp) +
fontTag + SkipTo(fontEnd) + fontEnd + Optional(nbsp) +
fontTag + aTag + SkipTo(aEnd) + aEnd + "," +
aTag + SkipTo(aEnd) + aEnd + fontEnd +
brTag + "Short form of" +
aTag + SkipTo(aEnd)("fullname") + aEnd)
for match,_,_ in nickEntry.scanString(html):
print match.nickname, "->", match.fullname
Печать:
ABE -> ABRAHAM