beautifulsoup4学习小记
pip安装
pip install beautifulsoup4
或easy_install
easy_install beautifulsoup4
或源码安装
python setup.py install
BeautifulSoup除了内置HTML解析器,还支持一些第三方解析去,比如html5lib,lxml等,可以安装之后,在初始化BeautifulSoup对象的时候构建
一般可以处理两种html文件,一种是在线获取再处理,一种是直接处理本地文件
import requests
from bs4 import BeautifulSoup
# 通过requests获取
html = requests.get('http://www.pm25.com/xian.html')
soup = BeautifulSoup(html.text)
# 处理本地文件
soup = BeautifulSoup(open('test.html'))
BeautifulSoup主要有四类对象 Tag,NavigableString,BeautifulSoup,Comment
Tag有两种重要的属性 name和attrs
soup.p.name
soup.p.attrs 包括class在内的p标签的所有属性
soup.p[‘class’] class属性
soup.p.get(‘class’) 与上一个作用相同,获取class属性
soup.p[‘class’] = ‘newClass’ 修改class属性
获取标签的内容使用 .string或get_text()
BeautifulSoup 对象表示的是一个文档的全部内容
打印前可以判断一下是否为注释
if type(soup.a.string)==bs4.element.Comment:
print(soup.a.string)
for child in soup.body.children:
print(child)
for child in soup.body.descendants:
print(child)
for string in soup.strings:
print(repr(string))
.string可能会包含很多空格或空行,.stripped_strings可以去除多余空白内容
for string in soup.stripped_strings:
print(repr(string))
content = soup.head.title.string
print content.parent.name
#title
content = soup.head.title.string
for parent in content.parents:
print parent.name
输出
title
head
html
[document]
兄弟节点
.next_sibling 属性获取了该节点的下一个兄弟节点,.previous_sibling 则与之相反,如果节点不存在,则返回 None
全部兄弟节点
通过 .next_siblings 和 .previous_siblings 属性可以对当前节点的兄弟节点迭代输出
for sibling in soup.a.next_siblings:
print(repr(sibling))
前后节点
与.next_sibling .previous_sibling 不同,它并不是针对于兄弟节点,而是在所有节点,不分层次
比如
<head><title>The Dormouse's storytitle>head>
print(soup.head.next_element)
它的下一个节点便是 title
for element in last_a_tag.next_elements:
print(repr(element))
标签soup.find_all('b')
B. 传正则表达式
import re
for tag in soup.find_all(re.compile('^b')):
print(tag.name)
C. 传列表
soup.find_all([‘a’, ‘b’])
D. 传方法
如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
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)
2) 关键字参数
# 查找id为link2
soup.find_all(id='link2')
# 传入href参数,搜索每个tag的‘href’属性
soup.find_all(href=re.compile('elseid'))
# 可以使用多个指定名字的参数,同时过滤tag的多个属性
soup.find_all(href=re.compile('elseid'),id='link1')
# 如果想用class过滤,但是class是python的关键词,怎么办? 加个下划线就可以
soup.find_all('a', class_="sister")
# 有些tag属性在搜索不能使用,比如html5的data-*属性,可以通过find_all()的attrs参数定义一个字典来搜索包含特殊属性的tag
soup.find_all(attrs={'data-foo': 'value'})
3) text参数
通过 text 参数可以搜搜文档中的字符串内容.与 name 参数的可选值一样, text 参数接受 字符串 , 正则表达式 , 列表, True
4) limit参数
limit参数与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果.
soup.find_all('a', limit=2)
5) recursive参数
调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False .
soup.html.find_all("title", recursive=False)
写css时,标签名不加修饰,类名前加点,id名前加#,可以利用类似的方法筛选元素,用到的方法是soup.select(),返回list
# 通过标签名查找
soup.select('title')
# 通过类名查找
soup.select('.sister')
# 通过id名查找
soup.select('#link1')
# 组合查找
soup.select('p #link1')
# 直接子标签查找
soup.select("head > title")
# 组合查找
soup.select('a[class="sister"]')
soup.select('a[href="http://example.com/elseid"]')
soup.select('p a[href="http://example.com/elseid"]')
以上的select方法范湖IDE结果都是列表形式i,可以遍历形式输出,然后用get_text()方法来获取它的内容
soup = BeautifulSoup(html, 'lxml')
print type(soup.select('title'))
print soup.select('title')[0].get_text()
for title in soup.select('title'):
print(repr(title))
本文参考 http://cuiqingcai.com/1319.html