第四章 bs4与css选择器

在这里插入图片描述

简介

BeautifulSoup 是一个HTML/XML的解析器,主要用于解析和提取HTML/XML 数据。

它基于HTML DOM的,会载入整个文档,解析整个DOM树,因此时间和内存开销都会大很多,所以性能要低于lxml。

BeautifulSoup用来解析HTML 比较简单,API非常人性化,支持CSS选择器、Python标准库中的HTML解析器,也支持lxml 的XML解析器。

官方文档:http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0

抓取工具 速度 难度
正则 最快 复杂
BeautifulSoup 简单
xpath 简单

安装

在pycharm的terminal终端命令窗口中输入:
pip install beautifulsoup4
或者使用清华源的镜像,会更快一点
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple beautifulsoup4

知识

初始化

from bs4 import BeautifulSoup

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>

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

<p class="story">...</p>
"""

root = etree.HTML(html_doc)
root.xpath()

# 加载字符串 构建BeautifulSoup对象 指明解析器
soup = BeautifulSoup(html_doc,"lxml")
soup.select()
# 加载文档
soup = BeautifulSoup(open("path"),"lxml")
# 格式化输出加载的内容
print(soup.prettify())

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以分为4种。

Tag(标签)

最重要的一类对象,后边解析网页就靠它了。

用BeautifulSoup来获取Tags

from bs4 import BeautifulSoup

# 加载字符串 构建BeautifulSoup对象 指明解析器
soup = BeautifulSoup(html_doc,"lxml")
# 加载文档
soup = BeautifulSoup(open("path"),"lxml")
# 格式化输出加载的内容
print(soup.prettify())

# 注意,它查找的是在所有内容中的第一个符合要求的标签。
# 等同于xpath的 //title[1]
print(soup.title)
print(soup.head)
print(soup.a)
print(soup.p)
print(type(soup.p))

对于Tag,它有两个重要的属性,是name 和attrs(attributes)

#soup对象本身比较特殊,它的name即为[document]
print(soup.name)
print(soup.head.name)

#把p标签的所有属性打印输出了出来,得到的类型是一个字典。
print(soup.p.attrs["class"])   attributes
#根据名称获取对应的属性值,类型为列表
print(soup.p['class'])
#//p[1]/@class
print(soup.p.get('class'))

===没啥用====
#可以对这些属性和内容等等进行修改
soup.p['class']="newClass"
print(soup.p)
#删除属性
del soup.p['class']
print(soup.p)

NavigableString(标签文本内容)

获取标签内部的文字用.string即可,例如

print(soup.p.string)
#The Dormouse's story

# //p[1]/text()
print(type(soup.p.string))
#In[13]:<class'bs4.element.NavigableString'>

BeautifulSoup(根对象)(没啥用)

BeautifulSoup 对象表示的是一个文档的内容。大部分时候,可以把它当作Tag对象,是一个特殊的Tag,我们可以分别获取它的类型,名称,以及属性

print(type(soup.name))
#<type'unicode'>

print(soup.name)
#[document]

# attributes
print(soup.attrs)
#文档本身的属性为空

Comment(注释内容)

Comment对象是一个特殊类型的NavigableString对象,其输出注释但不包含注释符号。

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

print(soup.a.string)
#Elsie

print(type(soup.a.string))#<class'bs4.element.Comment'>

a 标签里的内容实际上是注释,但是如果我们利用.string 来输出它的内容时,注释符号已经去掉了。

遍历文档树

.contents

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

print(soup.head.contents)
print(soup.head.contents[0])

.children

它返回的不是一个list,不过我们可以通过遍历获取所有子节点。
我们打印输出.children 看一下,可以发现它是一个list 生成器对象

print(soup.head.children)
for child in soup.body.children:
	print(child)

.descendants属性

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

for child in soup.descendants:
	print(child)

CSS选择器

通过标签名查找

语法格式:
#xpath: //标签名
soup.select(‘标签名’)

查找所有title标签
print(soup.select(‘title’))
查找所有a标签
print(soup.select('a'))
查找标签b标签
print(soup.select('b'))

通过类名查找

语法格式:
#xpath //*[@class=“类名”]
soup.select(’.类名’)

查找所有class是sister的标签
print(soup.select(‘.sister’))

通过ID查找

语法格式:
#xpath: //*[@id=“id名字”]
soup.select(’#id名字’)

查找所有id是link1的标签
print(soup.select(‘#link1’))

组合查找

直接子集查找

直接子标签查找,则使用 > 分隔。
例如查找head标签直接子集中,标签为title的元素,二者需要用 。

# xpath:     //head/title
print(soup.select("head > title"))

所有子集查找

每块表达式用 空格 连接。
例如查找p 标签中,id 等于link1的内容,二者需要用空格分开。

# xpath:    //p//*[@id="link"]
print(soup.select('p #link1'))

属性查找

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

# 查找所有class属性值为sister的a标签
#xpath //a[@class="sister"]
print(soup.select('a[class="sister"]'))

# 查找所有href属性值为"http://example.com/elsie"的a标签
#xpath //a[@href="http://example.com/elsie"]
print(soup.select('a[href="http://example.com/elsie"]'))

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

# 查找所有p标签下 href属性值为"http://example.com/elsie"的a标签

#xpath //p//a[@href="http://example.com/elsie"]/*[@class="className"]
print(soup.select('p a[href="http://example.com/elsie"] > .className')

任务

双色球信息爬取
http://zst.aicai.com/ssq/openInfo/
在这里插入图片描述
豆瓣新书的信息爬取
https://book.douban.com/latest
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章