当前位置: 代码迷 >> Web前端 >> Beautiful Soup 汉语教程
  详细解决方案

Beautiful Soup 汉语教程

热度:659   发布时间:2013-11-02 19:41:10.0
Beautiful Soup 中文教程
http://www.pythonclub.org/modules/beautifulsoup/start
使用yumex安装

官方文档:http://www.crummy.com/software/BeautifulSoup/bs4/doc/,version=4
中文文档:http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html

用python的BeautifulSoup分析html http://www.cnblogs.com/twinsclover/archive/2012/04/26/2471704.html
BeautifulSoup使用概要 http://blog.csdn.net/wangchongxiu/article/details/8901246

用BeautifulSoup查找属性值未知的标签 http://www.crifan.com/python_use_beautifulsoup_find_tag_with_unknown_attribute_value/
Python正则表达式操作指南 http://wiki.ubuntu.org.cn/Python%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97
运用BeautifulSoup抓取网页的链接 http://www.cnblogs.com/winterIce/archive/2011/10/06/2200002.html

Beautiful Soup 中文教程
创建 BeautifulSoup 对象
BeautifulSoup对象需要一段html文本就可以创建了。
下面的代码就创建了一个BeautifulSoup对象:
from BeautifulSoup import BeautifulSoup
doc = ['<html><head><title>PythonClub.org</title></head>',
       '<body><p id="firstpara" align="center">This is paragraph <b>one</b> of ptyhonclub.org.',
       '<p id="secondpara" align="blah">This is paragraph <b>two</b> of pythonclub.org.',
       '</html>']
soup = BeautifulSoup(''.join(doc))



查找HTML内指定元素
BeautifulSoup可以直接用”.”访问指定HTML元素
根据html标签(tag)查找:查找html title
可以用 soup.html.head.title 得到title的name,和字符串值。
>>> soup.html.head.title
<title>PythonClub.org</title>
>>> soup.html.head.title.name
u'title'
>>> soup.html.head.title.string
u'PythonClub.org'
>>> 

也可以直接通过soup.title直接定位到指定HTML元素:
>>> soup.title
<title>PythonClub.org</title>
>>> 



根据html内容查找:查找包含特定字符串的整个标签内容
下面的例子给出了查找含有”para”的html tag内容:
>>> soup.findAll(text=re.compile("para"))
[u'This is paragraph ', u'This is paragraph ']
>>> soup.findAll(text=re.compile("para"))[0].parent
<p id="firstpara" align="center">This is paragraph <b>one</b> of ptyhonclub.org.</p>
>>> soup.findAll(text=re.compile("para"))[0].parent.contents
[u'This is paragraph ', <b>one</b>, u' of ptyhonclub.org.']



根据CSS属性查找HTML内容
soup.findAll(id=re.compile("para$"))
# [<p id="firstpara" align="center">This is paragraph <b>one</b>.</p>,
#  <p id="secondpara" align="blah">This is paragraph <b>two</b>.</p>]
 
soup.findAll(attrs={'id' : re.compile("para$")})
# [<p id="firstpara" align="center">This is paragraph <b>one</b>.</p>,
#  <p id="secondpara" align="blah">This is paragraph <b>two</b>.</p>]






BeautifulSoup使用概要
在程序中中导入 Beautiful Soup库:
from BeautifulSoup import BeautifulSoup          
# For processing HTML
from BeautifulSoup import BeautifulStoneSoup     # For processing XML
import BeautifulSoup                             # To get everything

soup = BeautifulSoup(html, from_encoding='utf-8')
smartQuotesTo=None 到soup构造器:这时 smart quotes会被正确的转换为Unicode。
print soup.prettify()


导航soup的一些方法:
soup.contents[0].name
soup.contents[0].contents[0].name
head = soup.contents[0].contents[0]
head.parent.name
head.next
head.nextSibling.name
head.nextSibling.contents[0]
head.nextSibling.contents[0].nextSibling
next为下一个标签,nextSibling为下一个兄弟标签。


搜索soup
.string
soup.findAll('p', align="center")
soup.find('p', align="center")
soup('p', align="center")[0]['id']
soup.find('p', align=re.compile('^b.*'))['id']
soup.find('p').b.string
soup('p')[1].b.string
comment = commentSoup.find(text=re.compile("nice"))


有些标签可以内嵌 (<BLOCKQUOTE>) ,有些不行 (<P>).
table和list标签有一个自然的内嵌顺序。例如,<TD> 标签内为 <TR> 标签,而不会相反。
<SCRIPT> 标签的内容不会被剖析为HTML。
<META> 标签可以知道文档的编码类型。
BeautifulSoup 会智能判断那些需要添加关闭标签的位置,即使原始的文档没有。

soup.originalEncoding:获得解析之前的编码
默认的编码(str使用的)是UTF-8。

剖析对象包括2个其他类型的对象,Tag对象, 用于操纵像<TITLE> ,<B>这样的标签;
NavigableString对象, 用于操纵字符串,如"Page title"和"This is paragraph"。

