【Python】 html解析BeautifulSoup
BeautifulSoup
bs是个html解析模块,常用来做爬虫?
■ 安装
BeautifulSoup可以通过pip来安装,用pip install beautifulsoup4 即可。但是仅仅这样安装的bs,其默认的html解析器是python自带的HTMLParser模块,性能不是很好。可以考虑安装性能更加好的lxml和html5lib模块:pip install html5lib
■ 基本用法
BeautifulSoup有官方文档,可以查阅
① 建立BeautifulSoup对象,它是基于一个html字符串或者一个文件
from bs4 import BeautifulSoup
soup = BeautifulSoup("...一串html")
#或者
soup = BeautifulSoup(open("文件路径","r")) print soup.prettify() #可以美化这段html并打印出来
② 四类对象
bs将一个html抽象成一个树形结构,每个节点都是一个python里的对象。共分成了四种对象。
● Tag类对象
即html中的标签,BeautifulSoup对象(以上面代码中的soup为例)可以直接在后面接上某种标签的名称,得到的对象是该种标签在这段html中的第一个实例。
比如对于print soup.h1 >>> <h1 class="...">...</h1> (bs里的html对象是可打印的,打印出来就是html原文)
每个Tag类对象都有两个属性,name和attrs。
name就是标签的名字,而attrs是个字典,里面记录了所有这个tag的属性值。比如有tag是<h1 class="space-seo space-meta" name="testname">HELLO</h1>
其name就是u'h1',而attrs是{u'class':[u'space-seo',u'space-meta'],u'name':u'testname'} //注意区别tag对象的name属性和写在attrs里面的name属性的区别,另外所有被存到变量里的html内容全部都变成了unicode对象。在print的时候可以指定encode,默认encode是utf-8。还有,所有class属性都默认都被解析成一个列表,即便只有一个class值,也会成为[u'class_value']
当然,在定位到Tag对象之后可以获取查看其属性值,另一方面,也可以对其属性值等进行修改,修改完了之后就是存在内存中的这个变量里面的,最终可以输出成文件的形式。
● String对象 //selenium用的是text来指代标签内部的文本内容,而bs用的是string。而且对于<div>这种本身不带文本带后辈节点可能带文本的标签两者意义不同。selenium中的.text会带出来所有后辈节点中的文本,而bs中的这个.string返回的是None
String对象用于代表每个元素所含的文字部分,在标签后面加上.string即可调用
print soup.h1.string >>> HELLO
注意,某个Tag对象的子节点以及子节点里面的内容都不算进string,当一个元素(比如<div>这种)里面只有子节点,本身没有文字的话,得到的就是None。
● BeautifulSoup对象
指代整个文档的对象。可以视为是<html>的对象。其实之前创建的BeautifulSoup对象soup,就是指代整个html文档
● comment对象
用于代表某个元素内的注释
■ 遍历文件树
除了上面提到的一些基本属性,Tag对象(包括BeautifulSoup对象)都含有以下属性:
Tag.contents 将某个Tag的各个子节点(不包括孙和孙以下节点)按照列表的方式输出
Tag.children 返回一个上述列表的迭代器,也只有子节点(没有孙和孙以下节点)
Tag.descendants 返回一个迭代器,内容是所有后辈节点
Tag.strings 返回Tag中所有的文字部分的生成器,保留换行,制表符等空格。相当于是prettify之后去掉所有html标签的文本状态。
Tag.stripped_strings 和上一项相比,再去掉所有空白字符,只保留有实际字符的文本部分。这两个方法常用于对被分析网页文本的搜索和处理。
Tag.parent 父节点
Tag.parents 长辈节点的迭代器
Tag.next_sibling 下一个同辈节点(如果没有同辈就返回None,下同)
Tag.previous_sibling 上一个同辈节点
Tag.next_sibilings 之后所有同辈节点的迭代器
Tag.previous_sibilings 之前所有同辈节点的迭代器
//关于同辈节点有一个坑。。在看起来比较美观的HTML文档中,总是有很多换行符合制表符的。而在BS中如果要调用一个同辈节点,那么这些空白的文本节点也都会被算进去。比如:
#<p><span>one</span><span id="main">two</span></p>
print soup.find(name="span",attrs={"id":"main"}).previous_sibling
#得到的是<span>one</span> #如果处理的是这样一段HTML:
#<p>
# <span>one</span>
# <span id="main">two</span>
#</p>
print repr(soup.find(name="span",attrs={"id":"main"}).previous_sibling)
#得到的是"\n\t"因为在第一个span之前有一段空白文本被当做一个节点了。
然而在通过这个span.parent寻找p或者是通过p.children寻找span的时候,这些空白文本节点都不会被算进去。所以只有在引用同辈节点的时候要注意。
Tag.next_element 下一个元素,包括string对象,子节点,同辈分节点在内,无视辈分的下一个
Tag.previous_element 上一个元素,说明同上
Tag.next_elements next_element的迭代器
Tag.previous_elements previous_element的迭代器
■ 检索文件树方法
● Tag.find_all(name,attr,recursive,text,**kwargs) 方法。功能是检索Tag内所有后辈节点,并判断是否符合某种条件,最后返回一个列表
1. name参数
name参数可以直接写Tag.name。比如find_all("p"),find_all("div")等
也可以写正则表达式(re.compile之后的对象)。比如find_all(re.compile("^b"))
也可以写列表,比如find_all(['a','p'])
甚至可以写一个函数对象,这时就要自己定义这个函数了。这个函数要接收一个Tag对象来作为参数,并最终返回True或者False来告诉find_all这个对象该不该被find进去
2. attr参数
attr参数可以指定一个字典的形式来过滤,比如find_all(attrs={'id':'testid'})就是找到所有id是testid的元素
3. text参数
用于搜索字串内容。也可以支持name参数中那几种写的形式。注意,返回的不是对象的列表,而是文本的列表。当name和text的参数同时出现的话,text会作为name的一个附加条件,返回的还是带标签的列表。
4. recursive参数
默认是True,可改成False放弃递归进子辈以下子节点。只检索第一级的子节点。
5. limit参数
有时候文档太大了,检索所有元素很费时间,limit可以指定一个数值,当检索找到了这个数量的目标之后就停止检索
● Tag.find方法:参数和find_all一致,只不过其返回的不是一个列表,而是找到第一个就返回了。
● Tag.find_parents Tag.find_parent
Tag.find_next_sibilings Tag.find_next_sibiling
Tag.find_previous_sibilings Tag.find_previous_sibiling
Tag.find_all_next Tag.find_next
Tag.find_all_previous Tag.find_previous
以上所有方法,每行前一个和后一个的关系就是find_all和find的关系。而每一行相当于是为检索指定了一个大致的范围。比如说find_all和find是在所有后辈节点中检索的话,那么find_parents和find_parent就是在所有长辈节点中寻找,find_next_sibilings和find_next_sibiling就是在所有后面的同辈节点中寻找等等
● Tag.select("selector") 可以借助select方法来确定一个或多个特定的元素,默认查找全部符合的元素并返回一个列表。selector的语法就是jQuery里面selector的语法。这个方法还是比较实用的。与之相对的有select_one方法,只返回第一个查找到的元素。
总的来说,不管是通过一个节点,遍历文件树的方法来找到想要获得的节点对象,还是通过检索方法来定位一个节点对象,都是寻找对象的一种方法。很难说哪种最好哪种不好,应该要灵活运用。
【Python】 html解析BeautifulSoup的更多相关文章
- 【Python爬虫】BeautifulSoup网页解析库
BeautifulSoup 网页解析库 阅读目录 初识Beautiful Soup Beautiful Soup库的4种解析器 Beautiful Soup类的基本元素 基本使用 标签选择器 节点操作 ...
- python爬虫解析库之Beautifulsoup模块
一 介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会 ...
- 第14.12节 Python中使用BeautifulSoup解析http报文:使用select方法快速定位内容
一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>和<第14.11节 Python中使用BeautifulSo ...
- 第14.11节 Python中使用BeautifulSoup解析http报文:使用查找方法快速定位内容
一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>介绍了BeautifulSoup对象的主要属性,通过这些属性可以访 ...
- 第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问
一. 引言 在<第14.8节 Python中使用BeautifulSoup加载HTML报文>中介绍使用BeautifulSoup的安装.导入和创建对象的过程,本节介绍导入后利用Beauti ...
- Python网页解析
续上篇文章,网页抓取到手之后就是解析网页了. 在Python中解析网页的库不少,我最开始使用的是BeautifulSoup,貌似这个也是Python中最知名的HTML解析库.它主要的特点就是容错性很好 ...
- Python 爬虫 解析库的使用 --- Beautiful Soup
知道了正则表达式的相关用法,但是一旦正则表达式写的有问题,得到的可能就不是我们想要的结果了.而且对于一个网页来说,都有一定的特殊结构和层级关系,而且有很多节点都有id或class来做区分,所以借助它们 ...
- python爬虫解析页面数据的三种方式
re模块 re.S表示匹配单行 re.M表示匹配多行 使用re模块提取图片url,下载所有糗事百科中的图片 普通版 import requests import re import os if not ...
- python中的BeautifulSoup使用小结
1.安装 pip install beautifulsoup4 2.代码文件中导入 from bs4 import BeautifulSoup 3. 解析器 使用方法 优势 劣势 Python标准库 ...
- python学习(25) BeautifulSoup介绍和实战
BeautifulSoup是python的html解析库,处理html非常方便 BeautifulSoup 安装 pip install beautifulsoup4 BeautifulSoup 配合 ...
随机推荐
- 读取含有BOM头的文件遇到的问题
需求是读取一个csv文件,然后解析成对应的数据结构.csv必须包含指定的某些列,通过列名header来进行校验. 解析配置文件的方法. public List<QuestionData> ...
- linux2.6硬盘扇区直接读写程序
下面的程序可以在linux2.6内核直接读写硬盘的指定扇区,也是根据网上一个朋友的做法做了修改的: 有两个不是很明白的地方就是:1.bd_claim函数的使用,这个是个递归函数,像是匹配内存指针和设备 ...
- 【原】无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页
一.开发环境: 1.windows 7 企业版 2.IDEA 14 3.JDK 1.8 4.Maven 3.5.2 5.MariaDB 6.SQLYog 二.Maven设置: Maven目录下的con ...
- css图片的相关操作
css图片的相关操作 1.案例源码 <!DOCTYPE html><html lang="en"><head> <meta charset ...
- gprecoverseg导致的元数据库问题致使数据库无法启动以及修复
一.现象描述 在一次执行gprecoverseg后发现数据库无法正常连接,现象如下: 执行gprecoverseg日志如下: gprecoverseg:mdw-:gpadmin-[INFO]:-Sta ...
- java继承属性相关介绍
这个只需要记住一点,父类的任何属性(变量可以看做属性),子类均可继承并覆盖,allType(father)-->changeAnyType(son)-->AnyType 这是父类的所有代表 ...
- 【Luogu3768】简单的数学题(莫比乌斯反演,杜教筛)
[Luogu3768]简单的数学题(莫比乌斯反演,杜教筛) 题面 洛谷 \[求\sum_{i=1}^n\sum_{j=1}^nijgcd(i,j)\] $ n<=10^9$ 题解 很明显的把\( ...
- 【Luogu3041】视频游戏的连击(AC自动机,动态规划)
题面链接 题解 首先构建出AC自动机 然后在AC自动机上面跑DP 转移很显然从Trie树的节点跳到他的儿子节点 但是要注意一个问题, 在计算的时候,每一个节点加入后能够 造成的贡献 要加上他的子串的贡 ...
- [Luogu2073]送花
题面 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花束,他不断地 ...
- Git知识总览(六) Git分支中的远程操作实践
前几篇博客陆陆续续的讲了好多关于Git操作的内容,本篇博客仍然也不例外,不过本篇博客的主题是关于git的远程操作的.依照之前博客的风格,我们依然依托于LearningGitBranch中的相关内容来探 ...