Python html中一级元素.next_sibling打印为空

在学到BeautifulSoup库的兄弟节点有了疑惑,希望见到这篇文章的各位大神们能帮我解决这个疑惑。

以下是出现问题的代码,没有报错,只是实现与我期望的不同。

from bs4 import BeautifulSoup
sibling_html = """
    <html>
        <body>
            <p><p id="p1">biubiubiu</p><p id="p2">piupiupiu</p>
            <p>哔哩哔哩</p>
            <a class="brother" href="www.baidu.com" id="link1">Lazer</a>
            <a id="link2"><b>text1</b><c>text2</c></a>
            <a id="link3" href="wwww.163.com">163</a>
        </body>
    </html>
"""
sibling_soup = BeautifulSoup(sibling_html, 'lxml')
br = sibling_soup.p
while br.next_sibling != None:
    print br
    br = br.next_sibling

根据百度,兄弟节点是同级的节点,我理解在代码中<p><p id="p1">biubiubiu</p><p id="p2">piupiupiu</p>、<p>哔哩哔哩</p>、<a class="brother" href="www.baidu.com" id="link1">Lazer</a>都是同级的节点,所以

print br #打印出第一个p标签的节点,预期是打印出<p><p id='p1'>biubiubiu</p><p id='p2'>piupiupiu</p></p>

实际上打印的是:

<p></p>

理论上得到的下一个节点是

<p>哔哩哔哩</p>
实际上打印出来的下一个节点是:

<p id="p1">biubiubiu</p>


即原本是子节点的p1、p2被当成了p的兄弟节点,经过朋友的指点,用beautifulsoup对象.prettify来打印网页解析结果。

print sibling_soup.prettify
#打印出来的解析结果
#<html>\n<body>\n<p></p><p id="p1">biubiubiu</p><p id="p2">piupiupiu</p>\n
#<p>\u54d4\u54e9\u54d4\u54e9</p>\n
#<a class="brother" href="www.baidu.com" id="link1">Lazer</a>\n<a #id="link2"><b>text1</b><c>text2</c></a>\n
#<a href="wwww.163.com" id="link3">163</a>\n</body>\n</html>\n>

可以看到lxml解析器将第一个p的结束标签自动添加了上去,导致p1、p2变成和p同级的节点,在BeautifulSoup构造方法里修改解析器为python自带的解析器html.parser:

sibling_soup = BeautifulSoup(sibling_html, 'html.parser')
#打印出来的解析结果
#<html>\n<body>\n<p><p id="p1">biubiubiu</p><p id="p2">piupiupiu</p></p>\n
#<p>\u54d4\u54e9\u54d4\u54e9</p>\n<a class="brother" href="www.baidu.com" id="link1">Lazer</a>\n
#<a id="link2"><b>text1</b><c>text2</c></a>\n<a href="wwww.163.com" #id="link3">163</a>\n</body>\n</html>\n>

用了html.parser解析器后,网页解析正常,此时再print出所有兄弟字节就成功了:

#输出结果

<p><p id="p1">biubiubiu</p><p id="p2">piupiupiu</p></p>


<p>哔哩哔哩</p>


<a class="brother" href="www.baidu.com" id="link1">Lazer</a>


<a id="link2"><b>text1</b><c>text2</c></a>


<a href="wwww.163.com" id="link3">163</a>

而中间有换行,可能是因为网页解析将换行、空格等也一并解析了,当成是与p、a标签同级的子节点。


总结:当遇到输出节点与预想不一致时,print下beautifulsoup对象.prettify查看网页解析结果,确认是否是解析器导致的出入,如果是,更改解析器再查看结果。

附上从教程转来的解析器对照表:

解析器使用方法优势劣势
Python标准库BeautifulSoup(markup,"html.parser")1. Python的内置标准库
2. 执行速度适
3. 中文档容错能力强
Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
lxml HTML 解析器BeautifulSoup(markup,"lxml")1. 速度快
2. 文档容错能力强
需要安装C语言库
lxml XML 解析器BeautifulSoup(markup,["lxml-xml"])
BeautifulSoup(markup,"xml")
1. 速度快
2. 唯一支持XML的解析器
需要安装C语言库
html5libBeautifulSoup(markup,"html5lib")1. 最好的容错性
2. 以浏览器的方式解析文档
3. 生成HTML5格式的文档
速度慢,不依赖外部扩展

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值