我正在制作一个网络抓取器,该抓取器从索引网页上抓取一本在线小说,并且代码为小说的每本书创建了一个epub文件。小说的翻译者以两种不同的格式设置了小说的网页。
第一种格式是带有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
标签是否退出,以便我可以执行正确的代码。
答案 0 :(得分:1)
使用代码段:
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`
我认为这就是您想要的。
答案 1 :(得分:1)
在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