当前位置: 首页 > 编程日记 > 正文

python html解析查找字符串_用python的BeautifulSoup分析html

序言

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

入门

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

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

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

1

2

3

Page title

4

5

6

7 This is paragraphone.

8

9

10 This is paragraphtwo.

11

12

13

0、初始化:

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

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

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

#当用tag作为搜索条件时,我们获取的包含这个tag块的剖析树:

#ooo

#这里获取head这个块

head = soup.find('head')

# or

# head = soup.head

# or

# head = soup.contents[0].contents[0]

运行后,我们会得到:

1

2

Page title

3

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

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

如:

1 html = soup.contents[0] # ...

2 head = html.contents[0] #

...

3 body = html.contents[1] #

...

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

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

假设我们已经获得了body这个tag块,我们想要寻找,

, 第一个

, 第二个

这四个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 # [

This is paragraph one.

,

This is paragraph two.

]

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

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

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

2 a

3 b

4 c

5

我们看看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

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

当然也有findNext和findAllNext方法。

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

=======

待续

相关文章:

ejb 3中bean的种类

会话bean(session bean) 主要用来编写业务逻辑和对数据库进行操作,Session Bean用于实现业务逻辑,它分为有状态bean和无状态bean。每当客户端请求时,容器就会选择一个Session Bean来为客户端服务。Session Bean可以直接访问数据库&#xff0…

Android学习 —— 数据的存储与访问方式一: 文件存取

笔记摘要: 在Android中主要提供了四种数据存储与访问的方式,文件、SharedPreference(偏好参数保存)、SOLite数据库、内容提供者(Content provider)和网络, 本篇文章先介绍使用文件的方式进行数据…

react的安装使用

react的重要思想是通过组件来开发应用&#xff0c;而组件就是能够完成某个特定功能而独立、可复用的代码。 react是可以像JQuery那样直接下载引入使用&#xff0c;也可以直接引用官网提供的CDN的地址&#xff1a; <script src"https://unpkg.com/react16/umd/react.dev…

锐捷交换机配置snmp版本_snmp交换机配置

华为交换机1、查询交换机当前是snmp配置命令dis cur2、进入全局模式 int ethernet1/0/7 shutdown 关 undoshutdown 激活sys3、进入SNMP配置snmp-agent4、配置只读字符串snmp-agent community read abcd5、配置写字符串snmp-agent community write abcd6、开启snmp版本支持功能 …

Linux命令find的35个实例

注&#xff1a;本文内容参考《35 Practical Examples of Linux Find Command》 网址&#xff1a;http://www.tecmint.com/35-practical-examples-of-linux-find-command/ Linux 查找命令是Linux系统中最重要和最常用的命令之一。查找用于根据与参数匹配的文件指定的条件来搜索…

PHP使用APNS的 feedback service

http://blog.csdn.net/gnicky/article/details/7544202 1. URL是不一样的&#xff0c;端口是2196 2. 使用同样的Certificate&#xff0c;建立安全连接&#xff0c;接受数据&#xff0c;直到数据不存在&#xff0c;类似table select操作 3.每条纪录是一个token&#xff0c;serve…

洛谷——P2341 [HAOI2006]受欢迎的牛//POJ2186:Popular Cows

P2341 [HAOI2006]受欢迎的牛/POJ2186:Popular Cows 题目背景 本题测试数据已修复。 题目描述 每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶 牛都是自恋狂&#xff0c;每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜 欢…

学习使用Bing Maps Silverlight Control(五):离线使用和自定义地图模式

6 离线使用 在笔记第一部分的时候就提到如果要使用Bing Maps Silverlight Control 进行开发&#xff0c;需要申请一个key&#xff0c;不让会显示一个错误提示出来。但是在实际开发或使用过程中&#xff0c;使用环境和地图数据可能不是在线的&#xff0c;但控件因为验证失败仍然…

python123第k序元素查找_Python实现折半查找并用matplotlib实现动态过程可视化

折半查找是算法中减治策略的基本例子&#xff0c;实现起来也很简单&#xff0c;但是在网上看到的图片教程不觉得很乾巴麽&#xff1f;&#xff1f;在这里插入图片描述这是一个简单的实现&#xff1a;def Reduction(lists, k):""":param lists: 元素列表:param k…

