如何在忽略使用 BeautifulSoup 的格式标记的同时从 html 获取文本?
How does one get the text from html while ignoring formatting tags using BeautifulSoup?
以下代码用于从 html.
中抓取连续的文本段
for text in soup.find_all_next(text=True):
if isinstance(text, Comment):
# We found a comment, ignore
continue
if not text.strip():
# We found a blank text, ignore
continue
# Whatever is left must be good
print(text)
文本项目被 <div>
或 <br>
等结构标签以及 <em>
和 <strong>
等格式标签拆分。这给我在进一步解析文本时带来了一些不便,我希望能够在忽略文本内部的任何格式标记的同时获取连续的文本项。
例如,soup.find_all_next(text=True)
将采用 html 代码 <div>This is <em>important</em> text</div>
和 return 单个字符串,This is important text
而不是三个字符串,This is
、important
和 text
.
我不确定是否清楚...如果不清楚请告诉我。
编辑: 我逐条浏览 html 文本项的原因是我只是在看到特定的 "begin" 评论标签,我在到达特定的 "end" 评论标签时停止。在这种需要逐项走动的情况下,是否有任何解决方案可行?我正在使用的完整代码如下。
soup = BeautifulSoup(page)
for instanceBegin in soup.find_all(text=isBeginText):
# We found a start comment, look at all text and comments:
for text in instanceBegin.find_all_next(text=True):
# We found a text or comment, examine it closely
if isEndText(text):
# We found the end comment, everybody out of the pool
break
if isinstance(text, Comment):
# We found a comment, ignore
continue
if not text.strip():
# We found a blank text, ignore
continue
# Whatever is left must be good
print(text)
其中 isBeginText(text)
和 isEndText(text)
这两个函数 return 如果传递给它们的字符串与我的开始或结束评论标签匹配则为真。
如果您抓取包含您的子元素的父元素并执行 get_text()
,BeautifulSoup 将为您去除所有 html 标签,只有 return 一个连续的字符串文本。
你可以找一个例子here
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
print(soup.get_text())
如何使用 find_all_next
两次,开始和结束标记各一次,并取两个生成列表的差异?
例如,我将使用来自 the documentation of BeautifulSoup:
的 html_doc
的修改版本
import bs4
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<!-- START--><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p><!-- END -->
<p class="story">...</p>
"""
soup = bs4.BeautifulSoup(html_doc, 'html.parser')
comments = soup.findAll(text=lambda text:isinstance(text, bs4.Comment))
# Step 1: find the beginning and ending markers
node_start = [ cmt for cmt in comments if cmt.string == " START" ][0]
node_end = [ cmt for cmt in comments if cmt.string == " END " ][0]
# Step 2, subtract the 2nd list of strings from the first
all_text = node_start.find_all_next(text=True)
all_after_text = node_end.find_all_next(text=True)
subset = all_text[:-(len(all_after_text) + 1)]
print(subset)
# ['Lacie', ' and\n', 'Tillie', ';\nand they lived at the bottom of a well.']
以下代码用于从 html.
中抓取连续的文本段 for text in soup.find_all_next(text=True):
if isinstance(text, Comment):
# We found a comment, ignore
continue
if not text.strip():
# We found a blank text, ignore
continue
# Whatever is left must be good
print(text)
文本项目被 <div>
或 <br>
等结构标签以及 <em>
和 <strong>
等格式标签拆分。这给我在进一步解析文本时带来了一些不便,我希望能够在忽略文本内部的任何格式标记的同时获取连续的文本项。
例如,soup.find_all_next(text=True)
将采用 html 代码 <div>This is <em>important</em> text</div>
和 return 单个字符串,This is important text
而不是三个字符串,This is
、important
和 text
.
我不确定是否清楚...如果不清楚请告诉我。
编辑: 我逐条浏览 html 文本项的原因是我只是在看到特定的 "begin" 评论标签,我在到达特定的 "end" 评论标签时停止。在这种需要逐项走动的情况下,是否有任何解决方案可行?我正在使用的完整代码如下。
soup = BeautifulSoup(page)
for instanceBegin in soup.find_all(text=isBeginText):
# We found a start comment, look at all text and comments:
for text in instanceBegin.find_all_next(text=True):
# We found a text or comment, examine it closely
if isEndText(text):
# We found the end comment, everybody out of the pool
break
if isinstance(text, Comment):
# We found a comment, ignore
continue
if not text.strip():
# We found a blank text, ignore
continue
# Whatever is left must be good
print(text)
其中 isBeginText(text)
和 isEndText(text)
这两个函数 return 如果传递给它们的字符串与我的开始或结束评论标签匹配则为真。
如果您抓取包含您的子元素的父元素并执行 get_text()
,BeautifulSoup 将为您去除所有 html 标签,只有 return 一个连续的字符串文本。
你可以找一个例子here
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
print(soup.get_text())
如何使用 find_all_next
两次,开始和结束标记各一次,并取两个生成列表的差异?
例如,我将使用来自 the documentation of BeautifulSoup:
的html_doc
的修改版本
import bs4
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<!-- START--><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p><!-- END -->
<p class="story">...</p>
"""
soup = bs4.BeautifulSoup(html_doc, 'html.parser')
comments = soup.findAll(text=lambda text:isinstance(text, bs4.Comment))
# Step 1: find the beginning and ending markers
node_start = [ cmt for cmt in comments if cmt.string == " START" ][0]
node_end = [ cmt for cmt in comments if cmt.string == " END " ][0]
# Step 2, subtract the 2nd list of strings from the first
all_text = node_start.find_all_next(text=True)
all_after_text = node_end.find_all_next(text=True)
subset = all_text[:-(len(all_after_text) + 1)]
print(subset)
# ['Lacie', ' and\n', 'Tillie', ';\nand they lived at the bottom of a well.']