如何使用 BeautifulSoup4 获取 <br> 标签之前的所有文本
Posted
技术标签:
【中文标题】如何使用 BeautifulSoup4 获取 <br> 标签之前的所有文本【英文标题】:How do I use BeautifulSoup4 to get ALL text before <br> tag 【发布时间】:2018-07-21 05:05:20 【问题描述】:我正在尝试为我的应用抓取一些数据。我的问题是我需要一些 这是 html 代码:
<tr>
<td>
This
<a class="tip info" href="blablablablabla">is a first</a>
sentence.
<br>
This
<a class="tip info" href="blablablablabla">is a second</a>
sentence.
<br>This
<a class="tip info" href="blablablablabla">is a third</a>
sentence.
<br>
</td>
</tr>
我希望输出看起来像
这是第一句话。 这是第二句话。 这是第三句话。
有可能吗?
【问题讨论】:
您尝试过以下解决方案吗?人们正在尝试解决您的问题,但您甚至不关心回复@user4937980! 抱歉,我刚醒了几个小时。最后我使用了SIM的方法,它就像一个老板一样工作。以下所有解决方案都很棒。顺便说一句,网络爬虫真的很难学:'( 【参考方案1】:试试这个。它应该为您提供所需的输出。只需将以下脚本中使用的content
变量视为您上面粘贴的html elements
的持有者。
from bs4 import BeautifulSoup
soup = BeautifulSoup(content,"lxml")
items = ','.join([''.join([item.previous_sibling,item.text,item.next_sibling]) for item in soup.select(".tip.info")])
data = ' '.join(items.split()).replace(",","\n")
print(data)
输出:
This is a first sentence.
This is a second sentence.
This is a third sentence.
【讨论】:
【参考方案2】:这当然是可能的。我会稍微笼统地回答,因为我怀疑您是否只想处理那段 HTML。
首先,获取指向td
元素的指针,
td = soup.find('td')
现在,请注意,您可以获得此元素的子元素的列表,
>>> td_kids = list(td.children)
>>> td_kids
['\n This\n ', <a class="tip info" href="blablablablabla">is a first</a>, '\n sentence.\n ', <br/>, '\n This\n ', <a class="tip info" href="blablablablabla">is a second</a>, '\n sentence.\n ', <br/>, 'This\n ', <a class="tip info" href="blablablablabla">is a third</a>, '\n sentence.\n ', <br/>, '\n']
此列表中的一些项目是字符串,一些是 HTML 元素。至关重要的是,有些是 br
元素。
您可以首先通过查找将列表拆分为一个或多个列表,
isinstance(td_kid[<some k>], bs4.element.Tag)
对于列表中的每个项目。
然后,您可以遍历每个子列表,通过将它们变成汤来重复替换标签,然后获取这些子列表的子列表。最终,您将拥有几个子列表,其中仅包含 BeautifulSoup 所谓的“可导航字符串”,您可以照常操作。
将元素连接在一起,然后我建议您使用正则表达式 sub
消除空格,如下所示:
result = re.sub(r'\s2,', '', <joined list>)
【讨论】:
【参考方案3】:您可以使用bs4
和基本的字符串操作轻松做到这一点,如下所示:
from bs4 import BeautifulSoup
data = '''
<tr>
<td>
This
<a class="tip info" href="blablablablabla">is a first</a>
sentence.
<br>
This
<a class="tip info" href="blablablablabla">is a second</a>
sentence.
<br>This
<a class="tip info" href="blablablablabla">is a third</a>
sentence.
<br>
</td>
</tr>
'''
soup = BeautifulSoup(data, 'html.parser')
for i in soup.find_all('td'):
print ' '.join(i.text.split()).replace('. ', '.\n')
这将作为输出:
This is a first sentence.
This is a second sentence.
This is a third sentence.
【讨论】:
@novice-coder 是的,我知道 - 但是网络抓取很大程度上取决于内容格式(在这种情况下,OP 想要完整的句子 - 因此是点)。无论如何,这可以由 OP 根据实际内容轻松修复。这个答案中重要的是i.text
,因为许多程序员往往会忘记或忽略它甚至存在!【参考方案4】:
htmlText = """<tr>
<td>
This
<a class="tip info" href="blablablablabla">is a first</a>
sentence.
<br>
This
<a class="tip info" href="blablablablabla">is a second</a>
sentence.
<br>This
<a class="tip info" href="blablablablabla">is a third</a>
sentence.
<br>
</td>
</tr>"""
from bs4 import BeautifulSoup
# these two steps are to put everything into one line. may not be necessary for you
htmlText = htmlText.replace("\n", " ")
while " " in htmlText:
htmlText = htmlText.replace(" ", " ")
# import into bs4
soup = BeautifulSoup(htmlText, "lxml")
# using https://***.com/a/34640357/5702157
for br in soup.find_all("br"):
br.replace_with("\n")
parsedText = soup.get_text()
while "\n " in parsedText:
parsedText = parsedText.replace("\n ", "\n") # remove spaces at the start of new lines
print(parsedText.strip())
【讨论】:
以上是关于如何使用 BeautifulSoup4 获取 <br> 标签之前的所有文本的主要内容,如果未能解决你的问题,请参考以下文章
如何从 BeautifulSoup4 中的 html 标签中找到特定的数据属性?
如何使用python和beautifulsoup4循环抓取网站中多个页面的数据
使用python和beautifulsoup4抓取网页后重复数据