目录
使用requests模块爬取网页数据时,获取到的是html(xml)内容,比较复杂,不容易获取到想要的数据。而BeautifulSoup4就是用于对html,xml进行解析(修改)。
安装:
pip install beautifulsoup4
基本语法:
BeautifulSoup('要解析的字符串', '解析方式')
Beautifulsoup4 - 刘清政 - 博客园 (cnblogs.com)
下表列出了主要的解析器,以及它们的优缺点,官网推荐使用lxml作为解析器,因为效率更高。在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib,因为那些Python版本的标准库中内置的HTML解析方法不够稳定。
| 解析器 | 使用方法 | 优势 | 劣势 |
|---|---|---|---|
| Python标准库 | BeautifulSoup(markup, "html.parser") | Python的内置标准库 执行速度适中 文档容错能力强 | Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 |
| lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快 文档容错能力强 | 需要安装C语言库 |
| lxml XML 解析器 | BeautifulSoup(markup, ["lxml", "xml"]) BeautifulSoup(markup, "xml") | 速度快 唯一支持XML的解析器 | 需要安装C语言库 |
| html5lib | BeautifulSoup(markup, "html5lib") | 最好的容错性 以浏览器的方式解析文档 生成HTML5格式的文档 | 速度慢 不依赖外部扩展 |
文档容错能力:可以不是标准的html,缺一些标签,也可以解析
遍历文档树:即直接通过标签名字选择,特点是选择速度快,但如果存在多个相同的标签则只返回第一个。
获取html内容:
- import requests
- res = requests.get('https://www.cnblogs.com/')
- html_doc = res.text
BeautifulSoup4使用:
- from bs4 import BeautifulSoup
- soup = BeautifulSoup(html_doc, 'html.parser')
- # 美化html,自动缩进和补全html表标签
- # print(soup.prettify())
1.获取标签
- # div标签
- res = soup.div
- # div标签下的ul标签
- res = soup.div.ul
2.取标签的名称(可以说毫无作用)
- # div标签名称,即'div'
- res = soup.div # 'div'
3.获取标签的属性(两种方式)
- res = soup.div.ul
- # ul标签的class属性
- print(res['class'])
- res = soup.div.ul
- # ul标签的id属性
- print(res.attrs['id'])
4.获取标签的内容
- res = soup.div.ul
- print(res.text) # text 把所有子标签的文本内容拼到一起
- print(res.string) # string 没有子标签才能获取文本,有子标签返回None
- print(list(res.strings)) # generator strings:把子标签的文本内容放到生成器中
5.子节点、子孙节点
- # div.ul标签下的所有子节点
- res = soup.div.ul.contents
- print(res)
- print(soup.div.ul.children) # 得到一个迭代器,包含所有子节点
- # div.ul标签下的所有子节点和孙节点
- print(list(soup.div.ul.descendants))
6.父节点、祖先节点
- print(soup.div.parent) # 获取a标签的父节点
- print(list(soup.div.parents)) # 找到a标签所有的祖先节点,父亲、父亲的父亲...
7.兄弟节点(可能存在换行符,标签外换行算一个标签)
- print(soup.div.next_sibling) # 下一个兄弟
- print(soup.div.previous_sibling) # 上一个兄弟
-
- print(list(soup.div.next_siblings)) # 下面的兄弟们=>生成器对象
- print(list(soup.div.previous_siblings)) # 上面的兄弟们=>生成器对象
获取html内容:
- import requests
- res = requests.get('https://www.cnblogs.com/')
- html_doc = res.text
BeautifulSoup4使用:
- from bs4 import BeautifulSoup
- soup = BeautifulSoup(html_doc, 'html.parser')
两个方法:
1.字符串搜索
- # 查找div标签中class属性为post-item-text
- res = soup.find(name='div', class_='post-item-text')
- print(res)
- # 查找标签id属性为nav_dropdown_menu的标签
- res = soup.find(id='nav_dropdown_menu')
- print(res)
- # 有符合的文本返回文本内容,没有返回None
- res = soup.find(text="发现")
- print(res)
2.正则表达式
- import re
- # 查找标签id属性为'nav'开头的的标签
- res = soup.find(id=re.compile('^nav'))
- print(res)
3.列表
- # 查找div标签、p标签
- res = soup.find(name=['div', 'p'])
- print(res)
4.布尔值
- # 查找id属性有值的标签
- res = soup.find(id=True)
- print(res)
5.方法
- # 查找所有有class属性但没有id属性的表情
- def has_class_but_no_id(tag):
- return tag.has_attr('class') and not tag.has_attr('id')
-
- print(soup.find_all(name=has_class_but_no_id))
find_all的其它属性
find()其实就是find_all(),只不过取了第一条。
find_all(limit=1, recursive=False, attrs={'class':True})
还可以使用css选择器
- # res = soup.select('.abc')
- # res = soup.select('#abc')
- res = soup.select('#id1')[0]['class']
- print(res)