一、html文件准备
首先,我们要明确我们需要的数据,并在html中找到它们的位置。
1.帆船名称:11 METER
2.Sailboat Specifications
事实上,还可以获取更多帆船数据,但因为与Sailboat Specifications的过程基本相同,这里省略。
为了方便演示,我把相关部分摘下来:
11 METER - sailboatdata
Skip to content
11 METER
Hull Type:
Fin w/bulb & spade rudder
Rigging Type:
Fractional Sloop
LOA:
33.80 ft / 10.30 m
LWL:
26.90 ft / 8.20 m
S.A. (reported):
450.00 ft² / 41.81 m²
Beam:
8.20 ft / 2.50 m
Displacement:
3,527.00 lb / 1,600 kg
Ballast:
1,598.00 lb / 725 kg
Max Draft:
5.90 ft / 1.80 m
Construction:
FG w/core,Composite
Ballast Type:
Lead
First Built:
1990
# Built:
350
Designer:
Ron Holland & Rolf Gyhlenius
观察结构,它是由一个head和body组成,head中有一些meta、link
二、beautifulsoup基本类型与用法
beautifulsuop,漂亮的汤,它的作用是将一个html文件进行解析,转换成一个树状结构,每个节点是一个Python对象,有四种类型:Tag,NavigableString,BeautifulSoup,comment
首先我们新建文件testBs4.py
0.导包、读取文件、创建bs对象
from bs4 import BeautifulSoup
f = open(r"./11meters.html", "rb") # 以二进制读取,以模拟我们爬取页面response的结果
html = f.read().decode("utf-8") # 解码
#创建beautifulsoup对象
bs= BeautifulSoup(html,"html.paeser") # (待解析的文档,解析器类型)
1.bs4.element.Tag(获取第一次出现的标签及层级下的所有内容 )
print(type(bs.title),bs.title)
print("-"*50)
print(type(bs.meta),bs.meta)
print("-"*50)
print(type(bs.link),bs.link)
print("-"*50)
print(type(bs.head),bs.head)
print("-"*50)
print(type(bs.a),bs.a)
print("-"*50)
# print(type(bs.div),bs.div)
# print("-"*50)
D:\Anaconda3\python.exe C:\Users\和谐号\PycharmProjects\pythonProject\2023-08-22-sailboatData\testBs4.py
11 METER - sailboatdata
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
11 METER - sailboatdata
--------------------------------------------------
Skip to content
--------------------------------------------------
进程已结束,退出代码为 0
可以str()到字符串
2.bs4.element.NavigableString (获取第一次出现的标签里的内容 )
print(type(bs.title.string),bs.title.string)
print("-"*50)
print(type(bs.meta.string),bs.meta.string)
print("-"*50)
print(type(bs.link.string),bs.link.string)
print("-"*50)
print(type(bs.head.string),bs.head.string)
print("-"*50)
print(type(bs.a.string),bs.a.string)
print("-"*50)
# print(type(bs.div),bs.div)
# print("-"*50)
11 METER - sailboatdata -------------------------------------------------- None -------------------------------------------------- None -------------------------------------------------- None -------------------------------------------------- Skip to content --------------------------------------------------
当不存在内容时,就是None,类型也不是bs4.element.NavigableString了,
可以str()到字符串
3.bs4.BeautifulSoup (整个bs对象)
print(type(bs.name),bs.name)
print("-"*50)
print(type(bs.attrs),bs.attrs)
print("-"*50)
print(type(bs),bs)
[document] -------------------------------------------------- {} --------------------------------------------------
11 METER - sailboatdata
......
4.bs4.element.Comment(一种特殊的NavigableString)
当标签里的内容时注释时,再用.string命令,得到的不在是NavigableString,而是comment,同时也不会原封不动地输出注释,而是展示去掉注释符号以后的结果。
(1)对html做如下修改:
print(type(bs.a),bs.a)
print(type(bs.a.string),bs.a.string)
print(type(bs.a.attrs),bs.a.attrs)
Skip to content Skip to content {'class': ['skip-link', 'screen-reader-text'], 'href': '#primary'}
(2)在修改:
print(type(bs.a),bs.a)
print(type(bs.a.string),bs.a.string)
print(type(bs.a.attrs),bs.a.attrs)
Skip to content {'class': ['skip-link', 'screen-reader-text'], 'href': '#primary'}
5..attrs获取标签里的属性值(字典类型,键值对存储)
print(type(str(bs.title.attrs)),str(bs.title.attrs))
print("-"*50)
print(type(bs.meta.attrs),bs.meta.attrs)
print("-"*50)
print(type(bs.link.attrs),bs.link.attrs)
print("-"*50)
print(type(bs.head.attrs),bs.head.attrs)
print("-"*50)
print(type(bs.a.attrs),bs.a.attrs)
print("-"*50)
{} -------------------------------------------------- {'charset': 'UTF-8'} -------------------------------------------------- {'rel': ['profile'], 'href': 'https://gmpg.org/xfn/11'} -------------------------------------------------- {} -------------------------------------------------- {'class': ['skip-link', 'screen-reader-text'], 'href': '#primary'} --------------------------------------------------
当不存在内容时,返回空字典
上述内容只是让我们了解beautifulsoup中有的对象类型,以及它们的特点,真正在使用的时候,还用不上,因为它只能返回它找到的第一项,对我们提取数据用处不大。
三、beautifulsoup遍历(对tag操作)
1..contents属性
print(bs.body)
print("-"*500)
print(type(bs.body.contents))
for item in bs.body.contents:
print(item)
bs.body是tag对象,我们可以把它转为str,然后按行放到一个列表中,有点像readlins()方法
以上代码,主题部分是完全相同的,区别就是contents只有head里面的内容,head标签以及起止符不会出现:
.body:
.body.contents:
2.children
print(bs.body)
print("-"*500)
print(type(bs.body.children))
for item in bs.body.children:
print(item)
与contents相比,似乎只是数据类型的不同,contents得到是list,children得到的是list_iterator
3.其它
5.3 、 .descendants :获取 Tag 的所有子孙节点
5.4 、 .strings :如果 Tag 包含多个字符串,即在子孙节点中有内容,可以用此获取,而后进行遍历
5.5 、 .stripped_strings :与 strings 用法一致,只不过可以去除掉那些多余的空白内容
5.6 、 .parent :获取 Tag 的父节点
5.7 、 .parents :递归得到父辈元素的所有节点,返回一个生成器
5.8 、 .previous_sibling :获取当前 Tag 的上一个节点,属性通常是字符串或空白,真实结果是当前标签
与上一个标签之间的顿号和换行符
5.9 、 .next_sibling :获取当前 Tag 的下一个节点,属性通常是字符串或空白,真是结果是当前标签与下
一个标签之间的顿号与换行符
5.10 、 .previous_siblings :获取当前 Tag 的上面所有的兄弟节点,返回一个生成器
5.11 、 .next_siblings :获取当前 Tag 的下面所有的兄弟节点,返回一个生成器
5.12 、 .previous_element :获取解析过程中上一个被解析的对象 ( 字符串或 tag) ,可能与
previous_sibling 相同,但通常是不一样的
5.13 、 .next_element :获取解析过程中下一个被解析的对象 ( 字符串或 tag) ,可能与 next_sibling 相同,
但通常是不一样的
5.14 、 .previous_elements :返回一个生成器,可以向前访问文档的解析内容
5.15 、 .next_elements :返回一个生成器,可以向后访问文档的解析内容
5.16 、 .has_attr :判断 Tag 是否包含属性
遍历,感觉要对这个得到的html结构很熟悉,然后再用前节点后节点父节点子节点来回调指针,没有下面的搜索好用。
Python爬虫之数据解析——BeautifulSoup亮汤模块(二):搜索(再接上文,2023美赛春季赛帆船数据解析sailboatdata.com)_和谐号hexh的博客-CSDN博客