解析库BeautifulSoup4基本使用
一.安装
pip install Beautifulsoup4
Beautiful Soup在解析时实际是依赖解析器的,它除了支持python标准库中的HTML解析器外还支持第三方解析器如lxml等,推荐使用lxml.
安装解析器: pip install lxml
二.基本使用
创建beautifulsoup对象
soup=BeautifulSoup(html,'lxml')
html: 可以为 str, 也可以是 文件句柄fp
'lxml': 解析器, 需安装lxml包
1.节点选择器
直接调用节点的名称就可以选择节点元素,节点可以嵌套选择, 返回的类型都是bs4.element.Tag对象
soup.head #获取head标签
soup.p.b #获取p节点下的b节点
soup.p.string #获取p标签下的文本
当同级有多个相同节点时, 节点选择器默认只选择第一个
节点的属性方法:
name属性获取节点的名称:
soup.div.name
attrs属性获取节点属,返回的结果可能是列表或字符串类型,取决于节点类型
soup.p.attrs #获取p节点所有属性
soup.p.attrs['class'] #获取p节点class属性
soup.p['class'] #直接获取p节点class属性 以字典的形式直接获取
soup.p.get('class')
string属性获取节点元素包含的文本内容:
soup.p.string #获取第一个p节点下的文本内容
contents属性获取节点的直接子节点,以列表的形式返回内容
soup.div.contents #直接子节点,bs4将换行也作为一个节点
children属性获取的也是节点的直接子节点,以生成器的类型返回
soup.div.children
descendants属性获取子孙节点,返回生成器
soup.div.descendants
parent属性获取父节点,parents获取祖先节点,返回生成器
soup.b.parent
soup.b.parents
next_sibling属性返回下一个兄弟节点,previous_sibling返回上一个兄弟节点,注意换行符也是一个节点,所以获取兄弟节点是通常是字符串或者空白
soup.a.next_sibling
soup.a.previous_sibling
next_element和previous_element属性获取下一个被解析的对象,或者上一个
soup.a.next_element
soup.a.previous_element
next_elements和previous_elements迭代器向前或者后访问文档解析内容
soup.a.next_elements
soup.a.previous_elements
2.使用find_all
find_all(name,attrs,recursive,text,**kwargs):查询所有符合条件的元素,其中的参数:
name表示可以查找所有名字为name的标签(tag),也可以是过滤器,正则表达式,列表或者是True
attrs表示传入的属性,可以通过attrs参数以字典的形式指定如常用属性id,attrs={'id':'123'},由于class属性是python中的关键字,所有在查询时需要在class后面加上下划线即class_='element',返回的结果是tag类型的列表
text参数用来匹配节点的文本,传入的形式可以是字符串也可以是正则表达式对象
recursive表示,如果只想搜索直接子节点可以将参数设为false:recursive=Flase
limit参数,可以用来限制返回结果的数量,与SQL中的limit关键字类似
find_all(条件):查询所有符合条件的元素
查找标签名为 div 的所有元素
soup.find_all(name='div') # name代表标签名,不是name属性
soup.find_all('div') # 标签查找
查找标签名为 li 或 a 的所有元素
soup.find_all(name = ['li', 'a'])
查找 id 为 world 的所有元素
soup.find_all(id = 'world')
查找 class 为 active 的 所有元素
soup.find_all(class_='active') # class为python关键字,需加下划线
查找 a 标签中,title 属性为 hello 的所有元素
soup.find_all('a', title='hello') # 标签 加属性过滤
soup.find_all('a', title='hello', limit=2) # 限制输出, limit属性代表取前2个
查找 a 标签中包含属性 id='box', class='active' 的所有元素
soup.find_all('a',attrs={'id':'box','class':'active'}) # 多属性过滤
查找文本中能匹配字符串 hello 的所有元素
soup.find_all(text=re.compile('Tillie')) # 使用正则过滤查找
其他方法:
find( name , attrs , recursive , text , **kwargs ):它返回的是单个元素,也就是第一个匹配的元素,类型依然是tag类型
参数同find_all()一样
3. css选择器
使用css选择器语法查找元素
查找所有 a 标签
soup.select('a')
查找 class = 'active' 的所有元素
soup.select('.active')
查找 id = 'box' 的元素
soup.select('#box')
查找 .active 的 所有后代 li 标签
soup.select(.active li)
查找 li 标签 的所有子元素 a
soup.select('li > a')
通过是否存在某个属性来查找元素
soup.select('li[class]') # 查找带有class属性的所有 li 标签
通过属性的值来查找匹配
soup.select( 'li[class="active"]' ) # 查找带有 class='hello' 的 所有 li 标签
soup.select('li[class^="act"]') #匹配值的开头
soup.select('li[class$="ve"]') #匹配值的结尾
soup.select('li[class*="tiv"]') #模糊匹配
获取节点文本
soup.select('a')[0].get_text()
soup.select('a')[0].string #貌似仅有文本时有效, 嵌套了其他标签时失效