BS4解析库使用


BS4解析库

Beautiful Soup简称BS4(4表示版本号),是一个python第三方库,它可以从HTML或XML文档中快速提取指定的数据。

BS4安装

pip3 install bs4
#BS4解析页面时,需要依赖文档解析器,所以还需要安装lxml作为解析库
pip3 install lxml

BS4解析对象

创建BS4解析对象是万事开头的第一步

#导入解析包
from bs4 import BeautifulSoup
#创建beautifulsoup解析对象
soup = BeautifulSoup(html_doc,"lxml")
#注:如果是外部文档,可以通过open()方式打开读取,格式如下:
soup = BeautifulSoup(open('html_doc.html',encoding="utf-8"),"lxml")

BS4常用语法

Beautiful Soup将HTML文档转换成一个树形结构,该结构有利于快速的遍历和搜索HTML文档。

c语言中文网

c.biancheng.net

一个学习编程的网站

对应树状图如下:

文档树中的每个节点都是python对象,这些对象大致可分为四类:Tag、NavigableString、BeautifulSoup、Comment。其中使用最多的是Tag和NavigableString。

  • Tag:标签类,HTML文档中所有的标签都可以看做Tag对象
  • NavigableString:字符串类,指的是标签中的文本内容,使用text、string、strings来获取文本内容
  • BeautifulSoup:表示一个HTML文档的全部内容,可以将其当做一个特殊的tag对象
  • Comment:表示HTML文档中的注释内容以及特殊字符串,它是一个特殊的NavigableString

Tag节点

标签是组成HTML文档的基本元素。在BS4中,通过标签名和标签属性可以提取出想要的内容。示例如下:

#!/usr/bin/python3
#coding=utf-8

from bs4 import BeautifulSoup

soup = BeautifulSoup('

c.biancheng.net

',"lxml") #获取整个p标签的html代码 print("soup.p输出结果:") print(soup.p) #获取b标签 print("soup.p.b输出结果:") print(soup.p.b) #获取p标签内容,使用NavigableString类中的string、text、get_text() print("soup.p.text输出结果:") print(soup.p.text) #获取p标签属性 print("soup.p.attrs输出结果:") print(soup.p.attrs) #查看返回的数据类型 print("type(soup.p)输出结果:") print(type(soup.p)) #根据属性,获取标签的属性值,返回值为列表】 print("soup.p['class']输出结果是") print(soup.p["class"]) #给class属性赋值,此时属性值由列表转换为字符串 soup.p["class"] = ["Torres","Web"] print(soup.p)

执行结果如下:

soup.p输出结果:

c.biancheng.net

soup.p.b输出结果: c.biancheng.net soup.p.text输出结果: c.biancheng.net soup.p.attrs输出结果: {'class': ['Web', 'site', 'url']} type(soup.p)输出结果: soup.p['class']输出结果是 ['Web', 'site', 'url']

c.biancheng.net

遍历节点

Tag对象提供了许多遍历tag节点的属性,比如concents、children用来遍历子节点;parent和parents用来遍历父节点;而next_sibling和previous_sibling则用来遍历兄弟节点。示例如下:

#!/usr/bin/python3
#coding=utf-8

from bs4 import BeautifulSoup

html_doc = """
"c语言中文网"

c.biancheng.net

一个学习编程的网站

python教程, c语言教程 and """ soup = BeautifulSoup(html_doc,"html.parser") body_tag = soup.body print(body_tag) print(body_tag.contents) #Tag的children属性会生成一个可迭代对象,可用来遍历子节点 for child in body_tag.children: print(child)

输出结果:


c.biancheng.net

一个学习编程的网站

python教程, c语言教程 and #以列表形式输出 ['\n',

c.biancheng.net

, '\n',

一个学习编程的网站

, '\n', python教程, ',\n', c语言教程, ' and\n'] #child

c.biancheng.net

一个学习编程的网站

python教程 , c语言教程 and

find()和find_all()

find()和find_all()是解析HTML文档的常用方法,它们可以在HTML文档中按照一定的条件(相当于过滤器)查找所需内容。

find_all()

find_all()方法用来搜索当前tag的所有子节点,并判断这些节点是否符合过滤条件,最后以列表形式将符合条件的内容返回,语法格式如下:

find_all(name,attrs,recursive,text,limit)

参数说明:

  • name:查找所有名字为name的tag标签,字符串对象会被自动忽略
  • attrs:按照属性名和属性值搜索tag标签(注意:由于class是python的关键字,所以要用“class_”)
  • recursive:find_all()会搜素tag的所有子孙节点,设置recursive=False可以只搜索tag的直接子节点
  • text:用来搜索文档中的字符串内容,该参数可以接收字符串、正则表达式、列表、True。
  • limit:由于find_all()会返回所有的搜索结果,这样会影响执行效率,通过limit参数可以限制返回结果的数量

