如何识别beautifulsoup返回的'p'标签中是否存在'span'子标签?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何识别beautifulsoup返回的'p'标签中是否存在'span'子标签?相关的知识,希望对你有一定的参考价值。
我正在制作一个网络剪贴簿,从索引网页上抓取一个在线小说,代码为小说的每本书创建和epub文件。小说的翻译以2种不同的格式为小说设置了网页。
第一种格式是带有p
标签的span
标签。 span
标签在段落的每个部分都有一堆css,具体取决于其正常文本还是初始化。
另一种格式是p
标签中的文本,没有span
标签,也没有css代码。我已经能够使用Beautifulsoup来获取只有网页上的小说的部分代码。我试图制作一个if
语句,如果span
存在于章节内容中,请运行一个代码,否则运行其他代码。
我尝试过使用来自beautifulsoup的if chapter.find('span') != []:
和if chapter.find_all('span') != []:
,但这些beautifulsoup代码返回实际值,而不是布尔值。如果章节有标签,我通过打印'是'或'否'来测试这个,但是当我检查2个不同的章节以确保它们没有不同的格式时,输出将只是'是',或者只是'否' 。
我正在使用的代码:
#get link for chapter 1 from index
r = requests.get(data[1]['link'])
soup = BeautifulSoup(r.content, 'html.parser')
# if webpage announcement change 0 to 1
chapter = soup.find_all('div', {"class" : "fr-view"})[0].find_all('p')
根据章节,输出为:
#chapter equals this
[<p dir="ltr"><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap">Chapter 1 - title</span></p>,
<p dir="ltr"><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap">stuff</span></p>,
<p dir="ltr"><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap">italizes</span><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap"> stuff</span></p>]
要么:
#chapter equals this
[<p>Chapter 6 - title</p>,
<p>stuff</p>]
我正在尝试制作和if
语句,可以阅读章节,并告诉我,如果span
标签退出,所以我可以执行正确的代码。
在Beautiful Soup 4.7+中,Beautiful Soup使用一个名为Soup Sieve的新CSS选择器库。使用find_all
和find
是一种有条件地过滤标签的好方法,但我想展示一种可以用来用CSS选择器进行复杂过滤的替代方法。 Soup Sieve提供了许多有用的功能,因为Beautiful Soup依赖于它,如果您使用的是Beautiful Soup 4.7+,它应该已经安装。
在这种情况下,我们只搜索p
标签,然后直接利用Soup Sieve的API创建一个过滤器来比较返回的标签。只是另一种做事的方式。
from bs4 import BeautifulSoup
import soupsieve as sv
html = """
<p dir="ltr"><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap">Chapter 1 - title</span></p>,
<p dir="ltr"><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap">stuff</span></p>,
<p dir="ltr"><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap">italizes</span><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap"> stuff</span></p>
<p>Chapter 6 - title</p>,
<p>stuff</p>
"""
soup = BeautifulSoup(html, "html.parser")
css_match = sv.compile(':has(span)')
for i in soup.select('p'):
if css_match.match(i):
print('found span')
else:
print('no span')
产量
found span
found span
found span
no span
no span
使用您的代码段:
html = """
<p dir="ltr"><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap">Chapter 1 - title</span></p>,
<p dir="ltr"><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap">stuff</span></p>,
<p dir="ltr"><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: italic; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap">italizes</span><span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: 400; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap"> stuff</span></p>
<p>Chapter 6 - title</p>,
<p>stuff</p>
"""
你可以试试这个:
soup = BeautifulSoup(html, "lxml")
my_p = soup.find_all('p')
for i in my_p:
if i.find('span'):
print('found span')
else:
print('no span')
输出:
found span`
found span
found span
no span
no span`
我想这就是你要找的东西。
以上是关于如何识别beautifulsoup返回的'p'标签中是否存在'span'子标签?的主要内容,如果未能解决你的问题,请参考以下文章
如何解决'连接中止'。使用BeautifulSoup在Python中出错
如何使用 BeautifulSoup 从表中抓取特定列并作为熊猫数据框返回