BeautifiulSoup和lxml一样也是一个HTML/XML的解析器,主要功能是解析和提取HTML/XML数据。

lxml只会局部遍历,而BEautifulSoup是基于HTML DOM(Document OBject Model)的,会载入整个文档,解析整个DOM树,因此,时间和内存开销都会大很多,所以性能低于lxml。

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

 

几大解析工具对比:

解析工具 解析速度 使用难度
BeautifulSoup 最慢 最简单
lxml 简单
正则 最快 最难

 

 

安装和和文档:

1. 安装:pip install bs4

2. 中文文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

 

常见的四种对象:

1. Tag:BeautifulSoup中所有的标签都是Tag类型,并且BeautifulSoup的对象本质上也是一个Tag类型。所以一些方法比如:find、find_all并不是BeautifulSoup的,而是Tag的。

2. NavigableStrings: 继承自python中的str,用起来就跟使用python的str一样。

3. BeautifulSoup: 继承自Tag。用来生成BeautifulSoup树。对于一些查找方法:比如:find、select,其实还是Tag的。

4. Comment:继承自NavigableStrings。

 

beautifulSoup 的基本使用:

# pip install lxml
bs = BeautifulSoup(html,'lxml')
print(bs.prettify())

  "lxml"是解析器,使用之前先安装;html 为符合HTML格式的字符串;‘prettify()’函数是为了规范解析出来的内容,合理、美观。

 

find_all的使用:

1.在提取标签的时候,第一个参数是标签名字。如果在提取标签的时候想要使用标签属性进行过滤,那么可以在这个方法中通过关键字参数的形式,将属性的名字以及对应的值传进去(如果与python的关键字重复,则加下划线,如:class_),或者使用‘attrs'属性,将所有的属性以及对应的值放在一个字典中传给'attrs'属性。

2. 可以使用'limit'参数,限制提取标签的数量。

from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
# 1. 获取所有的tr标签
trs = soup.find_all('tr')
for tr in trs:
    print(tr)
# 2.获取第二个tr标签
tr = soup.find_all('tr',limit=2)[1]
print(tr)
# 3. 获取所有class等于even的tr标签
# 方式一:
trs = soup.find_all('tr',class_='even')
# 方式二:
trs = soup.find_all('tr',attrs={'class':'even'})
for tr in trs:
    print(tr)
# 4. 将所有id等于test,class也等于test的a标签提取出来。
aList = soup.find_all('tr',id='test',class_='test')
aList = soup.find_all('tr',attrs={'id':'test','class':'test'})
for a in aList:
    print(a)
# 5. 获取所有a标签的href属性
aList = soup.find_all('tr')
for a in aList:
    # 方式一
    href = a['href']
    # 方式二
    href = a.attrs['href']
    print(href)
# 6,获取所有职位信息(纯文本)
movies = []
trs = soup.find_all('tr')[1:]

for tr in trs:
    movie = {}
    
    # 方法一
    tds = tr.find_all('td')
    title = tds[0].string
    category = tds[1].string
    nums = tds[2].string
    city = tds[3].string
    pubtime = tds[4].string
    movie = {
        'title':title,
        'category': category,
        'nums':nums,
        'city':city,
        'pubtime':pubtime
    }
    movies.append(movie)

    # 方法二
    infos = list(tr.stripped_strings)
    movie = {
        'title': infos[0],
        'category': infos[1],
        'nums': infos[2],
        'city': infos[3],
        'pubtime': infos[4]
    }
    movies.append(movie)
View Code

 

find 与 find_all的区别:

1. find:只查找一个元素标签就返回;

2.find_all:将所有满足条件的标签以列表形式全部返回,

 

 

string、strings、stripped_strings和get_text 方法的区别:

1. string:获取某个标签下的非标签字符串,返回的是一个字符串,只能获取一行数据,如果有多个换行符时,就无法获取有用数据;

2. strings: 获取某个标签下的子孙非标签字符串,返回的是一个生成器;

3. stripped_strings:获取某个标签的子孙非标签字符串,会去掉空白字符,返回的是一个生成器;

4. get_text: 获取某个标签下的子孙非标签字符串,以普通字符串返回。

 

select方法:

有时候使用css选择器可以更加的方便。使用css选择器应该使用select方法:

(1)通过标签名查找:

soup.select('a')

(2) 通过类名查找

通过类名查找,应该在类的前面加一个 . 。比如要查找class=sister的标签:

soup.select('.sister')

(3)通过id查找

通过id 查找,应该在id的名字前面加一个#号。比如要查找id = link1的标签:

soup.select('#link1')

(4)组合查找

例如要查找p标签中,id等于link1的内容,二者需要空格隔开。

soup.select('p #link1'

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

soup.select('head>title')

(5)通过属性查找

通过属性查找时,属性应该使用中括号括起来,属性和标签属于同一节点,中间不能加空格,否则无法匹配到。

soup.select("a[href='http://www.example.com']")

 

from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
# 1. 获取所有的tr标签
trs = soup.select('tr')
for tr in trs:
    print(tr)
# 2.获取第二个tr标签
tr = soup.select('tr')[1]
print(tr)
# 3. 获取所有class等于even的tr标签
# 方式一:
trs = soup.select('.even')
# 方式二:
trs = soup.select("tr{"class':'even'}")
for tr in trs:
    print(tr)

# 4. 获取所有a标签的href属性
aList = soup.select('a')
for a in aList:
    href = a['href']
   
# 5,获取所有职位信息(纯文本)
trs = soup.select('tr')
for tr in trs:
    infos = list(tr.stripped_strings)
    print(infos)
View Code

 

 

contents 和 children:

返回某个标签下的直接子元素,其中包括字符串。区别是:contents返回的是一个列表,children返回的是一个迭代器。

 

 

 

 

 

 

 

 

 

 

 

posted on 2020-10-22 20:58  -豪-  阅读(182)  评论(0编辑  收藏  举报