首发于 Python爱好者社区

Python爬虫数据提取之bs4的使用方法

之前的爬虫文章中我们给大家简单介绍了一下网页的基本结构,同时也认识了一些常见的HTML标签。因为爬虫就是从这些标签中提取数据。比如以我的知乎页面为例,要想提取文章列表中的每篇文章的标题和内容简介等信息,就要读懂HTML:

我们如何解析出来HTML标签中的内容呢?解析页面局部的文本内容,一般都会在标签之间或者标签对应的属性中进行存储,我们可以通过:

首先使用开发者工具进行标签的定位,然后提取标签或者标签对应的属性中存储的数据值

常见的方式有:

  1. 正则表达式
  2. bs4
  3. xpath

正则我们已经给大家简单介绍过了,本次主要介绍bs4的使用。

关注后台回复:”bs4爬取知乎“ 获取源码

Beautiful Soup 的简介

Beautiful Soup 是 python 的一个库,最主要的功能是从网页抓取数据。官方解释如下:

Beautiful Soup 提供一些简单的、python 式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据。

因为它属于第三方库,所以需要使用pip下载安装

安装的lxml是bs4在解析过程中所要使用的一种解析器。

除了lxml之外还有:

解析器优点缺点
Python标准库Python的内置标准库、执行速度适中 、文档容错能力强Python 2.7.3 or 3.2.2前的版本中文容错能力差
lxml速度快、文档容错能力强需要安装C语言库
html5lib最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档速度慢、不依赖外部扩展

如果需要使用html5lib解析器,也是需要单独安装下载的

如何使用

无论哪种解析器都需要导入BeautifulSoup,即: from bs4 import BeautifulSoup

当使用不同的解析器时只需要改变上面代码的第二个参数即可:

推荐使用lxml作为解析器,因为效率更高。

对象的种类

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:TagNavigableStringBeautifulSoupComment

1.Tag

Tag即HTML中的标签,比如<div></div>,<p></p>,....

一个tag可能有很多个属性。比如

<a href="//zhuanlan.zhihu.com/p/137323184" target="_blank" rel="noopener noreferrer" data-za-detail-view-element_name="Title">分享几道LeetCode中的MySQL题目解法</a>

有 “href” 的属性,值为 “// zhuanlan.zhihu.com/p/13” ,有target属性,值为_blank。对于 Tag,它有两个重要的属性,是 name 和 attrs。

结果:

我们可以发现tag的属性的操作方法与字典相同,所以可以像操作字典一样操作属性。

2.NavigableString

字符串常被包含在tag内. Beautiful Soup用 NavigableString 类来包装tag中的字符串。

3.BeautifulSoup 和Comment(此部分了解即可不做举例)

BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,是一个特殊的 TagTag , NavigableString , BeautifulSoup 几乎覆盖了html和xml中的所有内容,但是还有一些特殊对象是文档的注释部分Comment。Comment 对象是一个特殊类型的 NavigableString 对象

遍历文档树

遍历文档树就是把整个文档看成一颗树形结构。如下图

见上图我们以body为例:子节点一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点。Beautiful Soup提供了许多操作和遍历子节点的属性。操作文档树最简单的方法就是告诉它你想获取的tag的name。

结果:

获取某个tag中的字标签可以使用属性:contents,返回结果是一个列表,也可以使用children属性,返回结果是一个生成器,可以通过for循环迭代输出每个子标签。如果想获取所有子孙节点可以使用:.descendants属性文本内容的获取如果想获取某个标签的文本内容可以使用.string 或者text,但是需要注意:

1.如果tag只有一个 NavigableString 类型子节点,那么这个tag可以使用 .string 得到子节点:
2.如果tag包含了多个子节点,tag就无法确定 .string 方法应该调用哪个子节点的内容, .string 的输出结果是 None .此时可以考虑使用text

结果:

None
None

但是如果换成:

结果:

我是标题
段落1链接测试

父节点

每个tag或字符串都有父节点:被包含在某个tag中。如果想获取父节点或者所有的父节点可以考虑使用 .parent 属性或者 .parents 属性

结果:

<h1>我是标题</h1>

兄弟节点

next_sibling .previous_sibling 属性: .next_sibling 属性获取了该节点的下一个兄弟节点,.previous_sibling 则与之相反,如果节点不存在,则返回 None.next_siblings .previous_siblings 属性: 通过 .next_siblings 和 .previous_siblings 属性可以对当前节点的兄弟节点迭代输出

前后节点

.next_element .previous_element 属性与 .next_sibling .previous_sibling 不同,它并不是针对于兄弟节点,可以获取到临近它的上/下一个节点,而不分层次关系。

结果:

<div>div1

<em>段落1

搜索文档树

  1. find_all( name , attrs , recursive , text , **kwargs ):find_all () 方法搜索当前 tag 的所有 tag 子节点,并判断是否符合过滤器的条件
name 参数 name 参数可以查找所有名字为 name 的 tag,当然name位置可以使用正则表达式、列表。keywords参数 即在find_all中可以跟关键字的参数部分,比如id = ‘div1’等等,但是需要注意的是**如果想用 class 过滤,不过 class 是 python 的关键词,这怎么办?加个下划线就可以即class_='xxxx'的形式,也可以通过 find_all () 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的 tag**

比如:

html结构的截图:

我们再看一个正则的例子(html内容不变):

结果:

find( name , attrs , recursive , text , **kwargs )它与 find_all () 方法唯一的区别是 find_all () 方法的返回结果是值包含一个元素的列表,而 find () 方法直接返回结果。

结果:

css样式

我们在写 CSS 时,标签名不加任何修饰,类名前加点,id 名前加 #,在这里我们也可以利用类似的方法来筛选元素,用到的方法是 soup.select(),返回类型是 list

结果:

也可以通过组合查找即和写 class 文件时,标签名与类名、id 名进行的组合原理是一样的,例如查找 p 标签中,id 等于 link1 的内容,二者需要用空格分开

在选择器中查找时还可以加入属性元素,属性需要用中括号括起来,注意属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到。

select的使用与 find_all 方法有异曲同工之妙的查找方法,是不是感觉很方便?

案例思考

爬取Running的知乎文章列表并保存到csv文件中,如何实现?

关注回复:”bs4爬取知乎“ 获取源码

系列文章

最后,推荐一套Python视频,非常适合初学者和想深入了解Python语言的小伙伴,让你学习无忧!

期待大家学习完爬虫的全部课程之后,能有一个不错的收获~~~,Good Luck!!!

深圳SEO优化公司丹竹头网站优化排名多少钱上海百搜标王报价观澜百姓网标王推广哪家好黄南优秀网站设计推荐横岗至尊标王价格承德百度爱采购价格大连优化推荐吉祥SEO按天计费报价林芝网站推广方案西乡企业网站改版公司株洲百度竞价多少钱十堰百姓网标王推广公司河源seo排名多少钱白城关键词按天收费哪家好文山建网站多少钱潮州设计公司网站宁波设计网站价格鹤岗百搜标王推荐山南阿里店铺托管厦门SEO按天收费价格楚雄营销网站价格黄石网站推广方案广安SEO按天计费公司那曲推广网站推荐临猗关键词按天收费多少钱宣城关键词按天收费公司普洱seo网站推广广元百度网站优化推荐徐州网站优化按天计费价格周口网站关键词优化多少钱歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化