<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="http://itecfun.com/extern.php?action=feed&amp;tid=3181&amp;type=rss" rel="self" type="application/rss+xml" />
		<title><![CDATA[个人知识管理站 / BeautifulSoup 方法小结]]></title>
		<link>http://www.itecfun.com/viewtopic.php?id=3181</link>
		<description><![CDATA[BeautifulSoup 方法小结 最近发表的帖子。]]></description>
		<lastBuildDate>Thu, 02 Jul 2015 07:28:39 +0000</lastBuildDate>
		<generator>FluxBB</generator>
		<item>
			<title><![CDATA[BeautifulSoup 方法小结]]></title>
			<link>http://www.itecfun.com/viewtopic.php?pid=3350#p3350</link>
			<description><![CDATA[<p>BeautifulSoup是Python的一个第三方库，可用于帮助解析html/XML等内容，以抓取特定的网页信息。目前最新的是v4版本，这里主要总结一下我使用的v3版本解析html的一些常用方法。<br /><strong>1.初始化<br />&#160; &#160;导入模块</strong></p><div class="codebox"><pre><code>#!/usr/bin/env python
from bs4 import BeautifulSoup       #process html
#from BeautifulSoup import BeautifulStoneSoup #process xml
#import BeautifulSoup                         #all</code></pre></div><p> <strong>创建对象：str初始化，常用urllib2或browser返回的html初始化BeautifulSoup对象。<br />doc = [&#039;hello&#039;,&#039;This is paragraph one of ptyhonclub.org.&#039;,&#039;This is paragraph two of pythonclub.org.&#039;,&#039;&#039;]<br />soup = BeautifulSoup(&#039;&#039;.join(doc))<br />指定编码：当html为其他类型编码（非utf-8和asc ii），比如GB2312的话，则需要指定相应的字符编码，BeautifulSoup才能正确解析。</strong></p><div class="codebox"><pre><code>htmlCharset = &quot;GB2312&quot;
soup = BeautifulSoup(respHtml, fromEncoding=htmlCharset)</code></pre></div><p><strong>2.获取tag内容<br />&#160; &#160;寻找感兴趣的tag块内容，返回对应tag块的剖析树</strong></p><div class="codebox"><pre><code>head = soup.find(&#039;head&#039;)
#head = soup.head
#head = soup.contents[0].contents[0]

print head</code></pre></div><p> 返回内容：hello<br /> 说明一下，contents属性是一个列表，里面保存了该剖析树的直接儿子。</p><div class="codebox"><pre><code>html = soup.contents[0]       # &lt;html&gt; ... &lt;/html&gt;
head = html.contents[0]       # &lt;head&gt; ... &lt;/head&gt;
body = html.contents[1]       # &lt;body&gt; ... &lt;/body&gt;</code></pre></div><p><strong><br />3.获取关系节点<br />&#160; &#160;使用parent获取父节点</strong></p><div class="codebox"><pre><code>body = soup.body
html = body.parent             # html是body的父亲</code></pre></div><p>使用nextSibling, previousSibling获取前后兄弟</p><div class="codebox"><pre><code>head = body.previousSibling    # head和body在同一层，是body的前一个兄弟
p1 = body.contents[0]          # p1, p2都是body的儿子，我们用contents[0]取得p1
p2 = p1.nextSibling            # p2与p1在同一层，是p1的后一个兄弟, 当然body.content[1]也可得到</code></pre></div><p> contents[]的灵活运用也可以寻找关系节点,寻找祖先或者子孙可以采用findParent(s), findNextSibling(s), findPreviousSibling(s)<br /><strong><br />4.find/findAll用法详解</strong><br />&#160; &#160;函数原型：find(name=None, attrs={}, recursive=True, text=None, **kwargs)，findAll会返回所有符合要求的结果，并以list返回。<br /> <strong>&#160; tag搜索</strong></p><div class="codebox"><pre><code>find(tagname)                                  # 直接搜索名为tagname的tag 如：find(&#039;head&#039;)
find(list)                                     # 搜索在list中的tag，如: find([&#039;head&#039;, &#039;body&#039;])
find(dict)                                     # 搜索在dict中的tag，如:find({&#039;head&#039;:True, &#039;body&#039;:True})
find(re.compile(&#039;&#039;))                           # 搜索符合正则的tag, 如:find(re.compile(&#039;^p&#039;)) 搜索以p开头的tag
find(lambda)                       # 搜索函数返回结果为true的tag, 如:find(lambda name: if len(name) == 1) 搜索长度为1的tag
find(True)                                     # 搜索所有tag</code></pre></div><p> <strong>&#160; attrs搜索</strong></p><div class="codebox"><pre><code>find(id=&#039;xxx&#039;)                                  # 寻找id属性为xxx的
find(attrs={id=re.compile(&#039;xxx&#039;), algin=&#039;xxx&#039;}) # 寻找id属性符合正则且algin属性为xxx的
find(attrs={id=True, algin=None})               # 寻找有id属性但是没有algin属性的

resp1 = soup.findAll(&#039;a&#039;, attrs = {&#039;href&#039;: match1})
resp2 = soup.findAll(&#039;h1&#039;, attrs = {&#039;class&#039;: match2})
resp3 = soup.findAll(&#039;img&#039;, attrs = {&#039;id&#039;: match3})</code></pre></div><p> <strong>&#160; text搜索</strong><br />&#160; &#160;文字的搜索会导致其他搜索给的值如：tag, attrs都失效。方法与搜索tag一致</p><div class="codebox"><pre><code>print p1.text
# u&#039;This is paragraphone.&#039;
print p2.text
# u&#039;This is paragraphtwo.&#039;
# 注意：1，每个tag的text包括了它以及它子孙的text。2，所有text已经被自动转为unicode，如果需要，可以自行转码encode(xxx)</code></pre></div><p> <strong>&#160; recursive和limit属性</strong><br />&#160; &#160; recursive=False表示只搜索直接儿子，否则搜索整个子树，默认为True。当使用findAll或者类似返回list的方法时，limit属性用于限制返回的数量，如findAll(&#039;p&#039;, limit=2)： 返回首先找到的两个tag</p>]]></description>
			<author><![CDATA[dummy@example.com (xuyg)]]></author>
			<pubDate>Thu, 02 Jul 2015 07:28:39 +0000</pubDate>
			<guid>http://www.itecfun.com/viewtopic.php?pid=3350#p3350</guid>
		</item>
	</channel>
</rss>
