解析库beautifulsoup

[复制链接]
发表于 2022-9-24 21:20:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
目录

一、介绍

Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup 3 目前已经停止开发,官网推荐在现在的项目中使用Beautiful Soup 4, 移植到BS4
  1. 1、安装 Beautiful Soup
  2. pip3 install beautifulsoup4
  3. 基本使用
  4. from bs4 import BeautifulSoup  # 导入BeautifulSoup
  5. # html.parser内置标准库,不需要安装第三方模块,速度慢
  6. soup=BeautifulSoup(res.text,'html.parser')  实例化得到对象
  7. # 安装第三方库解析器
  8. pip3 install lxml
  9. soup=BeautifulSoup(res.text,'lxml')  实例化得到对象
  10. [中文文档 https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html]()
复制代码
  1. 2、bs4的使用
  2. 文档模板
  3. html_doc = """
  4. <html><head><title>The Dormouse's story</title></head>
  5. <body>
  6. <p id="my_p" >hello<b id="bbb" >The Dormouse's story</b>
  7. </p>
  8. <p >Once upon a time there were three little sisters; and their names were
  9. <a target="_blank" href="http://example.com/elsie"  id="link1">Elsie</a>
  10. <a target="_blank" href="http://example.com/lacie"  id="link2">Lacie</a> and
  11. <a target="_blank" href="http://example.com/tillie"  id="link3">Tillie</a>;
  12. and they lived at the bottom of a well.</p>
  13. <p >...</p>
  14. import requests
  15. from bs4 import BeautifulSoup
  16. soup=BeautifulSoup(html_doc,'lxml')        # 文档字符串内容丢进去解析,第二个参数选择解析器
  17. soup=BeautifulSoup(open('a.html'),'lxml')  # 如果是一个文件,要open才能解析
  18. print(soup.prettify())                     # 美化文档
复制代码
二、遍历文档树
  1. 遍历文档树:即直接通过标签名字选择,特点是选择速度快,但如果存在多个相同的标签则只返回第一个
  2. 1、用法
  3. head=soup.head
  4. print(head)
  5. 2、获取标签的名称
  6. head=soup.head
  7. print(head.name)
  8. 3、获取标签的属性(重点)
  9. p=soup.p        # 直接找p标签,跟p=soup.find('p')等价,速度慢一点
  10. p=soup.body.p   # 遍历是从根上找,速度更快
  11. print(p.attrs)  # attrs拿出标签所有属性以字典形式,如{'id':'my_p', 'class':['title]},其中class属性可能有多个,即便有一个也放到列表中
  12. # 支持三种方式取出属性中class的值,取出来是个列表
  13. print(p.attrs.get('class'))  
  14. print(p['class'])
  15. print(p.get('class'))
  16. 4、获取标签的内容
  17. p=soup.body.p
  18. print(p.text)           # text会取该标签以及它下的子孙标签的文本内容,拼到一起
  19. print(p.content)        # 获取标签的二进制内容
  20. print(p.string)         # p标签自己内部有文本,则取到,否则为None;这个文本不能是子孙标签里的文本
  21. print(p.strings)        # 怕p标签下的文本太多,把所有内容放到生成器里
  22. print(list(p.strings))  # list遍历生成器,取出p标签下所有内容
  23. 5、嵌套选择(重点)
  24. a=soup.body.a
  25. print(a.get('id'))
  26. 6、子节点、子孙节点(不用)
  27. print(soup.p.contents)       # p下所有子节点(包含了文本内容)
  28. print(soup.p.children)       # 得到一个迭代器,包含p下所有子节点
  29. print(list(soup.p.children)) # list遍历迭代器,取出p标签下所有子孙节点
  30. 7、父节点、祖先节点(不用)
  31. print(soup.a.parent)         # 获取a标签的父节点(只有一个)
  32. print(soup.a.parents)        # 得到一个生成器,包含a标签所有的祖先节点
  33. print(list(soup.a.parents))  # list遍历,取出a标签所有最先节点
  34. 8、兄弟节点(不用)
  35. print(soup.a.next_sibling)             # 紧邻的下一个兄弟
  36. print(soup.a.previous_sibling)         # 紧邻的上一个兄弟
  37. print(list(soup.a.next_siblings))      #下面的兄弟们=>生成器对象
  38. print(list(soup.a.previous_siblings))  #上面的兄弟们=>生成器对象
  39. # 重点:取标签名,取属性值,嵌套选择
复制代码
三、搜索文档树(过滤)
  1. 1、两种主要搜索方式
  2. find()      # 只返回找到的第一个
  3. find_all()  # 返回找到的所有
  4. find_all()的两个参数
  5. # limit(限制查找的条数)
  6. # 有name的标签,只要第一条,相当于find,唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果
  7. # find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None
  8. res=soup.find_all(name=True,limit=1)  
  9. print(res)
  10. # recursive(recursive默认True,递归查找,找子子孙孙),不用递归查找速度快点
  11. res=soup.body.find_all(name='b',recursive=False)  # 从body往下找,不递归,找不到b标签
  12. res=soup.body.find_all(name='b',recursive=True)   # 递归查找可以找到b标签
  13. res=soup.body.find_all(name='p',recursive=False)  # 从body往下找,不递归,可以找到p标
  14. print(res)
复制代码
  1. 2、五种过滤器:字符串、正则表达式、列表、True、方法
  2. 2.1、字符串过滤,,过滤条件name/id/attrs/text(文档内容),过滤内容是正则表达式
  3. res=soup.find_all(text='The Dormouse's story')       # 按文档内容找标签
  4. res=soup.find(name='a')                              # 按标签名字查找
  5. res=soup.find(id='my_p')                             # 按id查找
  6. res=soup.find(class_='story')                        # 按属性查找,class属性关键字冲突,要用class_
  7. res=soup.find(href='http://example.com/elsie')       # 按属性查找
  8. res=soup.find(attrs={'id':'my_p'})                   # attrs是所有属性,按照属性的key:val查找
  9. res=soup.find(attrs={'class':'story'})
  10. print(res)
  11. # 过滤条件是and关系,可以soup.find(name='a', id='my_p')
  12. 2.2、正则表达式,过滤条件name/id/attrs/text,过滤内容是正则表达式
  13. import re
  14. re_b=re.compile('^b')  # 预编译正则表达式
  15. res=soup.find(name=re_b)                  # 查找标签名字是b开头的,返回一个
  16. res=soup.find_all(name=re_b)              # 查找标签名字是b开头的所有标签
  17. res=soup.find_all(id=re.compile('^l'))    # 查找id是l开头的所有的标签
  18. print(res)
  19. 2.3、列表,过滤条件name/id/attrs/text,过滤内容是列表,用来查找所有
  20. res=soup.find_all(name=['body','b'])          # 查找名字是body和b的标签
  21. res=soup.find_all(class_=['sister','title'])  # 查找class属性是'sister','title'的标签
  22. print(res)
  23. 2.4、布尔,过滤条件name/id/attrs,过滤内容是Ture/False,用来查所有
  24. res=soup.find_all(id=True)    # 查找所有带id的标签
  25. res=soup.find_all(id=False)   # 查找所有不带id的标签
  26. res=soup.find_all(href=True)  # 查找所有有href属性的标签,就把链接全部拿到了
  27. print(res)
  28. 2.5、方法(了解) 自定义过滤内容
  29. # 定义一个方法传入tag,返回有class属性没有id的标签
  30. def has_class_but_no_id(tag):
  31.         return tag.has_attr('class') and not tag.has_attr('id')
  32. print(soup.find_all(has_class_but_no_id))
复制代码
  1. 3、支持css选择器,不用find方法,而是用select方法;找出来的都放列表,即使一个也放列表
  2. ret=soup.select('#my_p')                 # 查找id为my_p的标签
  3. ret=soup.select('body p')                # 查找body下的子子孙孙所有的p标签
  4. ret=soup.select('body>p')                # 只查找body下的儿子p标签,只到儿子节点
  5. ret=soup.select('body>p')[0].text
  6. ret=soup.select('body>p')[0].get_text()  # 两种方式都可以取出文本内容
  7. print(ret)
  8. CSS选择器参考[https://www.w3school.com.cn/cssref/css_selectors.asp]()
复制代码
四、修改文档树
  1. 不仅可以修改name、id、class,还可以往html页面插入标签,插入内容                  
  2. 应用:有些java软件配置文件是xml格式的,可以用bs4来操作修改
  3. 目前软件的配置文件,主要是一下几种
  4. # ini: 用configparser模块操作
  5. # conf
  6. # xml: 用bs4模块操作
  7. # yaml格式
复制代码
五、总结
  1. 1、推荐使用lxml解析库
  2. 2、讲了三种选择器:标签选择器,find与find_all,css选择器
  3.     1、标签选择器筛选功能弱,但是速度快
  4.     2、建议使用find,find_all查询匹配单个结果或者多个结果
  5.     3、如果对css选择器非常熟悉建议使用select
  6. 3、记住常用的获取属性attrs和文本值get_text()的方法
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表