学习Python爬虫(六):美味的BeautifulSoup

原创 2018年04月15日 15:41:29

BeautifulSoup4是一个可以从HTML、XML文件中提取数据的Python第三方库,你可以指定特定的解析器实现遍历、查找和修改网页数据的功能


构造BeautifulSoup对象

要解析一个HTML或XML文档,只要把它传递给BeautifulSoup的构造方法,可以以:1)字符串,2)文件句柄这两种形式进行传递

from bs4 import BeautifulSoup

""" Create a bs4 object by passing a file handle. """
with open('index.html') as fp:
    soup = BeautifulSoup(sp)

""" Create a bs4 object by passing a string. """
soup = BeautifulSoup("<html>data</html>")

BeautifulSoup会把文档转换成Unicode编码,并且HTML实体也都被转换为Unicode字符

这里写图片描述


对象的种类及其属性和方法

Tag(标签)

一个Tag对象对应一个HTML或HTML原生文档中的标签

标签对象通过soup对象.标签名获取

这里写图片描述

如果想获取所有的同名标签,使用soup对象.find_all()方法

Name(标签名)

标签名通过标签对象.name获取

这里写图片描述

Attribute(标签属性)

标签的属性往出现在xx=xx的键值对的键的位置,访问方法和字典相同,即标签名['属性名']

或者使用标签名.attrs直接访问字典

这里写图片描述

Multi-Valued Attributes(多值属性)

Python通过列表处理多值属性

这里写图片描述

需要注意的是,如果某个属性看起来有多个值但是在HTML定义中却不是一个多值属性,就以一个完整字符串形式返回(不是多值属性)

这里写图片描述

将标签转换为字符串时,多值属性会合并为一个值

使用标签名.getattribute_list('属性名')获取属性对应值列表

这里写图片描述

这里写图片描述

对应标签内包含的文本,BeautifulSoup使用Navigable类包装这些文本

使用soup对象.string获取这些文本

这里写图片描述

使用str()方法将NavigableString转换为Unicode字符串

这里写图片描述

使用标签名.string.replace_with()方法替换NavigableString
或者直接用=赋值

这里写图片描述

BeautifulSoup(美味汤对象)

BeautifulSoup对象表示一个文档的全部内容

大部分时候可以把它当成Tag对象,它支持遍历文档树和搜索文档树中描述的大部分方法

因为BeautifulSoup对象并非真正的HTML或XML标签,所以他没有name或attribute属性,但是有时查看它的name属性时很方便的,所以BeautifulSoup对象包含了一个值为'[document]'的特殊属性

这里写图片描述

Comment(注释,以及其它)

在HTML文档中以<!--注释内容-->标注的东西就是注释

它是一类特殊的NavigableString

这里写图片描述


遍历文档树

通俗的讲,遍历文档树的直接效果就是『从文档的一个位置移动到另一个位置』

这里写图片描述

为了简单起见,我们做如下前提假设:

这里写图片描述

标签树的下行遍历

获取子结点列表(返回列表)

使用tag标签名.contents获取子结点列表

这里写图片描述

获取子结点迭代器(一层迭代)

使用tag标签名.children获取子结点迭代器

用来遍历直系单层儿子结点

这里写图片描述

获取后代结点迭代器(深度递归)

使用tag标签名.descendants获取后代结点迭代器

用来遍历子孙后代结点

这里写图片描述

标签树的上行遍历

获取父亲标签

使用tag标签名.parent获取父亲标签

这里写图片描述

获取先辈标签

使用tag.parents获取先辈标签的迭代器

这里写图片描述

soup的父结点为None

soup为最高层结点,没有父亲结点(为None)

这里写图片描述

在遍历时要考虑到这一点

这里写图片描述

以上,如果parent is None,虽然不能打印parent,但是可以打印parent.name

标签树的平行遍历

注意:所有的平行遍历总是发生在同一个父结点下的哥哥兄弟结点之间!

返回上一个兄弟结点

使用tag标签.next_sibling获取按照HTML文本顺序的下一个平行结点标签

返回上一个兄弟结点

使用tag标签.previous_sibling获取按照HTML文本顺序的上一个平行结点标签

返回平行后继结点迭代器

