爬虫-使用BeautifulSoup4(bs4)解析html数据
Beautiful Soup 是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据。
一、安装
- sudo pip3 install beautifulsoup4
二、使用
导入模块
- from bs4 import BeautifulSoup
创建BeautifulSoup对象
- In [1]: from bs4 import BeautifulSoup
- In [2]: text = '''
- ...: <div>
- ...: <ul>
- ...: <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- ...: <li class="item-1"><a href="link2.html">second item</a></li>
- ...: <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
- ...: <li class="item-1"><a href="link4.html">fourth item</a></li>
- ...: <li class="item-0"><a href="link5.html">fifth item</a></li>
- ...: </ul>
- ...: </div>
- ...: '''
- In [3]: bs = BeautifulSoup(text)#创建BeautifulSoup对象,可以直接传入字符串
- In [4]: bs1 = BeautifulSoup(open('./test.html'))#也可以传入文件对象
- In [5]: bs
- Out[5]:
- <html><body><div>
- <ul>
- <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- <li class="item-1"><a href="link2.html">second item</a></li>
- <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
- <li class="item-1"><a href="link4.html">fourth item</a></li>
- <li class="item-0"><a href="link5.html">fifth item</a></li>
- </ul>
- </div>
- </body></html>
创建Beautiful Soup对象时,既可以传入字符串,也可以传入文件对象。它将复杂HTML文档转换成一个复杂的树形结构,并且会自动修正文档,像上述例子中补齐了html和body节点,每个节点都是Python对象
获取Tag对象
- In [6]: bs.ul #获取ul标签内容
- Out[6]:
- <ul>
- <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- <li class="item-1"><a href="link2.html">second item</a></li>
- <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
- <li class="item-1"><a href="link4.html">fourth item</a></li>
- <li class="item-0"><a href="link5.html">fifth item</a></li>
- </ul>
- In [7]: type(bs.ul)
- Out[7]: bs4.element.Tag
- In [8]: bs.li #获取li标签内容,注意返回的是第一个符合要求的标签
- Out[8]: <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- In [12]: bs.ul.li.a #可叠加查找标签
- Out[12]: <a href="link1.html">first item</a>
通过Beautiful Soup对象后面接上‘.标签名’来获取需要查找的标签,可叠加
- In [6]: bs.ul #获取ul标签内容
Tag对象常用属性
name-----显示标签名
- In [13]: bs.name #大部分时候,可以把BeautifulSoup当作Tag对象,是一个特殊的 Tag
- Out[13]: '[document]'
- In [14]: bs.li.name
- Out[14]: 'li
BeautifulSoup 对象表示的是一个文档的内容。大部分时候,可以把它当作 Tag 对象
- In [13]: bs.name #大部分时候,可以把BeautifulSoup当作Tag对象,是一个特殊的 Tag
attrs----以字典的方式显示该标签所有属性
- In [15]: bs.attrs
- Out[15]: {}
- In [16]: bs.li.attrs #以字典的形式显示所有属性
- Out[16]: {'class': ['item-0'], 'id': 'first'}
- In [17]: bs.li.attrs['id'] #获取具体的某个属性方法1
- Out[17]: 'first'
- In [18]: bs.li['id'] #获取具体属性方法2,'.attrs'可省略
- Out[18]: 'first'
- In [19]: bs.li.get('id')#获取具体 属性方法3,利用get方法
- Out[19]: 'first'
- In [15]: bs.attrs
string----获取标签里面的内容
- In [20]: bs.li.string #li标签里面只有唯一的a标签了,那么 .string 会返回最里面a标签的内容
- Out[20]: 'first item'
- In [21]: bs.li.a.string #返回a标签的内容
- Out[21]: 'first item'
注意:如果标签内容是一个注释,则注释符号会被去掉,比如“<!-- 这是一个注释 -->”,则返回"这是一个注释"
- In [20]: bs.li.string #li标签里面只有唯一的a标签了,那么 .string 会返回最里面a标签的内容
contents----将直接子节点以列表的形式输出,同时也包含换行符'\n'
- In [22]: bs.ul.contents
- Out[22]:
- ['\n',
- <li class="item-0" id="first"><a href="link1.html">first item</a></li>,
- '\n',
- <li class="item-1"><a href="link2.html">second item</a></li>,
- '\n',
- <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>,
- '\n',
- <li class="item-1"><a href="link4.html">fourth item</a></li>,
- '\n',
- <li class="item-0"><a href="link5.html">fifth item</a></li>,
- '\n']
- In [22]: bs.ul.contents
chilldren----将直接子节点以列表生成器的形式输出,也包括换行符‘\n
- In [28]: bs.ul.children #返回的是列表生成器对象
- Out[28]: <list_iterator at 0x7f2d9e90ea30>
- In [29]: for child in bs.ul.children:
- ...: print(child)
- ...:
- <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- <li class="item-1"><a href="link2.html">second item</a></li>
- <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
- <li class="item-1"><a href="link4.html">fourth item</a></li>
- <li class="item-0"><a href="link5.html">fifth item</a></li>
- In [28]: bs.ul.children #返回的是列表生成器对象
descendants----返回的是一个生成器对象,进行迭代取值的时候,会递归循环的显示所有子孙节点
- In [30]: bs.ul.descendants #返回的是一个生成器对象,进行迭代取值的时候,会递归循环的显示所有子孙节点
- Out[30]: <generator object Tag.descendants at 0x7f2d9e79fc80>
- In [31]: for d in bs.ul.descendants:
- ...: print(d)
- ...:
- <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- <a href="link1.html">first item</a>
- first item
- <li class="item-1"><a href="link2.html">second item</a></li>
- <a href="link2.html">second item</a>
- second item
- <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
- <a href="link3.html"><span class="bold">third item</span></a>
- <span class="bold">third item</span>
- third item
- <li class="item-1"><a href="link4.html">fourth item</a></li>
- <a href="link4.html">fourth item</a>
- fourth item
- <li class="item-0"><a href="link5.html">fifth item</a></li>
- <a href="link5.html">fifth item</a>
- fifth item
- In [30]: bs.ul.descendants #返回的是一个生成器对象,进行迭代取值的时候,会递归循环的显示所有子孙节点
Tag对象常用方法
find(self, name=None, attrs={}, recursive=True, text=None,**kwargs)----------只返回第一个匹配的对象
name参数----过滤标签名,可以传入字符串、正则以及列表3种形式
- In [32]: bs.find('li') #查找第一个匹配的li标签
- Out[32]: <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- In [33]: bs.find(['li','a']) #查找第一个匹配的li标签或者a标签
- Out[33]: <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- In [34]: import re
- In [35]: bs.find(re.compile(r'^l')) #查找第一个以l开头的标签,li标签匹配上
- Out[35]: <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- In [36]: bs.find(re.compile(r'l$')) #查找第一个以l结尾的标签,html标签符合
- Out[36]:
- <html><body><div>
- <ul>
- <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- <li class="item-1"><a href="link2.html">second item</a></li>
- <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
- <li class="item-1"><a href="link4.html">fourth item</a></li>
- <li class="item-0"><a href="link5.html">fifth item</a></li>
- </ul>
- </div>
- </body></html>
- In [32]: bs.find('li') #查找第一个匹配的li标签
attrs参数----过滤属性,dict类型
- In [37]: bs.find(attrs={'class':'item-1'}) #查找class属性为item-1的第一个标签
- Out[37]: <li class="item-1"><a href="link2.html">second item</a></li>
- In [37]: bs.find(attrs={'class':'item-1'}) #查找class属性为item-1的第一个标签
recursive参数----如果为True,表示是否递归地从子孙节点中去查找匹配对象。否则只从直接子节点中进行查找
- In [38]: bs.find('li',recursive=True) #递归查找,能够匹配到li对象
- Out[38]: <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- In [39]: bs.find('li',recursive=False) #从直接子节点(即html)中无法找到li标签
- In [40]: bs.ul.find('li',recursive=False) #ul的直接子节点为li标签,所以能够匹配到
- Out[40]: <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- In [38]: bs.find('li',recursive=True) #递归查找,能够匹配到li对象
text参数----可以搜索文档中匹配的内容,和name参数一样,有字符串、正则、列表这3种形式
- In [41]: bs.find(text='first item') #查找字符串,需要传入完整内容,否则无法匹配
- Out[41]: 'first item'
- In [42]: bs.find(text=re.compile(r'item'))#查找第一个包含item的内容
- Out[42]: 'first item'
- In [43]: bs.find(text=re.compile(r'ir'))#查找第一个包含ir的内容
- Out[43]: 'first item'
- In [44]: bs.find(text=['second item','third item']) #查找内容为second item或third item的第一个内容
- Out[44]: 'second item'
- In [41]: bs.find(text='first item') #查找字符串,需要传入完整内容,否则无法匹配
其它关键字参数----关键字为属性名,但是注意不能直接传入和python关键字重名的class属性,需要在class后面加上下划线,即修改为"class_"
- In [45]: bs.find(id='first') #id属性作为关键字参数进行查找
- Out[45]: <li class="item-0" id="first"><a href="link1.html">first item</a></li>
- In [43]: bs.find(href='link4.html') #href属性作为关键字参数进行查找
- Out[43]: <a href="link4.html">fourth item</a>
- In [44]: bs.find(class='item-inactive') #和python关键字class重名的class属性则会报错
- File "<ipython-input-42-a9ab4a3f6cee>", line 1
- bs.find(class='item-inactive')
- ^
- SyntaxError: invalid syntax
- In [45]: bs.find(id='first') #id属性作为关键字参数进行查找
find_all(self, name=None, attrs={}, recursive=True, text=None,**kwargs)----以列表的形式返回所有能够匹配到的对象,所有参数用法同find()方法
- In [45]: bs.find_all('li') #查找所有的li标签
- Out[45]:
- [<li class="item-0" id="first"><a href="link1.html">first item</a></li>,
- <li class="item-1"><a href="link2.html">second item</a></li>,
- <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>,
- <li class="item-1"><a href="link4.html">fourth item</a></li>,
- <li class="item-0"><a href="link5.html">fifth item</a></li>]
- In [46]: bs.find_all('li',attrs={"class":"item-1"}) #查找所有的li标签,并且class属性为item-1
- Out[46]:
- [<li class="item-1"><a href="link2.html">second item</a></li>,
- <li class="item-1"><a href="link4.html">fourth item</a></li>]
- In [45]: bs.find_all('li') #查找所有的li标签
get()方法----获取对象的特定属性
- In [47]: bs.li.get('class') #class属性因为可以有多个,所以返回的是列表形式
- Out[47]: ['item-0']
- In [48]: bs.find(attrs={"class":"item-0"}).get('id') #以字符串的形式返回id属性值
- Out[48]: 'first'
- In [49]: bs.find_all('a')[1].get('href')
- Out[49]: 'link2.html'
- In [47]: bs.li.get('class') #class属性因为可以有多个,所以返回的是列表形式
get_text()方法----获取标签里面的内容,同string属性返回的结果一样
- In [50]: bs.li.get_text() #获取第一个li最里面的内容
- Out[50]: 'first item'
- In [51]: bs.find(attrs={"class":"bold"}).get_text() #获取class属性为bold标签(即span标签)里面的内容
- Out[51]: 'third item'
- In [52]: bs.find_all('a')[3].get_text() #获取第4个a标签里面的内容
- Out[52]: 'fourth item'
- In [50]: bs.li.get_text() #获取第一个li最里面的内容
select()方法----css选择器,同find_all方法有点类似,返回的是列表
通过标签名查找
- In [53]: bs.select('li') #查找所有li标签
- Out[53]:
- [<li class="item-0" id="first"><a href="link1.html">first item</a></li>,
- <li class="item-1"><a href="link2.html">second item</a></li>,
- <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>,
- <li class="item-1"><a href="link4.html">fourth item</a></li>,
- <li class="item-0"><a href="link5.html">fifth item</a></li>]
- In [53]: bs.select('li') #查找所有li标签
通过类名查找,类名前加上'.'
- In [54]: bs.select('.bold') #查找class='bold'的标签
- Out[54]: [<span class="bold">third item</span>]
- In [54]: bs.select('.bold') #查找class='bold'的标签
通过id查找,id前加上'#'
- In [55]: bs.select('#first') #查找id为first的标签
- Out[55]: [<li class="item-0" id="first"><a href="link1.html">first item</a></li>]
- In [55]: bs.select('#first') #查找id为first的标签
混合查找
- In [56]: bs.select('.item-0 a') #查找class="item-0"下的a标签
- Out[56]: [<a href="link1.html">first item</a>, <a href="link5.html">fifth item</a>]
- In [57]: bs.select('#first a') #查找id="first"下面的a标签
- Out[57]: [<a href="link1.html">first item</a>]
- In [58]: bs.select('ul span') #查找ul下面的span标签
- Out[58]: [<span class="bold">third item</span>]
- In [59]: bs.select('ul>span') #标签后面带上">"表示直接子标签,因为span标签不是ul的直接子标签,所以匹配不到
- Out[59]: []
- In [60]: bs.select('a>span') #span标签是a标签的子标签,所以能匹配到
- Out[60]: [<span class="bold">third item</span>]
直接子标签查找,则使用
>
分隔- In [56]: bs.select('.item-0 a') #查找class="item-0"下的a标签
通过属性查找
- In [61]: bs.select('li[class="item-inactive"]') #查找class属性为'item-inactive'的li标签
- Out[61]: [<li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>]
- In [62]: bs.select('a[href="link2.html"]') #查找href属性为'link2.html'的a标签
- Out[62]: [<a href="link2.html">second item</a>]
- In [61]: bs.select('li[class="item-inactive"]') #查找class属性为'item-inactive'的li标签
爬虫-使用BeautifulSoup4(bs4)解析html数据的更多相关文章
- Python爬虫教程-18-页面解析和数据提取
本篇针对的数据是已经存在在页面上的数据,不包括动态生成的数据,今天是对HTML中提取对我们有用的数据,去除无用的数据 Python爬虫教程-18-页面解析和数据提取 结构化数据:先有的结构,再谈数据 ...
- bs4解析库
beautifulsoup4 bs4解析库是灵活又方便的网页解析库,处理高效,支持多种解析器.利用它不用编写正则表达式即可方便地实现网页的提取 要解析的html标签 from bs4 import B ...
- pytho爬虫使用bs4 解析页面和提取数据
页面解析和数据提取 关注公众号"轻松学编程"了解更多. 一般来讲对我们而言,需要抓取的是某个网站或者某个应用的内容,提取有用的价值.内容一般分为两部分,非结构化的数据 和 结构化的 ...
- 爬虫的三种解析方式(正则解析, xpath解析, bs4解析)
一 : 正则解析 : 常用正则回顾: 单字符: . : 除换行符以外的所有字符 [] : [aoe] [a-w] 匹配集合中任意一个字符 \d : 数字 [0-9] \D : 非数字 \w : 非数字 ...
- 爬虫的两种解析方式 xpath和bs4
1.xpath解析 from lxml import etree 两种方式使用:将html文档变成一个对象,然后调用对象的方法去查找指定的节点 (1)本地文件 tree = etree.parse(文 ...
- 爬虫-使用lxml解析html数据
使用lxml之前,我们首先要会使用XPath.利用XPath,就可以将html文档当做xml文档去进行处理解析了. 一.XPath的简单使用: XPath (XML Path Language) 是一 ...
- python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容
python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容 Beautiful Soup 是用Python写的一个HTML/XML的解析器,它可以很好的处理不规范标记并生成剖 ...
- Python爬虫之Beautiful Soup解析库的使用(五)
Python爬虫之Beautiful Soup解析库的使用 Beautiful Soup-介绍 Python第三方库,用于从HTML或XML中提取数据官方:http://www.crummv.com/ ...
- python爬虫实战:基础爬虫(使用BeautifulSoup4等)
以前学习写爬虫程序时候,我没有系统地学习爬虫最基本的模块框架,只是实现自己的目标而写出来的,最近学习基础的爬虫,但含有完整的结构,大型爬虫含有的基础模块,此项目也有,“麻雀虽小,五脏俱全”,只是没有考 ...
- 爬虫系列 | 6、详解爬虫中BeautifulSoup4的用法
bs4,全称BeautifulSoup 4 , 它是Python独有的一种解析方式.也就是说只有Python语言才可以通过这种方式去解析数据. BeautifulSoup 3 只支持Python2,所 ...
随机推荐
- web 前端工具: Gulp 使用教程
1 1 1 Gulp 使用教程: 1 1 1 1 1 1 1 1 ERROR: ./app.js 当前目录路径: ./ 当前目录路径: ./ 1 1 1 1 1 参考资源: http://webpac ...
- React Refs All In One
React Refs All In One https://reactjs.org/docs/react-api.html#refs Ref https://reactjs.org/docs/refs ...
- chroot vs docker
chroot vs docker chroot Linux A chroot on Unix operating systems is an operation that changes the ap ...
- MDN & JavaScript 文档翻译状态
MDN & JavaScript 文档翻译状态 https://developer.mozilla.org/zh-CN/docs/MDN/Doc_status/JavaScript refs ...
- NGK生态之星空计划启动在即,稀有VAST高兑换比带来高价值!
NGK生态之星空计划启动在即,为了感谢NGK布道者的支持,NGK官方将全力辅助算力市场,开展全新的星空计划,并发行星空币SPC,空投给算力持有者进行额外奖励. 至此,SPC已经顺利完成2轮空投,也初步 ...
- NGK公链:通用型存储网络
NGK公链,是一条发展中的通用型存储网络. NGK的运用归结与存储场景.NGK通证的运用归结于支付场景.个人数据被中心化服务商买卖.被大数据服务商使用.被无数的商务及销售人员窃取.那么NGK的运用场景 ...
- 开发Microsoft Teams选项卡应用安全注意事项
我们都知道,为了方便广大的开发人员快速开发Microsoft Teams选项卡应用,微软提供了一个JS SDK,你可以通过这里 https://docs.microsoft.com/en-us/jav ...
- 使用python编写量子线路打印的简单项目,并使用Sphinx自动化生成API文档
技术背景 该文章一方面从量子线路的打印着手,介绍了一个简单的python量子线路工程.同时基于这个简单的小工程,我们顺带的介绍了python的API文档自动化生成工具Sphinx的基本使用方法. 量子 ...
- Hyperf-事件机制+异常处理
Hyperf-事件机制+异常处理 标签(空格分隔): php, hyperf 异常处理器 在 Hyperf 里,业务代码都运行在 Worker 进程 上,也就意味着一旦任意一个请求的业务存在没有捕获处 ...
- Newbe.Claptrap 框架入门,第一步 —— 开发环境准备
Newbe.Claptrap 框架依托于一些关键性的基础组件和一些可选的辅助组件.本篇我们来介绍一下如何准备一个开发环境. Newbe.Claptrap 是一个用于轻松应对并发问题的分布式开发框架.如 ...