vim进阶技巧

本篇博文是在之前的《vim基础入门》的基础之上写的&#xff0c;不懂的同学可以先看之前的分享 1. 视觉范围的选择 普通模式下&#xff0c;按v键确定范围起点&#xff0c;然后移动光标&#xff0c;光标所在位置为范围的终点&#xff0c;然后按操作键完成其他操作&#xff0c;之…

Flex Air程序打包成独立的exe安装文件

2019独角兽企业重金招聘Python工程师标准>>> 开发背景&#xff1a; FlexBuilder3.2开发生成的Air程序需要能够独立安装&#xff0c;事先不需要安装AdobeAir运行环境 实现方法&#xff1a; 1)用winrar打开xx.air文件爱能&#xff0c;并将它解压在D:\airapp目录中。 2…

《C++primer》第一章--开始

之前开始读《Cprimer》&#xff0c;想着读书不动笔不如不读书&#xff0c;于是就想做一个读书笔记的内容&#xff0c;于是就想起了写一个《Cprimer读思录》的一个专栏。一是为了给自己平时读书做笔记&#xff0c;方便自己随时查看。二是为了督促自己每天学习。三是为了知识的分…

对于计算机网络的整体框架的概括(转载) 个人感觉很好

作者&#xff1a; 阮一峰 日期&#xff1a; 2012年5月31日 我们每天使用互联网&#xff0c;你是否想过&#xff0c;它是如何实现的&#xff1f; 全世界几十亿台电脑&#xff0c;连接在一起&#xff0c;两两通信。上海的某一块网卡送出信号&#xff0c;洛杉矶的另一块网卡居然就…

Centos修改系统语言

使用man page帮助时&#xff0c;发现居然是中文的&#xff0c;不过想想即便英语再水&#xff0c;也要逼着自己去适应。于是百度找了一下修改系统语言的方法。 首先使用 locale 命令查看当前的系统语言 然后修改时一般有两种方法&#xff0c;一是临时修改&#xff0c;立即生效&a…

tp3 普通模式url模式_Thinkphp 3.2.3 url 路由访问模式

Thinkphp 3.2.3 url 的4中路由模式&#xff1a;// 0 (普通模式)http://网址/index.php?m模块&c控制器&a方法http://localhost/index.php?mHome&cindex&aindex//1 (PATHINFO 模式) 默认为PATHINFO 模式http://网址/index.php/模块/控制器/方法http://localhos…

Mysql 基于 Amoeba 的 读写分离(2)

<?xml version"1.0" encoding"gbk"?> <!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd"> <amoeba:configuration xmlns:amoeba"http://amoeba.meidusa.com/"><proxy><!-- service class must implem…

Linux驱动之LCD驱动编写

在Linux驱动之内核自带的S3C2440的LCD驱动分析这篇博客中已经分析了编写LCD驱动的步骤&#xff0c;接下来就按照这个步骤来字尝试字节编写LCD驱动。用的LCD屏幕为tft屏&#xff0c;每个像素点为16bit。对应与红绿蓝分别为565。 1、分配一个fb_info结构 2、设置fb_info结构 3、硬…

《C++primer》第二章--变量和基本内置类型

基本内置类型 如何选择类型的几点建议 当明确知晓数值不能为负数时&#xff0c;选用无符号类型使用int进行整数运算。因为short一般表示的范围比较小&#xff0c;而long一般和int有相同的范围。如果表示的范围超过了int就使用long long算术运算时尽量不要使用char和bool&…

【入门】等差素数组

题目描述 如果两个素数之和的一半仍然是一个素数&#xff0c;则这三个素数可以组成一个等差素数组&#xff0c;如&#xff08;37&#xff09;/25&#xff0c;则&#xff08;3&#xff0c;5&#xff0c;7&#xff09;为一个等差素数组&#xff0c;编程求100以内的所有等差素数组…

flutter和webapp_Flutter全平台!迁移现有Flutter项目到WEB端

写在前面Flutter 是 Google推出并开源的移动应用开发框架&#xff0c;主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App&#xff0c;一套代码同时运行在 iOS 、Android、web和桌面端。Flutter_web是Flutter代码兼容web的实现&#xff0c;可以将使用Dart编写的现有…

