第4章 解析库的使用---Beautiful soup

Beautiful Soup支持的解析器包括:HTML、XML和html5lib,但我们推荐使用lxml解析器,因为其解析器有解析HTML和XML的功能,速度快,容器能力强。

from bs4 import BeautifulSoup
# 使用时,将第二个参数设置为lxml即可;html是HTML字符串
soup=BeautifulSoup(html,'lxml')
#prettify()方法将要解析的字符串以标准的缩进格式输出
print(soup.prettify())
# 选取title节点,再调用string属性得到里面文本。
print(soup.title.string)

 

  1. 节点选择器

可直接调用节点的名称就可以选择节点元素,再调用string属性就可以得到节点内的文本。

  • 选择元素:
# 选择元素,输出title节点加里面的文字内容,返回值类型是bs4.element.Tag类型
print(soup.title)
# Tag类型具有很多属性,如:soup.title.string
# 该返回结果也是节点加其内部的所有内容
print(soup.head)
# 如下,存在多个p节点时,只会返回第一个匹配的p节点
print(soup.p)
  • 提取信息
# 获取节点的名称(貌似感觉这个多此一举,既然选取了该节点,为何还要获取当前选取的是啥节点?
# 定位吗?)
print(soup.title.name)# 结果是:title

# 获取属性
print(soup.p.attrs)# 以字典形式返回,节点p的所有属性和属性值组成一个字典
print(soup.p.attrs['name'])# 通过中括号加属性名,获取name的键值

# 更为简单的方式如下:不用写attrs,直接在节点元素后面加中括号,传入属性名即可
print(soup.p['name'])
print(soup.p['class'])
# 请注意,如若p节点下含有多个class属性,将会返回的是列表

# 获取内容,获取节点元素包含的文本内容,比如获取第一个p节点的文本
print(soup.p.string)
# 如若存在多个p,将只会返回第一个
  • 嵌套选择
# 比如:获取了head节点元素,还可以继续调用head来选取其内部的head节点元素
print(soup.head.title)
print(type(soup.head.title)) # bs4.element.Tag类型
print(soup.head.title.string)
# 再前者基础上继续选择string属性
  • 关联选择
选中某一节点元素,以其为基准再选择它的子节点、父节点、兄弟节点等
# 返回直接子节点的列表
print(soup.p.contents)
# 还可以通过children属性得到相应的结果,返回结果是生成器类型
print(soup.p.children)
# 所有子孙节点,调用descendants属性,返回结果是生成器类型,可通过for循环遍历输出
print(soup.p.descendants)
for i,child in(soup.p.descendants):
    print(i,child)
# 直接唯一父节点
print(soup.a.parent)
# 获取所有的祖先节点,加了一个s
print(soup.a.parents)

# 获取同级节点(也就是兄弟节点)
print('Next Sibling',soup.a.next_sibling) # 下一个兄弟节点
print('Prev Sibling',soup.a.previous_siblings) # 上一个兄弟节点
print('Next Siblings',list(enumerate(soup.a.next_sibling))) # 所有后面的兄弟节点
print('Prev Siblings',list(enumerate(soup.a.previous_siblings))) # 所有前面的兄弟节点

# 提取信息
print(soup.a.next_sibling) # 下一个兄弟节点
print(soup.a.next_sibling.string) # 下一个兄弟节点的文本信息
print(list(soup.a.parents)[0]) # a的直接父母
print(list(soup.a.parents)[0].attrs['class']) # 满足属性为class的a的直接祖先

2、方法选择器

  • find_all() 
查询所有符合条件的节点,API为:find_all(name, attrs, recursive, text, **kwargs)
# name
print(soup.find_all(name='ul'))
for ul in soup.find_all(name='ul'):
    print(ul.find_all(name='li'))#返回列表类型
    for li in ul.find_all(name='li'):
        print(li.string)

# attrs
# 除了根据节点查询外,还可以传入属性来查询
print(soup.find_all(attrs={'id':'list-1'}))
print(soup.find_all(attrs={'name':'elements'}))
# 传入的attrs参数类型是字典类型,如:{'id':'list-1'}.得到的结果是列表形式的所有符合条件结果
# 还可以不使用attrs
print(soup.find_all(id='list-1'))
print(soup.find_all(class_='element'))

# text
# 可匹配节点的文本,可传入字符串或者正则表达式
print(soup.find_all(text=re.compile('link'))) #传入正则表达式对象,结果返回所有匹配正则的文本列表
  • find()
# find返回第一个匹配到的单个元素、find_all返回的是所有匹配元素的列表
print(soup.find(name='ul'))
# find_parents()返回所有祖先节点、去掉s是直接父节点
# find_next_siblings()返回后面所有兄弟的节点,去掉s是返回第一个
# find_previous_siblings()前面所有兄弟
# fand_all_previous()返回前面所有符合条件的节点,同find_all_next()
# find_next()节点后第一个符合条件的节点、find_previous()节点前第一个。

3、CSS选择器

CSS选择器,使用时,调用select()方法,传入相应的CSS选择器
print(soup.select('.panel .panel-heading')) #
print(soup.select('ul li')) #选择所有ul节点下的li节点,返回类型依旧是Tag类型
print(soup.select('#list-2 .element'))
  • 嵌套选择
# 嵌套选择,先选择所有ul节点,再遍历每个ul节点,选择其li节点
for ul in soup.select('ul'):
    print(ul.select('li'))
  • 获取属性
# 获取属性,节点类型依旧是Tag类型
for ul in soup.select('ul'):
    print(ul['id'])
    print(ul.attrs['id']) # 这俩行输出的结果是一样的
  • 获取文本
# 获取文本,可用string属性,也可以使用get_text()
for li in soup.select('li'):
    print('Get Text:', li.get_text())
    print('String:', li.string)# 这俩行输出的结果是一样的

总结:

# 建议:
# 推荐使用lxml解析库,必要时使用html.parser
# 节点选择筛选功能弱但速度快
# 建议使用find()或者find_all()查询匹配单个结果或者多个结果
# 熟悉CSS选择器,可以使用select()方法选择

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值