BeautifulSoup
正文
1 基本信息
Beautiful Soup是用于处理解析页面信息的
具体的说, Beautiful Soup库是解析, 遍历, 维护"标签树"的功能库
安装方法
pip install beautifulsoup4
最基本的使用
1 2 3 4 5 6 | import requests from bs4 import BeautifulSoup r = requests.get( "http://www.baidu.com" ) soup = BeautifulSoup(r.content, 'html.parser' ) print (soup.prettify()) |
2 基本元素
Beautiful Soup处理的内容文档一般是HTML页面
HTML页面是标签对形成的
这些标签对最终会形成标签树, 这些标签树实际上是Beautiful Soup类
也就是 HTML文档<---->标签树<---->Beautiful Soup类
Beautiful Soup的解析器
最主要的还是是用 html.parser解析器
Beautiful Soup类的基本元素
使用方法如下:
1) Tag标签
使用方法
BS对象.标签名字
1 2 | soup.a soup.title |
其中如果该标签在页面存在多个, 那么只返回第一个
2) name
使用方法
BS对象.标签名字.name
3) attrs
使用方法
其中attrs获得的是一个字典类型的值
通过属性名字得到的就是列表类型
BS对象.标签名字.attrs
BS对象.标签名字.attrs['某个属性的名字']
1 2 | soup.a.sttrs soup.a.attrs[ 'class' ] |
4) NavigableString
表示的是标签内非属性的字符串, 使用如下
其中string如果该标签内存在别的标签嵌套, 获得的就是嵌套内部的string
因此, NavigableString可以跨越多个层次
BS对象.标签名字.string
5) Comment
标签内注释部分
获取方法和NavigableString相同, 都是通过string来获得
3 标签树的遍历
遍历分为 下行遍历, 上行遍历, 平行遍历
上行遍历的主要有: contents, children, descendants
其中contens获得的是标签的所有内容
children或的是contents的具体的列表, 其中'\n'会被当做一个元素
descendants和children都是生成器, descendants会逐步往下遍历打印出所有子孙节点
上行遍历主要有: parent, parents
parent获得的是父亲节点, 获得的父亲节点包括该节点内的所有内容, 是一个很丰富的节点
parents是一个生成器, 倒数第二个是<html>标签. 最后一个是整个文档
平行遍历主要有: next_sibling, previous_sibling, next_siblings, previous_siblings
注意: 平行是指的在一个父节点下的子节点间的
其中next_sibling和previous_sibling是返回下一个或者上一个平行节点标签
next_siblings和previous_siblings是返回生成器类型
4 信息和组织方法
主要主流的有三种, XML, JSON, YAML
XML的主要形式
<person>
<firstName>Tian</firstName>
<lastName>Song</lastName>
<address>
<streetAddr>中关村南大街5号</streetAddr>
<city>北京市</city>
<zipcode>100081</zipcode>
</address>
<prof>Computer System</prof><prof>Security</prof>
</person>
JSON的主要形式
{
“firstName” : “Tian” ,
“lastName” : “Song” ,
“address” : {
“streetAddr” : “中关村南大街5号” ,
“city” : “北京市” ,
“zipcode” : “100081”
} ,
“prof” : [ “Computer System” , “Security” ]
}
YANL的主要形式
firstName : Tian
lastName : Song
address :
streetAddr : 中关村南大街5号
city : 北京市
zipcode : 100081
prof :
‐Computer System
‐Security
三种类型的对比
XML: 可扩展性好, 但是繁琐, 主要用于网络传递信息
JSON: 信息有类型, 适合程序处理, 没有注释, 主要用于移动应用云端和节点的通信
YAML: 无类型, 信息比例高, 可读性好, 各类系统的配置文件
5 基于bs4的HTML的查找
最基本find_all()方法的解析
BS对象.fand_all(name, attrs, recursive, string, **kwargs)
name: 是对标签名称的检索, 返回一个list类型,
如果需要对多个标签查询, 可以组成一个list传给name
name=True 表示显示当前BS对象的 所有标签信息
还可以用正则表达式来匹配名字
attrs: 对标签属性值的检索
可以直接传入参数
也可是使用键值对的方式
recursive: 是否符子孙全部检索, 默认为True
如果赋值为False的话, 就是从当前对象的子节点进行查找
string: 对字符串信息检索
由于find_all()方法是十分常用, 所以有一个简写形式
标签.fand_all() 简写为: 标签()
soup.find_all() 简写为: soup()
扩展方法
6 基于BS库的爬虫实例
实例一: 爬取大学排名
爬取地址: http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html
实现对大学排名的信息的爬取
查看该HTML页面发现, 多有的排名信息都是<tbody>下的子节点
该子节点下的每一个<tr>就是一个排名信息
由于在find_all()的过程中可能出现查找的不是一个标签, 所以需要一个判断是否为标签的判断
具体实例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import requests from bs4 import BeautifulSoup import bs4 def getHTMLText(url): try : r = requests.get(url, timeout = 30 ) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except : return "" def fillUnivList(ulist, html): soup = BeautifulSoup(html, "html.parser" ) for tr in soup.find( 'tbody' ).children: if isinstance (tr, bs4.element.Tag): tds = tr( 'td' ) ulist.append([tds[ 0 ].string, tds[ 1 ].string, tds[ 2 ].string]) def printUnivList(ulist, num): tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}" print (tplt. format ( "排名" , "学校名称" , "总分" , chr ( 12288 ))) for i in range (num): u = ulist[i] print (tplt. format (u[ 0 ],u[ 1 ],u[ 2 ], chr ( 12288 ))) def main(): uinfo = [] url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' html = getHTMLText(url) fillUnivList(uinfo, html) printUnivList(uinfo, 20 ) # 20 univs main() |
实例二: 爬取PAT乙类的试题列表
具体代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = 'weihuchao' import requests from bs4 import BeautifulSoup import bs4 def getPAT(url): try : r = requests.get(url, timeout = 30 ) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except : print ( "获取PAT失败" ) def getUrlList(ulist, content): soup = BeautifulSoup(content, "html.parser" ) for tr in soup.find( "table" ).children: if isinstance (tr, bs4.element.Tag): if tr.name = = "tr" : tds = tr( 'td' ) href = "https://www.patest.cn" name = "" seq = tds[ 0 ].string try : href + = tds[ 1 ].contents[ 0 ].attrs[ 'href' ] name + = tds[ 1 ].string except : pass ulist.append([seq, name, href]) def printUrlList(ulist): tplt = "{0:^2}\t{1:{3}^30}\t{2:^50}" print (tplt. format ( "编号" , "试题名称" , "地址" , chr ( 12288 ))) for i in ulist: print (tplt. format (i[ 0 ], i[ 1 ], i[ 2 ], chr ( 12288 ))) def main(): ulist = [] url = "https://www.patest.cn/contests/pat-b-practise" content = getPAT(url) getUrlList(ulist, content) printUrlList(ulist) if __name__ = = "__main__" : main() |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?