BeautifulSoup库/bs4 基础&深入 技术干货

BeautifulSoup库的安装

pip install bs4

对HTML的装载,prettify()即表示整理,能清晰的显示文档结构(文档数)

 soup  = BeautifulSoup(doc,"lxml")
 s = soup.prettify()
 print("s")

如果HTML缺失缺失,beautifulsoup库会自动补缺。

BeautifulSoup查找文档元素

获取网页html代码以后,那么我们要把它装在在一个beautifulsoup的对象当中,那么如何在文档中找到目标元素

  1. 如何查找html元素
    利用find_all()函数,其原型为:
find_all(self,name = None, attrs = {},
recursive = True, text = None, 
limit = None,**kwargs)
元素 含义
self 类成员函数
name 要查找的tag元素名称,默认是None,如果不提供,就是查找所有的元素
attrs 是元素的属性,字典,默认是空,如果提供就是查找有这个指定属性的元素

find_all函数是查找所有满足要求的元素节点,如果只查找一个元素节点就可以使用find()函数

find(self, name = None, attrs = {}, 
recursive = True,text = None,
 limit = None, **kwargs)

其使用方法与find_all类似,不同的是它只返回第一个满足要求的节点,不是一个列表。

示例:查找文档中class="title"的< p >元素

from bs4 import BeautifulSoup
doc = '''
the Dormouse's story

the Dormouse's story

once uopn a time ther were three little sisters;and their names were , lacieand tillie; and they lived an the bottom of a well.

...

'''

利用find()函数

soup = BeautifulSoup(doc,"lxml")
tag = soup.find_all("p", attrs = {"class":"title"})
print(tag)
#result:

the Dormouse's story

因为这条目标信息因为其位置在最前面,所以用find()同样也能找到。

soup = BeautifulSoup(doc,"lxml")
tags = soup.find_all(name = None, attrs = {"class":"sister"})
for tag in tags:
    print(tag)
#result:
,

lacie
tillie

对于这个文档同样可以使用:

tags = soup.find_all("a")
tags_1 = soup.find_all("a",attrs = {"class","sister"})
print(tags)
print("\n",tags_1)
#result:
[,
, lacie, tillie]

 [,
, lacie, tillie]

两者效果一致

BeautifulSoup获取元素的属性值

如果一个元素已经找到,例如找到< a >元素,则可以通过tag[attrName]来获取tag元素的名称为attrName的属性值,其中tag是一个bs4.element.Tag对象。
例如:查找文档中所有的超链接地址

soup = BeautifulSoup(doc,"lxml")
tags = soup.find_all("a")
for tag in tags:
    print(tag["href"])
 #result:
 http://example.com/elsie
http://example.com/lacie
http://example.com/tillie

BeautifulSoup获取元素包含的文本值

使用方法:tag,text来获取tag元素包含的文本值,其中tag是一个bs4.element.Tag对象。
例如:查找文本中所有< a >超级链接包含的文本值

soup = BeautifulSoup(doc,"lxml")
tags = soup.find_all("a")
for tag in tags:
    print(tag.text)
#result:
,

lacie
tillie

tag.text获取的结果为一个标签下的所有文本

BeautifulSoup的高级查找

一般find或者find_all都能满足我们的需要,如果还不能,则可以设计一个查找函数来进行查找。

def mefilter(tag):
    print(tag.name)
    return(tag.name == "a" and tag.has_attr("href")and tag["href"]=="http://example.com/lacie")

soup = BeautifulSoup(doc,"lxml")
tag = soup.find_all(mefilter)
print("tag")
#result:
html
head
title
body
p
b
p
a
a
a
p
tag

说明:程序的运行中定义了一个筛选函数myfilter(tag)它的参数是tag对象,在调用soup.find_all(myfilter)时候会把每个tag元素传递给myfilter函数,返回True则取,否则就丢弃。

BeautifulSoup查找文档元素

高级查找要注意“class”标签为列表结构

def mefilter(tag):
    if tag.name == "p" and tag["class"] =="story":
        return True
soup = BeautifulSoup(doc,"html.parser")
tags = soup.find_all(mefilter)
print(tags)

def mefilter(tag):
    if tag.name == "p" and tag["class"] == ["story"]:
        return True
soup = BeautifulSoup(doc,"html.parser")
tags = soup.find_all(mefilter)
print("\n",tags)
#result:
[]

 [

once uopn a time ther were three little sisters;and their names were , lacieand tillie; and they lived an the bottom of a well.

,

...

]

tag[“class”]是一个很特殊的属性
倘若文本为< p class=“story exem”>,那么就应该写为:

tag["class"] == ["story","exem"]

BeautifulSoup遍历文档元素

获取元素节点的父节点、子节点、临近节点,所有子孙节点,兄弟节点

目的 操作
获取父节点 tag.parent
获取元素的直接子节点 tag.children
获取tag节点的所有子孙节点元素,包括element,text等类型的节点 tag.desendants
下一个兄弟节点 tag.next_sibling
前一个兄弟节点 tag.previous_sibling
#eg_1
soup = BeautifulSoup(doc,"lxml")
print(soup.name)
tag = soup.find("b")
while tag:
	print(tag.name)
	tag = tag.parent
#eg_2
suop = BeautifulSoup(doc,"lxml")
tag = soup.find("b")
print(tag.previous_sibling)

BeautifulSoup使用CSS语法查找元素
其除了自身的函数,还可以用CSS语法
CSS语法
tag.select(css)
其结构为:
[tagName][attName[=value]]
其中[…]部分是可选的

变量 含义
tagName 元素名称,没有指定就是所有元素
attName = value 属性名称,value是它对应的值
tag.select(css) 返回一个bs4.element.Tag的列表,可能只有一个元素

各种应用具体操作方法

目标 代码
soup.select(“p a”) 查找文档中所有< p >节点下的所有< a >节点
soup.select(“p[class=‘story’] a”) 查找文档中所有属性class="story"的< p >节点下的所有< a >元素节点
soup.select(“p[class] a”) 查找文档中所有具有class属性的< p >< a >元素节点
soup.select(“body head title”) 查找下面< head >的< title >节点
soup.select(“body[class]”) 查找< body >下面所有具有class属性的节点
soup.select(“body[class] a”) 查找< body >下面所有具有class属性的节点下面的< a >节点
soup.select(“a[id=‘link1’]”) 查找属性id="link1"的< a >节点

属性的语法规则

选择器 描述
[attName] 用于选取带有指定属性的元素
[attName-value] 用于选取带有指定属性的元素
attName^=value] 匹配属性值以指定值开头的每个元素
[attName$=value] 匹配属性值以指定结尾的每个元素
[attName*=value] 匹配属性中包含指定值的每个元素
#查找所有< div >节点下面的所有直接子节点< p >
#不包含孙节点
#注意 p左右有空格
soup.select("div > p")

你可能感兴趣的:(python,学习,学习笔记)