[学习]用python的BeautifulSoup分析html

序言

  之前用python爬取网页的时候,一直用的是regex或者自带的库sgmllib里的SGMLParser。但是遇到复杂一点的情况时,SGMLParser往往就不那么给力了!(哈,难道说我 too native了?毕竟beautifulSoup是继承sgmlparser的么~)所以,我寻寻觅觅寻寻觅觅,发现了BeautifulSoup这么个玩意。BeautifulSoup提供了很人性化的parser tree,有了它,我们可以简单的抽取出tagname, attrs, text等等等等...

  install什么的,看这里 -> http://www.crummy.com/software/BeautifulSoup/

入门

(ps:其实入门什么的看官方文档是最好的了,这里只是记录一下简单的用法。)

(official document link : http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html

  首先先介绍实际工作中最常用的几个方法:

  举例的html代码(就用官方例子好了):

复制代码
 1 <html>
 2     <head>
 3         <title>Page title</title>
 4     </head>
 5     <body>
 6         <p id="firstpara" align="center">
 7         This is paragraph<b>one</b>.
 8         </p>
 9         <p id="secondpara" align="blah">
10         This is paragraph<b>two</b>.
11         </p>
12      </body>
13 </html>
复制代码

 

0、初始化

 

1 soup = BeautifulSoup(html) # html为html源代码字符串,type(html) == str

 

1、用tag获取相应代码块的剖析树:

 

  既然要分析html,首先要找到对我们有用的tag块,beautiful提供了非常便利的方式。

复制代码
#当用tag作为搜索条件时,我们获取的包含这个tag块的剖析树:
#<tag><xxx>ooo</xxx></tag>
#这里获取head这个块
head = soup.find('head')
# or
# head = soup.head
# or
# head = soup.contents[0].contents[0]
复制代码

运行后,我们会得到:

1 <head>
2     <title>Page title</title>
3 </head>

  这里小灯我还是推荐使用第二种方法,find方法在当前tag剖析树(当前这个html代码块中)寻找符合条件的子树并返回。find方法提供多种查询方式,包括用喜闻乐见的regex哦~之后会详细介绍。

  contents属性是一个列表,里面保存了该剖析树的直接儿子。

如:

1 html = soup.contents[0] # <html> ... </html>
2 head = html.contents[0] # <head> ... </head>
3 body = html.contents[1] # <body> ... </body>

 

2、用contents[], parent, nextSibling, previousSibling寻找父子兄弟tag


  为了更加方便灵活的分析html代码块,beautifulSoup提供了几个简单的方法直接获取当前tag块的父子兄弟。

假设我们已经获得了body这个tag块,我们想要寻找<html>, <head>, 第一个<p>, 第二个<p>这四个tag块:

复制代码
# body = soup.bodyhtml = body.parent # html是body的父亲
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]也可得到 print p1.text # u'This is paragraphone.' print p2.text # u'This is paragraphtwo.' # 注意:1,每个tag的text包括了它以及它子孙的text。2,所有text已经被自动转 #为unicode,如果需要,可以自行转码encode(xxx)
复制代码

 

  然而,如果我们要寻找祖先或者孙子tag怎么办呢?? 用while循环吗? 不, beautifulsoup已经提供了方法。

 

3、用find, findParent, findNextSibling, findPreviousSibling寻找祖先或者子孙 tag:

 

  有了上面的基础,这里应该很好理解了,例如find方法(我理解和findChild是一样的),就是以当前节点为起始,遍历整个子树,找到后返回。

  而这些方法的复数形式,会找到所有符合要求的tag,以list的方式放回。他们的对应关系是:find->findall, findParent->findParents, findNextSibling->findNextSiblings...

  如:

1 print soup.findAll('p')
2 # [<p id="firstpara" align="center">This is paragraph <b>one</b>.</p>, <p id="secondpara" align="blah">This is paragraph <b>two</b>.</p>]

  

  这里我们重点讲一下find的几种用法,其他的类比:

  find(name=None, attrs={}, recursive=True, text=None, **kwargs)

(ps:只讲几种用法,完整请看官方link : http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html#The%20basic%20find%20method:%20findAll%28name,%20attrs,%20recursive,%20text,%20limit,%20**kwargs%29

  1) 搜索tag:

1 find(tagname)        # 直接搜索名为tagname的tag 如:find('head')
2 find(list)           # 搜索在list中的tag,如: find(['head', 'body'])
3 find(dict)           # 搜索在dict中的tag,如:find({'head':True, 'body':True})
4 find(re.compile('')) # 搜索符合正则的tag, 如:find(re.compile('^p')) 搜索以p开头的tag
5 find(lambda)         # 搜索函数返回结果为true的tag, 如:find(lambda name: if len(name) == 1) 搜索长度为1的tag
6 find(True)           # 搜索所有tag

 

  2) 搜索属性(attrs):

1 find(id='xxx')                                  # 寻找id属性为xxx的
2 find(attrs={id=re.compile('xxx'), algin='xxx'}) # 寻找id属性符合正则且algin属性为xxx的
3 find(attrs={id=True, algin=None})               # 寻找有id属性但是没有algin属性的

  3) 搜索文字(text):

