KCz*_*zar 5 html python beautifulsoup
我正在使用BeautifulSoup(Python 3.4版本'4.3.2')将html文档转换为文本。我遇到的问题是,有时网页中的换行符“ \ n”实际上不会在浏览器中显示为换行符,但是当BeautifulSoup将它们转换为文本时,它会留在“ \ n”中。
例:
您的浏览器可能会在一行中呈现以下所有内容(即使中间包含换行符):
这是一个段落。
即使我输入的内容中没有换行符,您的浏览器也可能以多行显示以下内容:
这是一个段落。
这是另一段。
但是,当BeautifulSoup将相同的字符串转换为文本时,它使用的唯一换行符是换行符-并且始终使用它们:
from bs4 import BeautifulSoup
doc = "<p>This is a\nparagraph.</p>"
soup = BeautifulSoup(doc)
soup.text
Out[181]: 'This is a \n paragraph.'
doc = "<p>This is a paragraph.</p><p>This is another paragraph.</p>"
soup = BeautifulSoup(doc)
soup.text
Out[187]: 'This is a paragraph.This is another paragraph.'
Run Code Online (Sandbox Code Playgroud)
有谁知道如何使BeautifulSoup以更漂亮的方式提取文本(或者实际上只是使所有换行符正确)?还有其他解决问题的简单方法吗?
nao*_*oko 12
get_text 在这里可能会有所帮助:
>>> from bs4 import BeautifulSoup
>>> doc = "<p>This is a paragraph.</p><p>This is another paragraph.</p>"
>>> soup = BeautifulSoup(doc)
>>> soup.get_text(separator="\n")
u'This is a paragraph.\nThis is another paragraph.'
Run Code Online (Sandbox Code Playgroud)
小智 8
虽然我确实意识到这是一篇旧帖子,但我想强调 bs4 中从标签打印文本的一些行为。
我不是 html 专家,但这些是我在尝试像浏览器一样制作 bs4 打印文本时考虑的几件事 -
我将要描述的行为适用于BeautifulSoup 中的tag.get_text()功能tag.find_all(text=True,recursive=True)
Beautiful soup 打印一个新行(如果它在 html 源代码中可用)
Beautiful soup 不会在块元素之前和之后添加新行,就像p标签周围没有源新行一样
<br>标签如果源包含标签并且标签<br>周围没有源新行, BeautifulSoup 不会打印新行<br>
解决方案
这是一个适用于多种情况的解决方案(限制因素为 -1)所有内联元素的列表 2)CSS/JS 在浏览器环境中运行时如何影响内联性或块性
def get_text(tag: bs4.Tag) -> str:
_inline_elements = {"a","span","em","strong","u","i","font","mark","label",
"s","sub","sup","tt","bdo","button","cite","del","b","a","font",}
def _get_text(tag: bs4.Tag) -> typing.Generator:
for child in tag.children:
if isinstance(child, bs4.Tag):
# if the tag is a block type tag then yield new lines before after
is_block_element = child.name not in _inline_elements
if is_block_element:
yield "\n"
yield from ["\n"] if child.name == "br" else _get_text(child)
if is_block_element:
yield "\n"
elif isinstance(child, bs4.NavigableString):
yield child.string
return "".join(_get_text(tag))
Run Code Online (Sandbox Code Playgroud)