刚开始接触 bs4 的时候,我也很迷茫,以为 string 属性和 text 属性是同样的,不明白为何要分红两个属性。html
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。post
print(type(p.string)) # <class 'bs4.element.NavigableString'>
print(type(p.text)) # <class 'str'>
不要小看了这点区别,看下面的示例:url
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 属性的输出结果为:spa
some text
None
more text
None
text 属性的输出结果为:code
some text
more text
even more text
理解了 string 属性和 text 属性的返回类型,就能够明白结果为何是这样的了。xml
第一项,返回都是 “some text”,这能够理解;htm
第二项,string 返回 None,由于不存在 NavigableString 节点;blog
第三项,text 返回的是标签的全部字符串链接成的字符串,因此是“more text”element
第四项,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>标签
html = '''<div>
<p> 附件: <a href='xxx'>下载</a></p>
</div> '''
用 string 属性来获取的话,代码以下:
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 属性的话,就必须传递方法来实现,但结果可能就不是你想要的了
def txt(tag): return re.search('附件', tag.text) is not None print(soup.find_all(txt))
结果以下,把每一层显示的都包含进来了。
[<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>]
相关博文推荐: