前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python:bs4中 string 属性和 text 属性的区别及背后的原理

Python:bs4中 string 属性和 text 属性的区别及背后的原理

作者头像
丹枫无迹
发布2019-01-22 16:00:51
8080
发布2019-01-22 16:00:51
举报
文章被收录于专栏:学无止境学无止境

刚开始接触 bs4 的时候,我也很迷茫,觉得 string 属性和 text 属性是一样的,不明白为什么要分成两个属性。

代码语言:javascript
复制
html = '<p>hello world</p>'
soup = BeautifulSoup(html, 'lxml')
p = soup.p
print(p.string)  # hello word
print(p.text)    # hello word

输出的结果是一样的。但实际上,string 属性的返回类型是 bs4.element.NavigableString,而 text 属性的返回类型是 str。

代码语言:javascript
复制
print(type(p.string))   # <class 'bs4.element.NavigableString'>
print(type(p.text))     # <class 'str'>

不要小看了这点区别,看下面的示例:

代码语言:javascript
复制
html = '''<html>
<td>some text</td> 
<td></td>
<td><p>more text</p></td>
<td>even <p>more text</p></td>
</html>'''

soup = BeautifulSoup(html, 'lxml')
tds = soup.find_all('td')

for td in tds:
    print(td.string)

for td in tds:
    print(td.text)

string 属性的输出结果为:

代码语言:javascript
复制
some text
None
more text
None

text 属性的输出结果为:

代码语言:javascript
复制
some text

more text
even more text

理解了 string 属性和 text 属性的返回类型,就可以明白结果为什么是这样的了。

第一项,返回都是 “some text”,这可以理解;

第二项,string 返回 None,因为不存在 NavigableString 节点;

第三项,text 返回的是标签的所有字符串连接成的字符串,所以是“more text”

第四项,bs4 的文档中指出:(地址:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/#string

  如果 tag 只有一个 NavigableString 类型子节点,那么这个 tag 可以使用 .string 得到子节点。

  如果一个 tag 仅有一个子节点,那么这个 tag 也可以使用 .string 方法,输出结果与当前唯一子节点的 .string 结果相同。

  如果 tag 包含了多个子节点,tag 就无法确定 .string 方法应该调用哪个子节点的内容, .string 的输出结果是 None。

  那么自然 string 属性返回的结果是 None,text 属性返回的结果是“even more text”

另外,要注意的是 find 方法中的 text 参数,官方解释是:text 参数用于搜索字符串会找到 .string 方法与 text 参数值相符的tag。

也就是说,虽然参数名是 text,但实际上搜索的是 string 属性。

看下面的例子,我们需要查找到包含附件链接的<a>标签

代码语言:javascript
复制
html = '''<div>
    <p>
        附件:
        <a href='xxx'>下载</a></p>
</div>
'''

用 string 属性来获取的话,代码如下:

代码语言:javascript
复制
soup = BeautifulSoup(html, 'lxml')
tab = soup.find(text=re.compile('附件'))
print(type(tab))    # <class 'bs4.element.NavigableString'>
print(tab)          # 附件

可以看到获取到的是 NavigableString 标签,要获取<a>标签,可以配合 find_next_sibling() 方法。

如果使用使用 text 属性的话,就必须传递方法来实现,但结果可能就不是你想要的了

代码语言:javascript
复制
def txt(tag):
    return re.search('附件', tag.text) is not None


print(soup.find_all(txt))

结果如下,把每一层显示的都包含进来了。

代码语言:javascript
复制
[<html><body><div>
<p>
        附件:
        <a href="xxx">下载</a></p>
</div>
</body></html>, <body><div>
<p>
        附件:
        <a href="xxx">下载</a></p>
</div>
</body>, <div>
<p>
        附件:
        <a href="xxx">下载</a></p>
</div>, <p>
        附件:
        <a href="xxx">下载</a></p>]

相关博文推荐:

Python:bs4的使用

Python:requests:详解超时和重试

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档