BeatifulSoup模块
一、介绍
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.你可能在寻找 Beautiful Soup3 的文档,Beautiful Soup 3 目前已经停止开发,官网推荐在现在的项目中使用Beautiful Soup 4, 移植到BS4
#安装 Beautiful Soup pip install beautifulsoup4 #安装解析器 Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是 lxml .根据操作系统不同,可以选择下列方法来安装lxml: $ apt-get install Python-lxml $ easy_install lxml $ pip install lxml 另一个可供选择的解析器是纯Python实现的 html5lib , html5lib的解析方式与浏览器相同,可以选择下列方法来安装html5lib: $ apt-get install Python-html5lib $ easy_install html5lib $ pip install html5lib
下表列出了主要的解析器,以及它们的优缺点,官网推荐使用lxml作为解析器,因为效率更高. 在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定.
二、基本使用
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" >Elsie</a>, <a href="http://example.com/lacie" class="sister" >Lacie</a> and <a href="http://example.com/tillie" class="sister" >Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p> """ #基本使用:容错处理,文档的容错能力指的是在html代码不完整的情况下,使用该模块可以识别该错误。使用BeautifulSoup解析上述代码,能够得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出 from bs4 import BeautifulSoup soup=BeautifulSoup(html_doc,'lxml') #具有容错功能 res=soup.prettify() #处理好缩进,结构化显示 print(res)
三、遍历文档树
#遍历文档树:即直接通过标签名字选择,特点是选择速度快,但如果存在多个相同的标签则只返回第一个 #1、用法 #2、获取标签的名称 #3、获取标签的属性 #4、获取标签的内容 #5、嵌套选择 #6、子节点、子孙节点 #7、父节点、祖先节点 #8、兄弟节点
1 #遍历文档树:即直接通过标签名字选择,特点是选择速度快,但如果存在多个相同的标签则只返回第一个 2 html_doc = """ 3 <html><head><title>The Dormouse's story</title></head> 4 <body> 5 <p >The Dormouse's story</b></p> 6 7 <p class="story">Once upon a time there were three little sisters; and their names were 8 <a href="http://example.com/elsie" class="sister" >Elsie</a>, 9 <a href="http://example.com/lacie" class="sister" >Lacie</a> and 10 <a href="http://example.com/tillie" class="sister" >Tillie</a>; 11 and they lived at the bottom of a well.</p> 12 13 <p class="story">...</p> 14 """ 15 16 #1、用法 17 from bs4 import BeautifulSoup 18 soup=BeautifulSoup(html_doc,'lxml') 19 # soup=BeautifulSoup(open('a.html'),'lxml') 20 21 print(soup.p) #存在多个相同的标签则只返回第一个 22 print(soup.a) #存在多个相同的标签则只返回第一个 23 24 #2、获取标签的名称 25 print(soup.p.name) 26 27 #3、获取标签的属性 28 print(soup.p.attrs) 29 30 #4、获取标签的内容 31 print(soup.p.string) # p下的文本只有一个时,取到,否则为None 32 print(soup.p.strings) #拿到一个生成器对象, 取到p下所有的文本内容 33 print(soup.p.text) #取到p下所有的文本内容 34 for line in soup.stripped_strings: #去掉空白 35 print(line) 36 37 38 ''' 39 如果tag包含了多个子节点,tag就无法确定 .string 方法应该调用哪个子节点的内容, .string 的输出结果是 None,如果只有一个子节点那么就输出该子节点的文本,比如下面的这种结构,soup.p.string 返回为None,但soup.p.strings就可以找到所有文本 40 <p id='list-1'> 41 哈哈哈哈 42 <a class='sss'> 43 <span> 44 <h1>aaaa</h1> 45 </span> 46 </a> 47 <b>bbbbb</b> 48 </p> 49 ''' 50 51 #5、嵌套选择 52 print(soup.head.title.string) 53 print(soup.body.a.string) 54 55 56 #6、子节点、子孙节点 57 print(soup.p.contents) #p下所有子节点 58 print(soup.p.children) #得到一个迭代器,包含p下所有子节点 59 60 for i,child in enumerate(soup.p.children): 61 print(i,child) 62 63 print(soup.p.descendants) #获取子孙节点,p下所有的标签都会选择出来 64 for i,child in enumerate(soup.p.descendants): 65 print(i,child) 66 67 #7、父节点、祖先节点 68 print(soup.a.parent) #获取a标签的父节点 69 print(soup.a.parents) #找到a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲... 70 71 72 #8、兄弟节点 73 print('=====>') 74 print(soup.a.next_sibling) #下一个兄弟 75 print(soup.a.previous_sibling) #上一个兄弟 76 77 print(list(soup.a.next_siblings)) #下面的兄弟们=>生成器对象 78 print(soup.a.previous_siblings) #上面的兄弟们=>生成器对象
1 soup = BeautifulSoup(html_doc,"lxml") #第一个参数指定文本内容,第二个参数解析器 2 3 # soup = BeautifulSoup(open("a.html"),"lxml") #也可以打开一个文件创建实例 4 print(soup.prettify()) #容错性的体现,自动补全 5 print(soup.a) #只找到了一个,而且是从整个文档树找 6 print(soup.a.text) #找到a标签里面的文本 7 print(soup.text) #找整个文档树种所有的文本 8 print(soup.a.attrs) #找a标签的所有属性,字典形式 9 print(soup.a.attrs["href"]) #找a标签的href属性 10 print(soup.p.b) #嵌套查找,这是只找一个 11 print(soup.p.contents) #子节点,找到的是一个闭标签 12 print(list(soup.p.children )) #得到生成器 13 print(list(soup.p.descendants)) #所有的子子孙孙 14 print(soup.a.parent)#找父亲 15 print(list(soup.a.parent))#父亲的父亲的父亲 16 17 print(soup.p.find_all() ) #标签名可以和find可以结合在一起使用