使用BeautifulSoup解析HTML文本
下载地址: http://www.crummy.com/software/BeautifulSoup/ .
下载完后解压, cd到该目录, 输入命令: python setup.py install
测试:
#!/usr/bin/env python # coding=utf-8 # Python 2.7.3 from bs4 import BeautifulSoup soup2 = BeautifulSoup("<html>HTML Data.</html>") print(soup2.html.text) print(soup2.html) # 整个标签页打印了出来
输出:
HTML Data
<html>HTML Data.</html>
首先HTML文本的基本元素有标签, 标签属性, 和标签的内容, 还有就是树形结构. BeautifulSoup的结构就是基于这样HTML的树形结构.
例如:
#!/usr/bin/env python # coding=utf-8 # Python 2.7.3 from bs4 import BeautifulSoup soup2 = BeautifulSoup('<b class="boldest">Extremely bold</b>') tag = soup2.b print(tag) # 整个标签 print(tag.name) # 标签名字 print(tag.text) # 标签内容 print(tag['class']) # 属性(标签属性是一个字典对象)
输出:
<b class="boldest">Extremely bold</b>
b
Extremely bold
[u'boldest']
要分析的HTML
<html> <head> <title>Page title</title> </head> <body> <p id="firstpara" align="center"> This is paragraph<b>one</b>. </p> <p id="secondpara" align="blah"> This is paragraph<b>two</b>. </p> </body> </html>
#!/usr/bin/env python # coding=utf-8 # Python 2.7.3 from bs4 import BeautifulSoup soup2 = BeautifulSoup('<html><head><title>Page title</title></head><body><p id="firstpara" align="center">This is paragraph<b>one</b>.</p><p id="secondpara" align="blah">This is paragraph<b>two</b>.</p></body></html>') htmlTag = soup2.html # html有两个子标签head和body, head和body是兄弟 # contents是便签的子标签列表 print(htmlTag.contents[0]) # head contents的索引值不一定与HTML上的子标签顺序一致, 最好还是使用find print(htmlTag.head) # head print(htmlTag.contents[1]) # body print(htmlTag.body) # body headTag = htmlTag.head bodyTag = htmlTag.body print(headTag.parent) # head的父亲是html print(headTag.parents) # head的父亲链 print(bodyTag.parents) # body的父亲链 print(bodyTag.parent) # body的父亲是html print(headTag.nextSibling) # head的下一个兄弟是body print(headTag.previousSibling) # head的前一个兄弟是"没有"(None)
BeautifulSoup提供了find和find_all的方法进行查找. find只返回找到的第一个标签, 而find_all则返回一个列表.
#!/usr/bin/env python # coding=utf-8 # Python 2.7.3 from bs4 import BeautifulSoup soup2 = BeautifulSoup('<html><head><title>Page title</title></head><body><p id="firstpara" align="center">This is paragraph<b>one</b>.</p><p id="secondpara" align="blah">This is paragraph<b>two</b>.</p></body></html>') htmlTag = soup2.html # 查找所有p标签 print(soup2.find('p')) # 找到第一个就返回 print(soup2.p) # 找到第一个就返回(同上等价) print(soup2.findAll('p')) # 这里有两个 print(soup2('p')) # 这里有两个(同上等价) headTag = htmlTag.head print(headTag.find_parents()) # 等价headTag.parents(返回父亲链) print(headTag.find_parent()) # 等价headTag.parent # 下面4个函数是在查找同一父节点上的兄弟 print(headTag.find_next_siblings()) # 等价headTag.nextSiblings print(headTag.find_next_sibling()) # 等价headTag.nextSibling print(headTag.find_previous_siblings()) # 等价headTag.nextSiblings print(headTag.find_previous_sibling()) # 等价headTag.nextSibling # 下面4个函数是在查找是在整个html的所有节点上查找的(不管父子关系) print(headTag.find_all_next()) # 等价headTag.allNext print(headTag.find_next()) # 等价headTag.next print(headTag.find_all_previous()) # 等价headTag.allPrevious print(headTag.find_previous()) # 等价headTag.previous
看find的参数: find(name, attrs, recursive, text, **kwargs). 其他的查找函数与find函数相似, 看文档
find(tagname) # 直接搜索名为tagname的tag 如:find('head') find(list) # 搜索在list中的tag,如: find(['head', 'body']) find(dict) # 搜索在dict中的tag,如:find({'head':True, 'body':True}) find(re.compile('')) # 搜索符合正则的tag, 如:find(re.compile('^p')) 搜索以p开头的tag find(lambda) # 搜索函数返回结果为true的tag, 如:find(lambda name: if len(name) == 1) 搜索长度为1的tag find(True) # 搜索所有tag
(find_all也类似)
find(id='xxx') # 寻找id属性为xxx的 find(attrs={id=re.compile('xxx'), algin='xxx'}) # 寻找id属性符合正则且algin属性为xxx的 find(attrs={id=True, algin=None}) # 寻找有id属性但是没有algin属性的
注意, 文字的搜索会导致其他搜索给的值如: tag, attrs都失效.
方法与搜索tag一致
recursive=False表示只搜索直接儿子, 否则搜索整个子树, 默认为True.
当使用findAll或者类似返回list的方法时, limit属性用于限制返回的数量, 如findAll('p', limit=2)返回首先找到的两个tag
修改便签很简单, 查找到对应的标签对象后, 进行复制修改即可.
有了上述功能, 分析HTML和XML都很简单了.
BeautifulSoup功能可能还不知这些, 但目前还是够用的.
参考: http://www.cnblogs.com/twinsclover/archive/2012/04/26/2471704.html
http://cndenis.iteye.com/blog/1746706