前端盲一枚 近期对爬虫产生了兴趣 嘿嘿 学习这份美丽的汤 并做个笔记
前言
-
官方宣布Beautiful Soup4之前的版本不再维护,所以不推荐去学习
Beautiful Soup 3是上一个发布版本,目前已经停止维护
只要一个小变动就能让大部分的Beautiful Soup 3代码使用Beautiful Soup 4的库和方法—-修改 BeautifulSoup 对象的引入方式
from BeautifulSoup import BeautifulSoup
修改为:
from bs4 import BeautifulSoup
-
如果代码抛出
ImportError
异常No module named BeautifulSoup
,原因可能是尝试执行Beautiful Soup 3
,但环境中只安装了Beautiful Soup 4
库 -
如果代码抛出
ImportError
异常No module named bs4
,原因可能是尝试运行Beautiful Soup 4
的代码,但环境中只安装了Beautiful Soup 3
.
安装
BeautifulSoup 一个灵活又方便的网页解析库,处理高效,支持多种解析器。
你也想使用吗?那就开始安装吧!!!
- 使用
pip
安装bs4
- 打开命令行
- 输入
pip install bs4
- 可以用
pip list
查看有没有安装成功
解析器
BeautifulSoup不仅支持Python标准库中的HTML解析器,还支持一些第三方的解析器
- 我使用的是lxml
解析器 | 使用方法 |
---|---|
Python标准库 | BeautifulSoup(markup, “html.parser”) |
lxml HTML 解析器 | BeautifulSoup(markup, “lxml”) |
lxml XML 解析器 | BeautifulSoup(markup, [“lxml-xml”]) 或者 BeautifulSoup(markup, “xml”) |
html5lib | BeautifulSoup(markup, “html5lib”) |
使用lxml解析器
- 导入模块
from bs4 import BeautifulSoup soup = BeautifulSoup(xxx.html,"lxml")
节点选择器
使用<标签>选择元素
- 选择元素用法格式
soup.tag(对象.标签名)
- 返回节点元素
例子:
soup.title
<title> XXX </title> 类型为:tag类对象
`soup.a`
`<a XXXX >XXX</a> `
提取信息用法
获取标签名
soup.tag.name
返回一个字符串
例子:
soup.a.name
值为“a”
获取属性
soup.tag.attrs
返回一个字典
例子:
soup.a.attrs
{'xx':'xxx','class':['xxx'],...}
获取内容
soup.tag.string
返回一个字符串
例子:
soup.a.string
"xxxxx"
节点嵌套选择
获取嵌套标签中的内容
soup.tag.tag
返回节点元素,类型为:tag类对象
例子:
嵌套样式
`<head><title>The Docmouse's stery</title></head>`
获取title
`soup.head.title`
获取title内容
`soup.head.title.string`
节点选择器关联选择
子节点
soup.tag.contents
返回一个列表
or
soup.tag.children
返回一个可迭代对象(生成器)
例子:
soup.p.contents
返回一个<p>区域中的所有子标签列表,其中包含<p>本身标签内容,也就是说把<p>中的所有内容选择出来放入列表中,值得注意的是:<p>子标签的子标签不会被选择
soup.p.children
返回一个可迭代对象(生成器),需要使用循环获取生成器中的内容。
父节点
soup.tag.parent
返回节点元素
例子:
soup.a.parent
返回<a>的父节点
祖先节点
soup.tag.parents
返回一个包含所有祖父的可迭代对象(生成器)
例子:
soup.a.parents
返回<a>的祖先节点的迭代器,遍历迭代器将得到<a>的父节点、<a>的父节点的父节点直到迭代结束
兄弟节点
- 获取下一个兄弟节点
soup.tag.next_sibling
返回节点元素
例子:
soup.a.next_sibling
获取下一个节点
- 获取后面所有兄弟节点
soup.a.tag.next_siblings
返回一个包含 < a > 的所有兄弟节点的可迭代对象(生成器)
- 获取上一个兄弟节点
soup.tag.previous_sibling
返回节点元素
用法同soup.a.next_sibling
- 获取前面所有的兄弟节点
soup.tag.previous_siblings
用法同soup.a.tag.next_siblings
CSS选择器
id选择器,需要使用
#
来定位元素
soup.select("#list-1")
类选择器,需要使用
.
来定位元素
soup.select(".body")
标签选择器,需要使用标签名来定位元素
soup.select("li")
混合使用 结合实际使用
例子:
可以先用类选择器>然后使用id选择器>最后使用标签
soup.select(".body #list-1 li")
- 小技巧:使用父节点限制选择class的范围,达到精准定位的效果
基本使用
- 使用BeautifulSoup中的select()方法结合CSS选择器语法即可定位
soup = BeautifulSoup(xxx.html,"lxml")
soup.select()
进阶用法
- 嵌套选择
例子:获取ul下的所有<li>标签
soup = BeautifulSoup(xxx.html,"lxml")
for ul in soup.select("ul"):
for li in ul.select("li"):
- 属性获取
例子:获取所有<li>标签中的class属性值
soup = BeautifulSoup(xxx.html,"lxml")
for ul in soup.select("ul"):
for li in ul.select("li"):
print(li.attrs['class'])
- 文本获取
例子:获取所有<li>标签中的文本
soup = BeautifulSoup(xxx.html,"lxml")
for ul in soup.select("ul"):
for li in ul.select("li"):
print(li.string)
方法选择器
方法表
方法 | 作用 |
---|---|
find_all() | 查找所有符合条件的元素 |
find_all_previous() | 往前查找所有符合条件的节点(包括子孙节点) |
find_all_next() | 往后查找所有符合条件的节点(包括子孙节点) |
find() | 查找第一个符合条件的元素 |
find_previous() | 往前查找第一个符合条件的元素 |
find_next() | 往后查找第一个符合条件的元素 |
find_parents() | 查找祖先节点 |
find_parent() | 查找父节点 |
find_next_siblings() | 往后查找所有符合条件的兄弟节点 |
find_next_sibling() | 往后查找符合条件的兄弟节点 |
find_previous_siblings() | 往前查找所有符合条件的兄弟节点 |
find_previous_sibling() | 往前查找符合条件的兄弟节点 |
过滤器
过滤器可以被用在tag的name中,节点的属性中,字符串中或他们的混合中.
常用的过滤器
- 字符串
- 正则表达式
- 列表
- CSS选择器
原型
find_all( name , attrs , recursive , string ,limit, **kwargs )
返回值是一个列表
find( name , attrs , recursive , string , **kwargs )
找不到目标时返回None
-
name 参数
name 参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉.
例子:
soup.find_all("title")
[<title>The Dormouse's story</title>]
- attrs参数
以字典类型传入
soup.find_all(attrs={'id':'link'})
- kwargs参数
soup.find_all(id='link')
soup.find_all(class_='element')
需要注意的是在Python中class是关键字,所以在匹配时必须在后面加上下划线
- text参数
soup.find_all(text='link')
- limit参数
限制返回结果
find()方法没有此参数
soup.find_all('a',limit=2)
得到的结果就是返回两个<a>标签
- recursive参数
值为布尔值,默认为True,是否获取子孙节点
soup.find_all('title',recursive=False)
- string 参数
搜文档中的字符串内容
soup.find_all(string="Elsie")
- True
可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点
for tag in soup.find_all(True):
print(tag.name)
复制Beautiful Soup对象
- 使用
copy
中的copy()
方法可以复制Beautiful Soup对象
例子:
import copy
p_copy = copy.copy(soup.p)
print p_copy
- 这会在把复制出来保存在新地址中
soupStrainer类
-
只会解析在 SoupStrainer 中定义过的文档.
-
导入模块
from bs4 import SoupStrainer
- 方法参数
only_tags = SoupStrainer(name,attrs,recursive,string,**kwargs)
from bs4 import SoupStrainer
only_a_tags = SoupStrainer("a") #只解析a标签
only_tags_with_id_link2 = SoupStrainer(id="link2")#解析标签id值为link2的的标签
def is_short_string(string):
return len(string) < 10
only_short_strings = SoupStrainer(string=is_short_string)
常见错误
- 解析错误
TMLParser.HTMLParseError: malformed start tag
HTMLParser.HTMLParseError: bad end tag
-
解析异常
找不到指定的tag,而这个tag确实存在 -
以上的解决方案
安装lxml解析器即可解决