Beautiful Soup库是解析、遍历、维护“标签树”的功能库。Beautiful Soup库也叫beautifulsoup4 或 bs4。但主要还是用BeautifulSoup类,约定引用方式如下:
from bs4 import BeautifulSoup
import bs4
Beautiful Soup库解析器
soup = BeautifulSoup('<html>data</html>','html.parser')
bs4的HTML解析器 BeautifulSoup(mk,'html.parser') 安装bs4库
lxml的HTML解析器 BeautifulSoup(mk,'lxml') pip install lxml
lxml的XML解析器 BeautifulSoup(mk,'xml') pip install lxml
html5lib解析器 BeautifulSoup(mk,'html5lib') pip install html5lib
BeautifulSoup类的基本元素
- 任何存在于HTML语法中的标签都可以用soup.<tag>访问获得。当HTML文档中存在多个相同<tag>对应内容时,soup.<tag>返回第一个。
- 每个<tag>都有自己的名字,通过<tag>.name获取,字符串类型。
- 一个<tag>可以有0或多个属性,字典类型.
- NavigableString可以跨越多个层次
举例:假设我们获得的某个网页的文本信息如下
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup('<html>data</html>','html.parser')
>>> soup.title
This is d pyton demo page
>>> soup.a.name
'a'
>>> tag = soup.a
>>> tag.attrs
{'id':'link1','class':['py1'], 'href': 'http://....'}
>>>tag.string
'Basic Python'
HTML内容遍历方法
下行遍历常见属性:
.contents 子节点的列表,将<tag>所有儿子节点存入列表
.children 子节点的迭代类型,与.contents类似,用于循环遍历儿子节点
.descendants 子孙节点的迭代类型,包含所有子孙节点,用于循环遍历
# 遍历儿子节点
for child in soup.body.children:
print(child)
# 遍历子孙节点
for child in soup.body.descendants:
print(child)
上行遍历常见属性:
.parent 节点的父亲标签
.parents 节点先辈标签的迭代类型,用于循环遍历先辈节点
平行遍历常见属性:平行遍历发生在同一个父节点下的各节点间。
.next_sibling 返回按照HTML文本顺序的下一个平行节点标签
.previous_sibling 返回按照HTML文本顺序的上一个平行节点标签
.next_siblings 迭代类型,返回按照HTML文本顺序的后续所有平行节点标签
.previous_siblings 迭代类型,返回按照HTML文本顺序的前续所有平行节点标签
规范输出
.prettify()方法可以使得HTML内容显示更加规范。在每个把标签的结尾田间一个换行符'\n' 。.prettify()可用于标签,方法:<tag>.prettify()。
print (soup.prettifu())
print (soup.a.prettifu())
编码格式
bs4库将任何HTML输入都变成utf‐8编码,因此我们在解析时无障碍。
>>>soup = BeatifulSoup("<p>中文<\p>",'html.parser')
>>>soup.p.string
'中文'
HTML信息标记方式
超文本 包括声音、图像、视频。对于这类信息的标记便于我们更好的表示。标记后的信息能够增强信息维度,更加有利于程序的理解和存储。
信息标记方式可以包括三种: XML、JSON、YAML
XML Internet上的信息交互与传递
JSON 移动应用云端和节点的信息通信,无注释
YAML 各类系统的配置文件,有注释易读
XML(eXtensible Markup Language)
# XML标签 <name> … </name>
<img src=“china.jpg” size=“10”> … </img>
# 空元素的缩写形式 <name />
<img src=“china.jpg” size=“10” />
# 注释书写形式 <!‐‐ ‐‐>
<!‐‐ This is a comment, very useful ‐‐>
示例:
<person>
<firstName>公众号</firstName>
<lastName>花重锦城</lastName>
<address>
<streetAddr>重庆市北碚区</streetAddr>
<city>重庆市</city>
<zipcode> 033478 </zipcode>
</address>
<prof>Computer System</prof><prof>Security</prof>
</person>
JSON(JavsScript Object Notation)
有类型的键值对 key : value
#有类型的键值对 key : value
“name” : “公众号花重锦城”
# 其中:“”表示类型,name表示key,‘公众号花重锦城’表示值valu
当value 有多个值时用,号分隔。例如
“name” :['公众号 ', '花重锦城']
键值对嵌套形式
“name”: {
“FirstName” : “公众号”,
“lastName” : “花重锦城”
}
示例:
{
“firstName” : “公众号” ,
“lastName” : “花重锦城” ,
“address” : {
“streetAddr” : “重庆市北碚区” ,
“city” : “重庆市” ,
“zipcode” : “033478 ”
} ,
“prof” : [ “Computer System” , “Security” ]
}
YAML (YAML Ain’t Markup Language)
无类型键值对 key:value
name : “公众号花重锦城”
# 其中:name表示key,‘公众号花重锦城’表示值valu
通过缩进表达所属关系,通过‐ 表达并列关系
# 注意缩进
name :
firstName : 公众号
lastName : 花重锦城
# 并列关系
name :
‐公众号
‐花重锦城
示例:
firstName : 公众号
lastName : 花重锦城
address :
streetAddr : 重庆市北碚区
city : 重庆市
zipcode : 033478
prof :
‐Computer System
‐Security
信息提取方式
信息的提取也是对网页内容的解析,根据网页的结构和自己需要提取内容的关键标识符号来进行信息的检索,最终得到数据。在网页的解析过程中,我们除了要明确网页信息的表示方式之外,还要利用正则表达式定位关键位置实现信息提取。基于bs4库的HTML内容查找:
>>> soup.findall('a')
>>> soup.findall(['a','b']
# 注意
<tag>(..) 等价于 <tag>.find_all(..)
soup(..) 等价于 soup.find_all(..)
实例,中国大学排名爬虫
提示: 中文字符的空格填充 chr(12288)
import requests
import bs4
from bs4 import BeautifulSoup
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.find_all('td')
ulist.append([tds[0].string,tds[1].string,tds[3].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, 5)
if __name__ == "__main__":
main()
'''out
排名 学校名称 总分
1 清华大学 95.9
2 北京大学 82.6
3 浙江大学 80
4 上海交通大学 78.8
5 复旦大学 70.9
'''
扫描二维码学习了解更多关于python、机器学习、Linux系统以及开源软件的知识