nextSibling和previousSibling
使用它们你可以跳往在剖析树中同等层次的下一个元素。

next和previous
使用它们可以按照soup处理文档的次序遍历整个文档,而不是它们在剖析树中看到那种次序。

一个Tag的有多少child可以直接使用len(tag)而不必使用len(tag.contents)来获得。
这里的两个方法(findAll和 find)仅对Tag对象以及 顶层剖析对象有效,但 NavigableString不可用。

findAll(name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)
参数name 匹配tags的名字,获得相应的结果集。
1 最简单用法是仅仅给定一个tag name值。下面的代码寻找文档中所有的 <B> Tag:
soup.findAll('b')
2 你可以传一个正则表达式。下面的代码寻找所有以b开头的标签:
tagsStartingWithB = soup.findAll(re.compile('^b'))
3 你可以传一个list或dictionary。下面两个调用是查找所有的<TITLE>和<P>标签。 他们获得结果一样,但是后一种方法更快一些:
soup.findAll(['title', 'p'])
soup.findAll({'title' : True, 'p' : True})
4 你可以传一个True值,这样可以匹配每个tag的name:也就是匹配每个tag。
allTags = soup.findAll(True)
5 你可以传callable对象,就是一个使用Tag对象作为它唯一的参数,并返回布尔值的对象。 findAll使用的每个作为参数的Tag对象都会传递给这个callable对象, 并且如果调用返回True,则这个tag便是匹配的。
下面是查找两个并仅两个属性的标签(tags):
soup.findAll(lambda tag: len(tag.attrs) == 2)
下面是寻找单个字符为标签名并且没有属性的标签:
soup.findAll(lambda tag: len(tag.name) == 1 and not tag.attrs)
keyword参数用于筛选tag的属性。下面这个例子是查找拥有属性align且值为center的 所有标签:
soup.findAll(align="center")
soup.findAll(id=re.compile("para$"))
soup.findAll(align=["center", "blah"])
soup.findAll(align=lambda(value): value and len(value) < 5)


attrs是一个字典,用起来就和keyword参数一样
soup.findAll(attrs={'id' : re.compile("para$")})

你可以使用attrs去匹配那些名字为Python保留字的属性, 例如class, for, 以及import; 或者那些不是keyword参数但是名字为Beautiful Soup搜索方法使用的参数名的属性, 例如name, recursive, limit, text, 以及attrs本身。

text 是一个用于搜索NavigableString对象的参数。 它的值可以是字符串,一个正则表达式, 一个list或dictionary,True或None, 一个以NavigableString为参数的可调用对象:如果你使用text,任何指定给name 以及keyword参数的值都会被忽略。
soup.findAll(text="one")
soup.findAll(text=u'one')
soup.findAll(text=["one", "two"])
soup.findAll(text=re.compile("paragraph"))
soup.findAll(text=True)
soup.findAll(text=lambda(x): len(x) < 12)

recursive 是一个布尔参数(默认为True),用于指定Beautiful Soup遍历整个剖析树, 还是只查找当前的子标签或者剖析对象。
[tag.name for tag in soup.html.findAll()]
[tag.name for tag in soup.html.findAll(recursive=False)]
设置limit 参数可以让Beautiful Soup 在找到特定个数的匹配时停止搜索。
soup.findAll('p', limit=1)
soup.findAll('p', limit=100)


find(name, attrs, recursive, text, **kwargs):只返回一个结果。
NavigableString没有contents:它们是剖析树的叶子。

s = soup.h1
while getattr(s, 'name', None) != 'ul':
    s = s.nextSibling
s.li
soup.h1.findNextSibling('ul').li
soup.find(text='Heading').findNext('ul').li


findNextSiblings(name, attrs, text, limit, **kwargs) and findNextSibling(name, attrs, text, **kwargs)
这两个方法以nextSibling的成员为依据, 获得满足条件的Tag或NavigableText对象。

findPreviousSiblings(name, attrs, text, limit, **kwargs) and findPreviousSibling(name, attrs, text, **kwargs)
这两个方法以previousSibling成员为依据,获得满足条件的Tag和 NavigableText对象。

findAllNext(name, attrs, text, limit, **kwargs) and findNext(name, attrs, text, **kwargs)
这两个方法以next的成员为依据, 获得满足条件的Tag和NavigableText对象。

findAllPrevious(name, attrs, text, limit, **kwargs) and findPrevious(name, attrs, text, **kwargs)
这两方法以previous的成员依据, 获得满足条件的Tag和NavigableText对象。

findParents(name, attrs, limit, **kwargs) and findParent(name, attrs, **kwargs)
这两个方法以parent成员为依据, 获得满足条件的Tag和NavigableText对象。 他们没有text参数,因为这里的对象的parent不会有NavigableString。
bTag = soup.find('b')
[tag.name for tag in bTag.findParents()]
bTag.findParent('body').name
  相关解决方案