00、安装Beautiful Soup
Beautiful Soup官方文档
pip install beautifulsoup4
01、解析文件
Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是 lxml .
pip install lxml
另一个可供选择的解析器是纯Python实现的 html5lib , html5lib的解析方式与浏览器相同
pip install html5lib
import requests
from bs4 import BeautifulSoup
url = "http://www.baidu.com"
html = requests.get(url).text
soup = BeautifulSoup(html,'html.parser') #创建beautifulsoup对象
常用方法
soup.prettify() #格式化输出
02、bs4常用对象
<i class="fa fa-user">i>
<a href="/wp-login.php?action=register">投稿a>
<time class="muted">4年前 (2015-03-10)time>
<h2>1. Beautiful Soup的简介h2>
常用浏览数据结构方法
soup.title
#<title>百度一下,你就知道title>
soup.title.name
# u'title'
soup.title.string
# u'百度一下,你就知道'
soup.title.parent.name
# u'head'
soup.p
#<p id="lh"> <a href="http://home.baidu.com">关于百度a> <a href="http://ir.baidu.com">About Baidua> p>
soup.find_all('a')
#[<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻a>, <a class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123a>, <a class="mnav" href="http://map.baidu.com" name="tj_trmap">地图a>, <a class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频a>, <a class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧a>, <a class="lb" href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login">登录a>, <a class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="display: block;">更多产品a>, <a href="http://home.baidu.com">关于百度a>, <a href="http://ir.baidu.com">About Baidua>, <a href="http://www.baidu.com/duty/">使用百度前必读a>, <a class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈a>]
for link in soup.find_all('a'):
print(link.get('href'))
#href="http://www.baidu.com/duty/"
#....
#link["href"]起一样效果,操作跟字典一样
其属性与使用方法
name
soup 对象本身比较特殊,它的 name 即为 [document],对于其他内部标签,输出的值便为标签本身的名称。
通过点取属性的方式只能获得当前名字的第一个tag
print (soup.name) #[document]
print (soup.a) #a
其他具体属性,请详参官方文档
03、搜索数据
Beautiful Soup定义了很多搜索方法,这里着重介绍2个: find() 和 find_all()
过滤器
介绍 find_all() 方法前,先介绍一下过滤器的类型 ,这些过滤器贯穿整个搜索的API.过滤器可以被用在tag的name中,节点的属性中,字符串中或他们的混合中.
字符串
最简单的过滤器是字符串.在搜索方法中传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容,下面的例子用于查找文档中所有的标签:
soup.find_all('b')
# [The Dormouse's story]
正则表达式
如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容.下面例子中找出所有以b开头的标签,这表示body和b标签都应该被找到:
import re
for tag in soup.find_all(re.compile("^b")):
print(tag.name)
# body
# b
下面是个实际应用的例子
for i in soup.find_all('a'):
print (i["href"])
http://news.baidu.com
https://www.hao123.com
http://map.baidu.com
http://v.baidu.com
http://tieba.baidu.com
http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1
//www.baidu.com/more/
http://home.baidu.com
http://ir.baidu.com
http://www.baidu.com/duty/
http://jianyi.baidu.com/
PS C:\Users\Administrator\Desktop>
方法
如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 [4] ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
下面方法校验了当前元素,如果包含 class 属性却不包含 id 属性,那么将返回 True:
def has_class_but_no_id(tag):
return tag.has_attr('class') and not tag.has_attr('id')
将这个方法作为参数传入 find_all() 方法,将得到所有
标签:
soup.find_all(has_class_but_no_id)
# [<p class="title"><b>The Dormouse's storyb>p>,
# <p class="story">Once upon a time there were...p>,
# <p class="story">...p>]