使用正则表达式构造定制的HTML5输入框

为什么80%的码农都做不了架构师&#xff1f;>>> 正则表达式&#xff08;点此在线编辑测试&#xff09;是一个功能强大的灵活而简洁的匹配文本字符串的工具&#xff0c;比如匹配特定的字符、单词等。正则表达式通过一个语言规则来书写&#xff0c;通过正则表达式处理…

idea dubbo jar error:cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'dubbo:application' 的声明...

声明&#xff1a; 出现这个错误的情形是&#xff0c;在idea开发环境里面运行是没有问题的&#xff0c;使用哦idea自带的打包工具生成jar之后&#xff0c;运行jar的时候报的这个错误&#xff0c;如果不是这个情况&#xff0c;这篇文章可能不适用。 主要的原因是spring.schemas、…

lwip可以用于发udp_LWIPUDP一对多

最近在STM32F767的开发板上移植了LWIP UDP的代码&#xff0c;开发板的资料里面有介绍LWIP移植的文档&#xff0c;介绍了几种网络通信方式&#xff0c;如TCP server&#xff0c;TCP client&#xff0c;UDP&#xff0c;按照文档里面的介绍也很容易实现。这里我选择的是基于ucos2操…

奇淫怪巧之给Delphi的PrintDialog增加一个页码选定范围打印的Edit

在Delphi中使用PrintDialog打印对话框的时候&#xff0c;这个控件有三个选项&#xff0c;就是PrintRang那个属性的三个选项&#xff0c;其中有一个选项三&#xff0c;让我们自定义选择页码范围来打印。但是比较蛋疼的是&#xff0c;这个地方选中了之后啥子效果都没有。无法制定…

进程管理(图文)

进程的图文形象表示 阮一峰–进程与线程的一个简单解释 多进程实质 现在&#xff0c;多核CPU已经非常普及了&#xff0c;但是&#xff0c;即使过去的单核CPU&#xff0c;也可以执行多任务。由于CPU执行代码都是顺序执行的&#xff0c;那么&#xff0c;单核CPU是怎么执行多任…

拿到WP官方主题Twenty Ten就是一顿nofollow伺候

2019独角兽企业重金招聘Python工程师标准>>> 今天2012-07-03&#xff0c;我的个人cn域名申请下来了&#xff0c;于是网站搬迁&#xff0c;暂时没有选择一个好的WordPress主题&#xff0c;只有用默认的Twenty Ten&#xff0c;不过这个主题对SEO方面还有一些欠缺&…

Qt分析:Qt中的两种定时器

QTimer类的定时器 QTimer类定时器是QObject类定时器的扩展版或者说升级版&#xff0c;因为它可以提供更多的功能。比如说&#xff0c;它支持单次触发和多次触发。 使用QTimer类定时器的步骤&#xff1a; &#xff08;1&#xff09;创建一个QTimer定时器实例&#xff1a;QTimer …

uestc 1012 饭卡

饭卡(card) Time Limit: 1000 ms Memory Limit: 65535 kB Solved: 253 Tried: 2169 Submit Status Best Solution Back Description 电子科大本部食堂的饭卡有一种很诡异的设计&#xff0c;即在购买之前判断余额。如果购买一个商品之前&#xff0c;卡上的剩余金额大于或等…

wps临时文件不自动删除_win10系统下wps残留文件无法删除如何解决

一位用户反馈自己在win10系统电脑中卸载金山WPS办公软件时&#xff0c;发现根本无法将wps残留的文件夹删除&#xff0c;在删除的时候提示“操作无法完成&#xff0c;因为其中的文件夹或文件已在另一程序打开 请关闭该文件夹文件重试”&#xff0c;这该怎么办呢&#xff1f;接下…

WEB登录H3C模拟器

思路&#xff1a;先将路由器与本地网卡绑定&#xff0c;然后将本地网卡与路由器接口ip设置在同一网段&#xff0c;在路由器上建立本地用户&#xff0c;最后登录就OK了。 1、查看本机网卡的序列号&#xff0c;在CMD里输入systeminfo&#xff0c;输出的最下…