BeautifulSoup爬取数据常用方法总结
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.
文章目录
- 安装BeautifulSoup
- 几个简单的浏览结构化数据的方法
- 从文档中找到所有的< a>标签的链接
- 在文档中获取所有的文字内容
- 常见解释器的优缺点
- Tag
- Name
- Attributes
- 可以遍历的字符串
- BeautifulSoup
- 注释及特殊字符串
- 遍历文档树
- 子节点
- - find_all
- .contents和.children
- 子节点
安装BeautifulSoup
代码语言:javascript复制pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple beautifulsoup4
代码语言:javascript复制from bs4 import BeautifulSoup
- 素材
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
代码语言:javascript复制soup = BeautifulSoup(html_doc,"lxml")
几个简单的浏览结构化数据的方法
代码语言:javascript复制soup.title
代码语言:javascript复制<title>The Dormouse's story</title>
代码语言:javascript复制soup.title.name
代码语言:javascript复制'title'
代码语言:javascript复制soup.title.string
代码语言:javascript复制"The Dormouse's story"
代码语言:javascript复制soup.title.text
代码语言:javascript复制"The Dormouse's story"
代码语言:javascript复制soup.title.parent.name
代码语言:javascript复制'head'
代码语言:javascript复制soup.p
代码语言:javascript复制<p class="title"><b>The Dormouse's story</b></p>
代码语言:javascript复制soup.p.name
代码语言:javascript复制'p'
代码语言:javascript复制soup.p["class"]
代码语言:javascript复制['title']
代码语言:javascript复制soup.a
代码语言:javascript复制<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
代码语言:javascript复制soup.find("a")
代码语言:javascript复制<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
代码语言:javascript复制soup.find_all("a")
代码语言:javascript复制[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
从文档中找到所有的< a>标签的链接
代码语言:javascript复制for link in soup.find_all("a"):
print(link.get("href"))
代码语言:javascript复制http://example.com/elsie
http://example.com/lacie
http://example.com/tillie
在文档中获取所有的文字内容
代码语言:javascript复制print(soup.get_text())
代码语言:javascript复制The Dormouse's story
The Dormouse's story
Once upon a time there were three little sisters; and their names were
Elsie,
Lacie and
Tillie;
and they lived at the bottom of a well.
...
常见解释器的优缺点
Tag
- Tag有很多方法和属性,在 遍历文档树 和 搜索文档树 中有详细解释.现在介绍一下tag中最重要的属性: name和attributes
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
tag
代码语言:javascript复制<b class="boldest">Extremely bold</b>
代码语言:javascript复制type(tag)
代码语言:javascript复制bs4.element.Tag
Name
- 每个tag都有自己的名字,通过 .name 来获取:
tag.name
代码语言:javascript复制'b'
- 如果改变了tag的name,那将影响所有通过当前Beautiful Soup对象生成的HTML文档
tag.name = "blockquote"
tag
代码语言:javascript复制<blockquote class="boldest">Extremely bold</blockquote>
Attributes
- 一个tag可能有很多个属性.tag 有一个 “class” 的属性,值为 “boldest” . tag的属性的操作方法与字典相同:
tag["class"]
代码语言:javascript复制['boldest']
代码语言:javascript复制tag.attrs
代码语言:javascript复制{'class': ['boldest']}
- tag的属性可以被添加,删除或修改. 再说一次, tag的属性操作方法与字典一样
tag["class"] = "verybold"
tag["id"] = 1
tag
代码语言:javascript复制<blockquote class="verybold" id="1">Extremely bold</blockquote>
代码语言:javascript复制del tag["class"]
tag
代码语言:javascript复制<blockquote id="1">Extremely bold</blockquote>
多值属性
代码语言:javascript复制css_soup = BeautifulSoup('<p class="body strikeout"></p>')
css_soup.p['class']
代码语言:javascript复制['body', 'strikeout']
代码语言:javascript复制css_soup = BeautifulSoup('<p class="body"></p>')
css_soup.p['class']
代码语言:javascript复制['body']
可以遍历的字符串
- 字符串常被包含在tag内.Beautiful Soup用 NavigableString 类来包装tag中的字符串:
tag.string
代码语言:javascript复制'Extremely bold'
代码语言:javascript复制type(tag.string)
代码语言:javascript复制bs4.element.NavigableString
- 一个 NavigableString 字符串与Python中的Unicode字符串相同, 并且还支持包含在遍历文档树 和 搜索文档树 中的一些特性. 通过 unicode() 方法可以直接将 NavigableString 对象转换成Unicode字符串:
- tag中包含的字符串不能编辑,但是可以被替换成其他的字符串,用replace_with()方法
tag.string.replace_with("No longer bold")
tag
代码语言:javascript复制<blockquote id="1">No longer bold</blockquote>
BeautifulSoup
- BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,它支持 遍历文档树 和 搜索文档树 中描述的大部分的方法.
- 因为 BeautifulSoup 对象并不是真正的HTML或XML的tag,所以它没有name和attribute属性.但有时查看它的 .name 属性是很方便的,所以 BeautifulSoup 对象包含了一个值为 “[document]” 的特殊属性 .name
soup.name
代码语言:javascript复制'[document]'
注释及特殊字符串
- 文档的注释部分
markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
soup = BeautifulSoup(markup)
comment = soup.b.string
comment
代码语言:javascript复制'Hey, buddy. Want to buy a used parser?'
代码语言:javascript复制type(comment)
代码语言:javascript复制bs4.element.Comment
- Comment 对象是一个特殊类型的 NavigableString 对象:
comment
代码语言:javascript复制'Hey, buddy. Want to buy a used parser?'
但是当它出现在HTML文档中时, Comment 对象会使用特殊的格式输出:
代码语言:javascript复制print(soup.prettify())
代码语言:javascript复制<html>
<body>
<b>
<!--Hey, buddy. Want to buy a used parser?-->
</b>
</body>
</html>
代码语言:javascript复制from bs4 import CData
cdata = CData("A CDATA block")
comment.replace_with(cdata)
print(soup.b.prettify())
代码语言:javascript复制<b>
<![CDATA[A CDATA block]]>
</b>
遍历文档树
代码语言:javascript复制html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
代码语言:javascript复制from bs4 import BeautifulSoup
代码语言:javascript复制soup = BeautifulSoup(html_doc,"html.parser")
子节点
一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点.Beautiful Soup提供了许多操作和遍历子节点的属性.
代码语言:javascript复制soup.head
代码语言:javascript复制<head><title>The Dormouse's story</title></head>
代码语言:javascript复制soup.title
代码语言:javascript复制<title>The Dormouse's story</title>
这是个获取tag的小窍门,可以在文档树的tag中多次调用这个方法.下面的代码可以获取标签中的第一个标签:
代码语言:javascript复制soup.body.b
代码语言:javascript复制<b>The Dormouse's story</b>
通过点取属性的方式只能获得当前名字的第一个tag:
代码语言:javascript复制soup.a
代码语言:javascript复制<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
- find_all
如果想要得到所有的标签,或是通过名字得到比一个tag更多的内容的时候,就需要用到 Searching the tree 中描述的方法,比如: find_all()
代码语言:javascript复制soup.find_all("a")
代码语言:javascript复制[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
.contents和.children
代码语言:javascript复制head_tag = soup.head
head_tag
代码语言:javascript复制<head><title>The Dormouse's story</title></head>
代码语言:javascript复制head_tag.contents
代码语言:javascript复制[<title>The Dormouse's story</title>]
代码语言:javascript复制head_tag.contents[0]
代码语言:javascript复制<title>The Dormouse's story</title>
代码语言:javascript复制head_tag.contents[0].contents
代码语言:javascript复制["The Dormouse's story"]
BeautifulSoup 对象本身一定会包含子节点,也就是说标签也是 BeautifulSoup 对象的子节点:
代码语言:javascript复制soup.contents
代码语言:javascript复制['n',
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
</body></html>]
代码语言:javascript复制len(soup.contents)
代码语言:javascript复制2
代码语言:javascript复制soup.contents[0].name
到这里就结束了,如果对你有帮助,欢迎点赞关注评论,你的点赞对我很重要