CSS 选择器:BeautifulSoup4解析器(二)

简介: CSS 选择器:BeautifulSoup4解析器(二)

遍历文档树



1. 直接子节点 :.contents .children 属性


.content


tag 的 .content 属性可以将tag的子节点以列表的方式输出


print soup.head.contents 
#[<title>The Dormouse's story</title>]


输出方式为列表,我们可以用列表索引来获取它的某一个元素


print soup.head.contents[0]
#<title>The Dormouse's story</title>
.children


它返回的不是一个 list,不过我们可以通过遍历获取所有子节点。


我们打印输出 .children 看一下,可以发现它是一个 list 生成器对象


print soup.head.children
#<listiterator object at 0x7f71457f5710>
for child in  soup.body.children:
    print child


结果:


<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>


2. 所有子孙节点: .descendants 属性


.contents 和 .children 属性仅包含tag的直接子节点,.descendants 属性可以对所有tag的子孙节点进行递归循环,和 children类似,我们也需要遍历获取其中的内容。


for child in soup.descendants:
    print child


运行结果:


<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body></html>
<head><title>The Dormouse's story</title></head>
<title>The Dormouse's story</title>
The Dormouse's story
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<b>The Dormouse's story</b>
The Dormouse's story
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
 Elsie 
,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
Lacie
 and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
Tillie
;
and they lived at the bottom of a well.
<p class="story">...</p>
...


3. 节点内容: .string 属性


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


通俗点说就是:如果一个标签里面没有标签了,那么 .string 就会返回标签里面的内容。如果标签里面只有唯一的一个标签了,那么 .string 也会返回最里面的内容。例如:


print soup.head.string
#The Dormouse's story
print soup.title.string
#The Dormouse's story


搜索文档树



1.find_all(name, attrs, recursive, text, **kwargs)


1)name 参数


name 参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉


A.传字符串


最简单的过滤器是字符串.在搜索方法中传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容,下面的例子用于查找文档中所有的<b>标签:


soup.find_all('b')
# [<b>The Dormouse's story</b>]
print soup.find_all('a')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]


B.传正则表达式


如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容.下面例子中找出所有以b开头的标签,这表示<body>和<b>标签都应该被找到


import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
# body
# b


C.传列表


如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.下面代码找到文档中所有<a>标签和<b>标签:


soup.find_all(["a", "b"])
# [<b>The Dormouse's story</b>,
#  <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]


2)keyword 参数


soup.find_all(id='link2')
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]


3)text 参数


通过 text 参数可以搜搜文档中的字符串内容,与 name 参数的可选值一样, text 参数接受 字符串 , 正则表达式 , 列表


soup.find_all(text="Elsie")
# [u'Elsie']
soup.find_all(text=["Tillie", "Elsie", "Lacie"])
# [u'Elsie', u'Lacie', u'Tillie']
soup.find_all(text=re.compile("Dormouse"))
[u"The Dormouse's story", u"The Dormouse's story"]

CSS选择器



这就是另一种与 find_all 方法有异曲同工之妙的查找方法.


写 CSS 时,标签名不加任何修饰,类名前加.,id名前加#


在这里我们也可以利用类似的方法来筛选元素,用到的方法是 soup.select(),返回类型是 list


(1)通过标签名查找


print soup.select('title') 
#[<title>The Dormouse's story</title>]
print soup.select('a')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
print soup.select('b')
#[<b>The Dormouse's story</b>]


(2)通过类名查找


print soup.select('.sister')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]


(3)通过 id 名查找


print soup.select('#link1')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]


(4)组合查找


组合查找即和写 class 文件时,标签名与类名、id名进行的组合原理是一样的,例如查找 p 标签中,id 等于 link1的内容,二者需要用空格分开



print soup.select('p #link1')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]


直接子标签查找,则使用 > 分隔


print soup.select("head > title")
#[<title>The Dormouse's story</title>]


(5)属性查找


查找时还可以加入属性元素,属性需要用中括号括起来,注意属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到。


print soup.select('a[class="sister"]')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
print soup.select('a[href="http://example.com/elsie"]')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]


同样,属性仍然可以与上述查找方式组合,不在同一节点的空格隔开,同一节点的不加空格


print soup.select('p a[href="http://example.com/elsie"]')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]


(6) 获取内容


以上的 select 方法返回的结果都是列表形式,可以遍历形式输出,然后用 get_text() 方法来获取它的内容。


soup = BeautifulSoup(html, 'lxml')
print type(soup.select('title'))
print soup.select('title')[0].get_text()
for title in soup.select('title'):
    print title.get_text()


目录
相关文章
|
3月前
|
存储 移动开发 前端开发
高效的 HTML 与 CSS 编写技巧,涵盖语义化标签、文档结构优化、CSS 预处理、模块化设计、选择器优化、CSS 变量、媒体查询等内容
本文深入探讨了高效的 HTML 与 CSS 编写技巧,涵盖语义化标签、文档结构优化、CSS 预处理、模块化设计、选择器优化、CSS 变量、媒体查询等内容,旨在提升开发效率、网站性能和用户体验。
86 5
|
3月前
|
前端开发 JavaScript UED
深入理解与应用 CSS 伪类选择器
【10月更文挑战第23天】通过以上对 CSS 伪类选择器的深入探讨,我们可以更好地理解和应用它们,为网页设计和开发带来更丰富、更灵活的样式效果。同时,要注意在实际应用中根据具体情况合理选择和使用伪类选择器,以达到最佳的设计效果和用户体验。
81 2
|
4月前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
4月前
|
前端开发
CSS常见的选择器
CSS常见的选择器
41 0
|
5月前
|
前端开发
CSS:高级选择器
CSS:高级选择器
66 1
|
5月前
|
前端开发 JavaScript
CSS:基础选择器
CSS:基础选择器
75 1
|
5月前
|
前端开发 JavaScript 容器
谁动了我的选择器?深入理解CSS选择器优先级
该文章详细解释了CSS选择器的工作原理,包括不同种类选择器的权重计算规则,并通过实例说明了如何解决样式冲突问题,确保所需的样式能够正确应用到目标元素上。
|
5月前
|
前端开发
前端基础(四)_CSS层叠样式表_什么是css_css样式的引入方式_样式表的优先级_样式选择器
本文详细介绍了CSS(层叠样式表)的基本概念、语法规则、引入方式、样式表的优先级和样式选择器。文章解释了CSS的作用,展示了如何在HTML中通过行内样式、内部样式和外部样式引入CSS,讨论了不同CSS选择器的优先级和如何确定最终的样式应用。此外,还强调了使用`!important`规则时的优先级高于行内样式。
190 1
|
5月前
|
前端开发 JavaScript
【CSS】选择器
【CSS】选择器
|
6月前
|
前端开发 Java UED
JSF 面向组件开发究竟藏着何种奥秘?带你探寻可复用 UI 组件设计的神秘之路
【8月更文挑战第31天】在现代软件开发中,高效与可维护性至关重要。JavaServer Faces(JSF)框架通过其面向组件的开发模式,提供了构建复杂用户界面的强大工具,特别适用于设计可复用的 UI 组件。通过合理设计组件的功能与外观,可以显著提高开发效率并降低维护成本。本文以一个具体的 `MessageComponent` 示例展示了如何创建可复用的 JSF 组件,并介绍了如何在 JSF 页面中使用这些组件。结合其他技术如 PrimeFaces 和 Bootstrap,可以进一步丰富组件库,提升用户体验。
76 0

热门文章

最新文章

推荐镜像

更多