使用`tag标签.next_siblings获取按照HTML文本顺序的所有后续平行结点标签

返回平行前驱结点标签迭代器

使用tag标签.previous_siblings获取按照HTML文本顺序的所有前面平行结点标签

回退和前进

还记得我们构造BeautifulSoup对象时要传入的第二个参数——是一个『解析器』这个解析器的作用就是自外向里逐层打开标签,在对最里层的标签解析完后再从里往外逐层关闭标签

<html><head><title>This is a Title</title></head></html>

一上面的html代码为例就是,解析器首先打开html标签,接着打开head标签,接着打开title标签,接着关闭title标签,接着关闭head标签,最后关闭html标签

BeautifulSoup提供了重现HTML文档被解析的过程的工具

返回元素

下一个元素

使用tag标签.next_element返回下一个被解析的标签

上一个标签

使用tag标签.previous_element返回上一个被解析的标签

返回迭代器

向后解析

使用tag标签.next_elements返回向后解析的迭代器

向前解析

使用tag标签.previous_elements返回向前解析的迭代器


搜索文档树

find_all()方法

find_all(name, attrs, recursive, string, limit, **kwargs)

find_all()方法遍历当前结点的所有孩子结点,找到匹配模式的标签

这里写图片描述

这里写图片描述

还可以根据CSS类名进行搜索,因为class是Python的关键字所以在BeautifulSoup中使用class_代替CSS的类名的关键字,搜索指定类名的标签

和关键字参数一样,class_也支持不同类型的过滤器:包括字符串、正则表达式、函数(定义一个函数,返回boolean类型,作为参数传给find_all()方法)或者True(所有不是字符串的东西)

将BS对象或Tag对象当成find_all()方法使用

由于find_all()是在是太常用的搜索方法,BeautifulSoup为我们提供了find_all()的简写形式:

>>> soup.find_all('p')
>>> soup('p')
>>> tag.find_all('a')
>>> tag('a')

上面两种写法前者与后者是等价的(后者是前面的语法糖)相当于为BS对象和Tag对象实现了__call__()方法

另外说明,find_all()方法看似返回一个列表

甚至可以对它的返回值进行列表的分片操作

这里写图片描述

但是在查看type(..)类型后发现,其实它是一个bs4.element.ResultSet对象才对

这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/abc_12366/article/details/79948021

Python破解有道翻译爬虫

1.课程介绍了普通的爬虫方式 2.如何攻破有道翻译的反爬虫机制 3.以及制作属于自己的GUI有道词典
  • 2017年08月14日 21:29

Python爬虫包 BeautifulSoup 学习(三) 实例

一步一步构建一个爬虫实例,抓取糗事百科的段子先不用beautifulsoup包来进行解析第一步,访问网址并抓取源码# -*- coding: utf-8 -*- # @Author: HaonanWu...
  • u013007900
  • u013007900
  • 2016-12-22 21:46:54
  • 1550

Python爬虫包 BeautifulSoup 学习(五) 实例

BeautifulSoup使用BeautifulSoup抓取豆瓣电影的一些信息。# -*- coding: utf-8 -*- # @Author: HaonanWu # @Date: 2016-...
  • u013007900
  • u013007900
  • 2016-12-24 18:08:42
  • 1212

Python爬虫之美味鸡汤-BeautifulSoup

Python爬虫之美味鸡汤-BeautifulSoup进一步学习: python3实现网络爬虫(2)–BeautifulSoup使用(1)python3实现网络爬虫(3)–BeautifulSou...
  • dongdong230
  • dongdong230
  • 2017-09-06 15:18:06
  • 473

beautifulsoup python

  • 2013年06月07日 12:36
  • 137KB
  • 下载

使用requests+beautifulsoup模块实现python网络爬虫功能

1. 前言之前实现python的网络爬虫, 主要都是使用较为底层的urllib, urllib2 实现的, 这种实现方案显得比较原始, 编码起来也比较费劲, 尤其是提取信息的时候, 还得使用正则表达是...
  • zhyh1435589631
  • zhyh1435589631
  • 2016-06-20 10:08:26
  • 8213

Python爬虫包 BeautifulSoup 学习(六) 递归抓取

之前的代码都是对单个静态页面进行抓取,这是人为简化的例子。爬虫的主要目的就是为了沿着网络抓取需要的内容。它们的本质是一种递归的过程。它们首先需要获得网页的内容,然后分析页面内容并找到另一个URL,然后...
  • u013007900
  • u013007900
  • 2016-12-25 11:09:56
  • 2883

python爬虫还在用BeautifulSoup?你有更好的选择!

1.前言 1.1 抓取网页 本文将举例说明抓取网页数据的三种方式:正则表达式、BeautifulSoup、lxml。 获取网页内容所用代码详情请参照Python网络爬虫-你的第一个爬虫。利用...
  • mifaxie
  • mifaxie
  • 2018-03-07 22:41:08
  • 161

python学习(6):python爬虫之requests和BeautifulSoup的使用

前言: Requests库跟urllib库的作用相似,都是根据http协议操作各种消息和页面。 都说Requests库比urllib库好用,我也没有体会到好在哪儿。 但是,urllib库有一点不爽的...
  • qq_32166627
  • qq_32166627
  • 2017-03-04 21:10:22
  • 3960

Python3 爬虫(八) -- BeautifulSoup之再次爬取CSDN博文

序 我的Python3爬虫(五)博文使用utllib基本函数以及正则表达式技术实现了爬取csdn全部博文信息的任务。 链接:Python3 爬虫(五) -- 单线程爬取我的CSDN全部博文 上一...
  • fly_yr
  • fly_yr
  • 2016-06-01 17:48:18
  • 11556
收藏助手
不良信息举报
您举报文章:学习Python爬虫(六):美味的BeautifulSoup
举报原因:
原因补充:

(最多只允许输入30个字)