注意,文字的搜索会导致其他搜索给的值如:tag, attrs都失效。

方法与搜索tag一致

  4) recursive, limit:

  recursive=False表示只搜索直接儿子,否则搜索整个子树,默认为True。

  当使用findAll或者类似返回list的方法时,limit属性用于限制返回的数量,如findAll('p', limit=2): 返回首先找到的两个tag

 

*4、用next,previous寻找上下文tag(少用)

 

  这里我们主要看看next, next是取得当前的tag的下一个(按代码从上到下的顺序)tag块。这与contents是不一样的,千万别混淆了哦^ ^

  我们举个栗子来看看

1 <a>
2     a
3     <b>b</b>
4     <c>c</c>
5 </a>

 我们看看next的实际效果:

1 a = soup.a
2 b = soup.b
3 n1 = b.next
4 n2 = n1.next

 输出一下:

1 print a.next
2 # u'a'
3 print n1
4 # u'b'
5 print n2
6 # <c>c</c>

所以,next仅仅是获取文档上的“下一个”的tag,和剖析树中的位置无关。

当然也有findNext和findAllNext方法。

至于previous, 表示上一个tag块,就类比一下吧~^ ^

=======

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很高兴回答你的问题!Python数据分析是一种重要的数据科学工具,可以让你从数据中发现有意义的信息。Python有许多数据分析库,包括pandas、numpy、matplotlib等等,它们都可以帮助你更好地理解数据。你可以使用这些库来清洗和准备数据、执行数据分析和可视化、以及构建机器学习模型等等。如果你想深入了解Python数据分析,建议学习一些数据科学的基础知识,比如数据结构、统计学、概率论等等。 ### 回答2: Python数据分析是一种使用Python编程语言来处理、清洗、分析和可视化数据的技术或方法。Python拥有丰富的库和工具,使得进行数据分析变得相对简单和高效。以下是关于Python数据分析的一些重要内容和特点: 1. 数据处理:Python数据分析工具提供了处理大规模数据集的能力。例如,使用NumPy和Pandas库可以进行数据结构操作、数据过滤和转换,以及缺失值的处理。 2. 数据可视化:Python的Matplotlib和Seaborn等库提供了强大的绘图功能,可以创建各种静态和动态的图表,有助于更好地理解数据和发现数据之间的模式和关联。 3. 机器学习Python拥有许多强大的机器学习库,如Scikit-learn和TensorFlow,使得应用各种机器学习算法和模型变得更加容易。这些库提供了许多经典的机器学习算法和模型,如线性回归、决策树、支持向量机等。 4. 数据挖掘:Python还提供了一些用于数据挖掘的库,如NLTK(自然语言处理工具包)和BeautifulSoup(用于解析HTML和XML文档)。这些库可以帮助提取和处理文本数据,进行文本分析和情感分析等任务。 5. 大数据:随着大数据技术的发展,Python也逐渐融入到大数据处理和分析领域。例如,PySpark是一个使用Python开发的大数据处理框架,可以运行在Apache Spark上,支持高效的并行计算和分布式数据处理。 总之,Python数据分析是一种功能强大、灵活且易于上手的数据分析方法。它提供了丰富的库和工具,可以处理各种类型的数据,并使用机器学习和数据挖掘技术进行高级分析和预测。无论是在学术研究、商业决策还是其他领域,Python数据分析都是一项不可或缺的技能。 ### 回答3: Python数据分析是利用Python语言进行数据处理、清洗、分析和可视化的过程。Python作为一种简洁、易学的编程语言,具备强大的数据分析能力,能够有效地处理和探索大量的数据。 Python数据分析的基础是使用各种数据处理库,如NumPy、Pandas和SciPy等。NumPy是Python中常用的数值计算库,提供了大量的数值运算函数和数据结构,能够高效地进行向量化计算。Pandas是数据分析中最常用的库之一,提供了DataFrame数据结构,可以方便地处理结构化数据,进行数据清洗、过滤和聚合等操作。SciPy库则提供了一系列科学计算和统计分析功能,包括概率分布、假设检验和回归分析等。 除了基础库之外,Python还有一些专门用于数据分析的库,例如Matplotlib和Seaborn用于数据可视化,可以绘制各种图表和图形,方便展示和分析数据。此外,还有Scikit-learn用于机器学习,可以进行分类、聚类和回归等任务,以及StatsModels用于统计模型拟合和推断等。 Python数据分析的优势在于其丰富的库和工具生态系统、易于学习和使用、跨平台性强,并且有大量的社区支持和文档资源。Python还可以和其他语言(如R语言和SQL)配合使用,扩展数据分析的能力。 总的来说,Python数据分析是一种强大的数据处理工具,能够帮助人们从大量的数据中提取有价值的信息,并支持决策和预测。无论是在科学研究、商业分析还是数据挖掘等方面,Python数据分析都扮演着重要的角色。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值