BeautifulSoup是用来从HTML、XML文档中提取数据的一个python库,安装如下:
pip install beautifulsoup4
它支持多种解析器,包括python标准库、lxml HTML解析器、lxml XML解析器、html5lib等。结合稳定性和速度,这里推荐使用lxml HTML解析器。安装:
pip install lxml
如果lxml不能正确解析内容,这是可以使用html5lib。安装:
pip install html5lib
beautifulsoup的使用流程一般包括:1.导入库 2.实例化对象 3.调用对象
在实例化对象的时候要传入两个参数,一个是待解析的html或xml字符串(markup),另一个是选择的解析器(features)。如果未指定解析器,会调用默认解析器。
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str, 'lxml')
要定位到指定的地方提取想要的数据,就需要借助选择器进行定位。beautifulsoup有三种选择器:节点选择器、方法选择器、css选择器。
节点选择器的使用
选取标签:节点选择器是通过HTML标签进行定位的,使用方法是实例化soup对象后直接加.tag,tag就是html标签名。
import requests from bs4 import BeautifulSoup url = 'https://www.baidu.com' response = requests.get(url=url) response.encoding = response.apparent_encoding soup = BeautifulSoup(response.text, 'lxml') print(soup.a)# out:
这样选取的缺点是:如果有多个相同标签,只会提取第一个标签,其他的被忽略。
获取标签信息:在获取到的标签的基础上,还可以进一步获取标签名、属性、值
print(soup.a) print(soup.a.name) print(soup.a.attrs) print(soup.a.string)# out:
新闻
a
{'href': 'http://news.baidu.com', 'name': 'tj_trnews', 'class': ['mnav']}
新闻
嵌套选择:如果一个标签里还包含一个子标签,我们还可以通过嵌套选择的方法取出子标签
print(soup.head.title) print(soup.head.title.string)# out:
百度一下,你就知道
百度一下,你就知道
子标签列举: 有两种方式,包括contents(返回列表)、children(返回可迭代对象)。该方法会把所有子标签取出,这样我们就可以拿到指定位置的子标签。
from bs4 import BeautifulSoup hh = '''''' soup = BeautifulSoup(hh, 'lxml') print(soup.tr.contents) print(soup.tr.children) for index, child in enumerate(soup.tr.children): print(f'({index}):{child}') IP PORT 匿名度 类型 位置 响应速度 录取时间 test# out:
[
IP ,PORT ,匿名度 ,类型 ,位置 ,响应速度 ,录取时间 ]test
(0):IP
(1):PORT
(2):匿名度
(3):类型
(4):位置
(5):响应速度
(6):录取时间 test
父标签列举:.parent会列出标签的父标签,.parents会列出所有的祖先元素并整合在可迭代对象里。
from bs4 import BeautifulSoup hh = '''''' soup = BeautifulSoup(hh, 'lxml') print(soup.div.parent) print(soup.div.parents) for index, parents in enumerate(soup.tr.parents): print(f'({index}):{parents}') IP PORT 匿名度 类型 位置 响应速度 录取时间 test# out:
录取时间
test
(0):
IP
PORT
匿名度
类型
位置
响应速度
录取时间
test
(1):
IP
PORT
匿名度
类型
位置
响应速度
录取时间
test
兄弟节点选取: next_sibling获取下一个兄弟节点,next_siblings获取后续所有兄弟节点,previous_sibling获取前一个兄弟节点,previous_siblings获取前面所有兄弟节点。
from bs4 import BeautifulSoup hh = '''''' soup = BeautifulSoup(hh, 'lxml') print(soup.th.next_sibling) print(soup.th.next_siblings) print(list(soup.th.next_siblings)[1].previous_sibling) print(soup.th.previous_siblings) IP PORT 匿名度 类型 位置 响应速度 录取时间 test# out:
PORT
PORT
CSS选择器的使用
使用CSS选择器,只需要调用select()方法,结合CSS语法即可定位到元素。
在css语法中,我们可以使用类选择器、id选择器、标签选择器、以及混合使用来定位。
from bs4 import BeautifulSoup hh = '''''' soup = BeautifulSoup(hh, 'lxml') print(soup.select('th')) IP PORT 匿名度 类型 位置 响应速度 录取时间 test# out:
[
IP ,PORT ,匿名度 ,类型 ,位置 ,响应速度 ,录取时间 ]test
我们只需传入css同样的定位语法即可 ,返回结果为列表。
获取节点的属性和文本用法与前面的节点选择器相同。
方法选择器的使用
使用方法选择器主要使用其中的find()和findALL()方法,finaALL方法需要传入的参数有name,attrs,text,kwargs。
name为定位条件,可以为标签名如'a',也可以是多个标签名组成的列表,还可以是正则表达式。
from bs4 import BeautifulSoup hh = '''''' soup = BeautifulSoup(hh, 'lxml') print(soup.findAll(name='th')) IP PORT 匿名度 类型 位置 响应速度 录取时间 test# out:
[
IP ,PORT ,匿名度 ,类型 ,位置 ,响应速度 ,录取时间 ]test
attrs为属性,可根据属性定位标签。
from bs4 import BeautifulSoup hh = '''''' soup = BeautifulSoup(hh, 'lxml') print(soup.findAll(attrs={"id":"te"})) IP PORT 匿名度 类型 位置 响应速度 录取时间 test# out:
[
test]
string为文本,可以搜索文本信息,常与其他name或attr混用来获取标签。
from bs4 import BeautifulSoup hh = '''''' soup = BeautifulSoup(hh, 'lxml') print(soup.findAll(name='th', string='匿名度')) IP PORT 匿名度 类型 位置 响应速度 录取时间 test# out:
[
匿名度 ]
kwargs为关键字参数,比attr使用更方便,传入指定关键字参数以定位标签。class与python中的关键字冲突了,所以需要加下划线避免冲突。
from bs4 import BeautifulSoup hh = '''''' soup = BeautifulSoup(hh, 'lxml') print(soup.findAll(class_='te')) IP PORT 匿名度 类型 位置 响应速度 录取时间 test# out:
[
test]
limit为限制参数,限制返回结果的数量
from bs4 import BeautifulSoup hh = '''''' soup = BeautifulSoup(hh, 'lxml') print(soup.findAll(name='th', limit=3)) IP PORT 匿名度 类型 位置 响应速度 录取时间 test# out:
[
IP ,PORT ,匿名度 ]
find方法 :相比于find_all()方法,除了limit参数不能用,其他参数均与find_all()方法相同,不过find方法只会返回一个值,而不是像find_all返回所有值。