用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块,就类比一下吧~^ ^
=======
待续
用python的BeautifulSoup分析html的更多相关文章
- 用python的BeautifulSoup分析html 【转】
原地址:http://www.cnblogs.com/twinsclover/archive/2012/04/26/2471704.html 序言 之前用python爬取网页的时候,一直用的是rege ...
- python爬虫之分析Ajax请求抓取抓取今日头条街拍美图(七)
python爬虫之分析Ajax请求抓取抓取今日头条街拍美图 一.分析网站 1.进入浏览器,搜索今日头条,在搜索栏搜索街拍,然后选择图集这一栏. 2.按F12打开开发者工具,刷新网页,这时网页回弹到综合 ...
- Ubuntu下一个python的BeautifulSoup和rsa安装方法---信息检索project2部分:微博爬行要求python包裹
后果<信息检索>第二project,微博具有抓取数据,再处理.师兄给了代码.让慢慢爬.可是在ubuntu下.少了非常多python软件包.须要安装. 1.首先执行时.说少了python.B ...
- 搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台
搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台 By 子敬叔叔 最近在学习麦好的<机器学习实践指南案例应用解析第二版>,在安装学习环境的时候 ...
- Python配合BeautifulSoup读取网络图片并保存在本地
本例为Python配合BeautifulSoup读取网络图片,并保存在本地. BeautifulSoup可代替正则表达式,更好地解析Html文本,获取其中的指定内容,如Tag.Property等 # ...
- Python文章相关性分析---金庸武侠小说分析
百度到<金庸小说全集 14部>全(TXT)作者:金庸 下载下来,然后读取内容with open('names.txt') as f: data = [line.strip() for li ...
- [python]Python代码安全分析工具(Bandit)
简介: Bandit是一款Python源码分析框架,可用于Python代码的安全性分析.Bandit使用标准库中的ast模块,将Python源码解析成Python语法节点构成的树.Bandit允许用户 ...
- 用python探索和分析网络数据
Edited by Markdown Refered from: John Ladd, Jessica Otis, Christopher N. Warren, and Scott Weingart, ...
- python scrapy,beautifulsoup,regex,sgmparser,request,connection
In [2]: import requests In [3]: s = requests.Session() In [4]: s.headers 如果你是爬虫相关的业务?抓取的网站还各种各样, ...
随机推荐
- C++走向远洋——62(项目二1、类模板)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- pyteeseract使用报错Error: one input ui-file must be specified解决
Python在图像识别有天然的优势,今天使用pytesseract模块时遇到一个报错:“Error: one input ui-file must be specified”. 环境:windows ...
- 基于vue开发的在线付费课程应用
最近在弄一个付费课程的应用,主要有微信登录,支付和自定义分享,在开发过程中遇到的坑,这里做一下记录 文章主要有以下几点 使用库简介 微信登录解决 微信支付解决 微信自定义分享解决 页面前进后退数据状态 ...
- 前端每日实战:152# 视频演示如何用纯 CSS 创作一个圆点错觉效果
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/gBwzKR 可交互视频 此视频是可 ...
- 网页程序迁移至微信小程序web-view详解
小程序现在越来越流行,但是公司的很多项目都是用网页写的,小程序语法不兼容原生网页,使得旧有项目迁移至小程序代价很高: 小程序之前开放了webview功能,可以说是网页应用的一大福音了,但是微信的web ...
- React Native 在 Airbnb(译文)
在Android,iOS,Web和跨平台框架的横向对比中,React Native本身是一个相对较新且快速开发移动的平台.两年后,我们可以肯定地说React Native在很多方面都是革命性的.这是移 ...
- 前端面试题-<!DOCTYPE>
现在的各种前端开发工具都足够强大,支持插入模板代码,也就导致我们往往会忽略已经自动生成的代码,而代码的第一行 DOCTYPE 声明,就是最容易忽略的部分. 一.DOCTYPE DOCTYPE 是 do ...
- C#小游戏—钢铁侠VS太空侵略者
身为漫威迷,最近又把<钢铁侠>和<复仇者联盟>系列又重温了一遍,真的是印证了那句话:“读书百遍,其意自现”.看电影一个道理,每看一遍,都有不懂的感受~ 不知道大伙是不是也有同样 ...
- 处理公共CDN突然失效的情况
公共CDN的使用 刚开始开发我的博客时,使用的bootcdn,发现他们被黑过,虽然想骂那些“黑客”,但是我们也没办法去防范,只能从自己的网站上入手解决. 那时我还没技术解决这个问题,网上搜过,大都只提 ...
- 峰哥说技术:10-Spring Boot静态资源处理
Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 10 峰哥说技术:Spring Boot静态资源处理 今天我们聊聊关于 Spring Boot 中关于静 ...