使用示例如下:

#!/usr/bin/python3
#coding=utf-8

import re
from bs4 import BeautifulSoup

html_doc = """
"c语言中文网"

c.biancheng.net

一个学习编程的网站

python教程 c语言教程 django教程

加入我们阅读所有教程

成为vip """ #创建soup解析对象 soup = BeautifulSoup(html_doc,"lxml") #查找所有a标签并返回 print(soup.find_all("a")) #查找前两条标签 print(soup.find_all("a",limit=2))

返回结果如下:

>>> soup = BeautifulSoup(html_doc,"lxml")

>>> print(soup.find_all("a"))
[python教程, c语言教程, django教程, 成为vip]
#只返回前两条结果
>>> print(soup.find_all("a",limit=2))
[python教程, c语言教程]
#列表查询tag标签
>>> print(soup.find_all(['b','a']))
[c.biancheng.net, python教程, c语言教程, django教程, 成为vip]
#正则表达式匹配id属性值
>>> print(soup.find_all("a",id=re.compile(r".\d")))
[python教程, c语言教程, django教程, 成为vip]
#True可以匹配任何值,以下返回相应的tag名称
>>> for tag in soup.find_all(True):
...     print(tag.name)
... 
html
head
title
body
p
b
p
a
a
a
p
a
#输出所有以b开始的tag标签
>>> for tag in soup.find_all(re.compile("^b")):
...     print(tag.name)
... 
body
b

find()

find()和find_all()类似,不同之处在于:find_all()会将文档这是所有符合条件的结果返回,而find()仅返回第一个符合条件的结果,所以find()方法没有limit参数。示例如下:

#!/usr/bin/python3
#coding=utf-8

import re
from bs4 import BeautifulSoup

html_doc = """
"c语言中文网"

c.biancheng.net

一个学习编程的网站

python教程 c语言教程 django教程

加入我们阅读所有教程

成为vip """ #创建soup解析对象 soup = BeautifulSoup(html_doc,"lxml") #查找第一个a标签并返回 print(soup.find_("a")) #查找title print(soup.find("title")) #匹配指定herf属性的a标签 print(soup.find("a",href='http://c.biancheng.net/python/')) #根据属性值正则匹配 print(soup.find(class_=re.compile("tit"))) #attr参数值 print(soup.find(attrs={"class":"vip"}))

结果如下:

#查找第一个a标签并返回
>>> print(soup.find("a"))
python教程
#查找title
>>> print(soup.find("title"))
"c语言中文网"
#匹配指定herf属性的a标签
>>> print(soup.find("a",href="http://c.biancheng.net/python/"))
python教程
#根据属性值正则匹配
>>> print(soup.find(class_=re.compile("tit")))

c.biancheng.net

#attr参数值 >>> print(soup.find(attrs={"class":"vip"}))

加入我们阅读所有教程

CSS选择器

BS4支持大部分的CSS选择器,比如常见的标签选择器、类选择其、id选择器以及层级选择器。Beautiful Soup提供了一个select()方法,通过想该方法中添加选择器,就可以在HTML文档中搜索到与之对应的内容,示例如下:

#!/usr/bin/python3
#coding=utf-8

from bs4 import BeautifulSoup

html_doc = """
"c语言中文网"

c.biancheng.net

一个学习编程的网站

python教程 c语言教程 django教程

加入我们阅读所有教程

成为vip

介绍: 关于网站 关于站长

""" soup = BeautifulSoup(html_doc,"lxml") #根据元素标签查找 print(soup.select("title")) #根据属性选择器查找 print(soup.select("a[href]")) #根据类查找 print(soup.select(".vip")) #后代节点查找 print(soup.select("html head title")) #查找兄弟节点 print(soup.select("p + a")) #根据id选择p标签的兄弟节点 print(soup.select("p ~ #link3")) #nth-of-type(n)选择器,用于匹配同类型中的第n个同级兄弟元素 print(soup.select("p ~ a:nth-of-type(1)")) #查找子节点 print(soup.select("p > a")) print(soup.select(".introduce > #link5"))

结果如下:

[root@aliyun ~]# python3 /home/python/test.py
["c语言中文网"]
[python教程, c语言教程, django教程, 成为vip, 关于网站, 关于站长]
[

加入我们阅读所有教程

] ["c语言中文网"] [python教程, 成为vip] [django教程] [python教程] [关于网站, 关于站长] [关于网站]