整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

BeautifulSoup库的上行,下行,平行遍历

BeautifulSoup库的上行,下行,平行遍历
1、上行遍历即查找自己的父节点或者先前节点
2、下行遍历即查找自己的子节点或者孙节点
3、平行遍历即查找跟自己平行的节点,必须发生在同一个父亲节点下
#本代码演示BeautifulSoup的上行遍历,下行遍历,平行遍历,代码如下:
#1、导入相应的模块
import requests
from bs4 import BeautifulSoup
#2、对网站进行get请求
url="http://huizhou.loupan.com" #设置网站为惠州楼盘网
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"} # 设置网页请求头
response=requests.get(url,headers=headers) ##伪装浏览器对url进行get请求
response.encoding=response.apparent_encoding #根据网页内容进行解析编码并赋值给response.encoding
html=response.text #将响应的网页源代码赋值给html
#3、对网站进行解析
soup=BeautifulSoup(html,"html.parser")
print(soup.a) #打印a标签
print(soup.head) #打印head标签
print("head标签的儿子标签:",soup.head.contents) #打印head标签的儿子标签
print("a标签的父节点:",soup.a.parent) #打印a标签的父节点,即上行查找
print(soup.a.parent.parent) #打印a标签的父节点的父节点,即上行查找祖先节点
print("a标签的先前节点:",soup.a.parents) #打印a标签的先前节点,即上行查找先前节点,包含父节点,也包含祖先节点
print("a标签的下一个平行节点:",soup.a.next_sibling) #查找a标签的下一个平行节点
print("div标签的上一个平行节点:",soup.div.previous_sibling) #查找div标签的上一个平行节点
print("a标签的儿子节点:",soup.a.children) #打印a标签的儿子节点,返回迭代类型
print(soup.a.contents) #打印a标签的儿子节点,返回列表类型
print("body标签的子孙节点:",soup.body.descendants) #打印body标签的子节点和孙节点

码运行结果如下图所示:

虫的基本框架是获取HTML页面信息,解析页面信息,保存结果;bs4库主要是解析、遍历、提取页面信息;bs4将复杂的HTML文档转化为一个树形结构,每个节点都是一个Python对象,这些对象可以分为四类:Tag,NavigableString,Comment,BeautfifulSoup

Tag:标签,是最基本的信息组织单元,对应HTML原生文档的tag,Tag的两个基本属性是name和attributes;

BeautfifulSoup:表示的是一个文档的全部内容,大部分时候可以把它当成Tag对象,但并不是真正的HTML的tag,因此没有name和attribute属性,但可以用.name来查看它的名字“[document]”

NavigableString:标签内非属性字符串,<>-<\>内的字符串;

Coment:Comment对象时一个特殊的NavgableString对象,表示HTML文档的注释部分,使用特殊的格式输出(prettify()):

例子:

from bs4 import BeaufifulSoup 
soup=BeautifulSoup(
tag=soup.title 
tag.name # 可以获得tag 的name :'title'
tag.attrs #获取属性:{},这个例子是空值
tag['class']='for example' #可以根据字典形式添加属性
tag.attrs #再获取属性就是{‘class’: 'for example'}
print(tag) #现在打印tag就可以得到:title class="for example">网易</title>

遍历文档树:

下行遍历:

1.contents:子节点的列表,把所有<tag>的所有子节点都存入列表;

2.children:子节点的迭代类型,与contents类似,遍历子节点;

3.descendants:子孙节点的迭代类型,包含所有子孙节点,用于循环遍历;

上行遍历:

1.parent:获取某元素的父亲节点;

2.parents:迭代得到元素的所有父辈节点,用于循环遍历先辈节点;

平行遍历:

1.next_sibling:返回按照HTML文档顺序的下一个平行节点标签

2.nex_siblings:迭代类型,返回按照HTML文档顺序的后续所有平行节点标签;

3.previous_sibling: 返回按照HTML文档顺序的上一个平行节点标签

4.previous_siblings: 迭代类型,返回按照HTML文档顺序的前面所有平行节点标签;


验说明与环境准备

在开始本次实验之前请先完成 Python 爬虫 1-Requests 库入门与实战 实验

如果你尚未完成 Python 爬虫 1-Requests 库入门与实战 实验,请查看教程相关说明,之前的内容将作为本次实验的基础

本次实验需要你懂得 html 标签的基本用法

在本教程中 bs4 库是 Beautiful Soup4 库的简写

实验建议:

为保证实验高效进行,请:

实验过程中使用 ubuntu 用户,请勿切换至 root 用户

文件命名,目录设定请遵循教程要求

调整命令窗口大小到合适的大小

戒骄戒躁,保持良好的心态开始本次实验

环境准备

环境与实验一环境相同,这里直接给出指令,这并不是教程的重点,你可以逐行复制到命令提示框中运行。

sudo apt-get updatesudo apt-get install python3 python3-pip -ypip3 install requests

安装 Beautiful Soup 库

关于 Beautiful Soup 库

Beautiful Soup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库

我们在本次实验中使用到的解析器为 html.parser, 无需单独安装。

这里给出其他一些解析器,了解他们的用法请查阅相关库说明。

lxml:lxml 的 HTML 解析器 Beautiful Soup

xml:lxml 的 XML 解析器 Beautiful Soup

html5lib:html5lib 的解析器 Beautiful Soup

解析器的选择

Beautiful Soup 支持的解析器有以上几种,如何选择是我们面临实际问题时应该思考的问题。这里给出各库的优缺点,在不同的环境选择不同的解析器是很重要的。

标准库解析器 html.parser, 执行速度适中,文档容错能力强,但 Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差

lxml 和 xml 解析器都有着速度快的优点,但需要安装C语言库,xml 解析器是唯一支持 XML 的(官方文档中最推荐使用 lxml 解析器)

html5lib 解析器有最好的容错性,以浏览器的方式解析文档,能生成 HTML5 格式的文档,但速度也是最慢的

Beautiful Soup 库的安装

使用 pip 安装

如果你需要使用其他方式安装,请参阅官方文档(中文)或官方文档(英文)。

pip3 install beautifulsoup4

!!!请注意这里是 beautifulsoup4 而不是 Beautiful Soup

pypi 中的 Beautiful Soup 是 Beautiful Soup 3版本,不是我们所需要的 bs4 版本

Beautiful Soup 库的使用

从这里开始,请按教程提示完成操作,以便检查器能正确识别您的操作。

温故而知新

百度主页爬虫

让我们回顾一下百度首页(http)的爬取,在用户目录下创建 task1.py, 完成百度主页的爬取程序,不需要输出任何内容。

推荐自行编写,如果有一定困难,可以参考示例程序

请点击 编辑 task1.py,按 Ctrl+S 可以保存

示例代码:/home/ubuntu/task1.py

import requestsurl="http://www.baidu.com"res=requests.get(url)res.encoding=res.apparent_encoding

尝试运行

python3 task1.py

没有任何报错那么我们可以进行下一步

在 Python 命令行中使用 Beautiful Soup 库

在这一部分如果你遇到了无法解决的问题,可以尝试 Ctrl+D 或在 Python 命令行中输入 exit() 来退出命令行,退出后查看教程检查器根据你之前的输出给出的判定

让我们先把之前的程序放一放,打开 Python 命令行

python3

导入 requests 库并从 bs4 库中导入 Beautiful Soup 函数

import requestsfrom bs4 import BeautifulSoup

请注意这里的库是 bs4

完成百度首页的爬取

res=requests.get("http://www.baidu.com")res.encoding="utf-8"

这里给出简便的写法

Beautiful Soup 解析网页

我们先用一个变量来存放爬取到的页面内容

t=res.text

用 Beautiful Soup 进行解析

soup=BeautifulSoup(t,"html.parser")

P.S.如果要使用其他解析器在这里更改就对了

Beautiful Soup 解析后可以用美观的方式输出 html 页面

soup.prettify()

是不是与之前直接输出 text 要看着更好一些呢?

换行符被加上,部分页面格式变得规范,在一定程度上增加了可读性

标签和标签树

Beautiful Soup 库到底是一个什么库?

它的最重要的作用并不是解析 html 页面,从之前的内容你也许也能意识到解析网页并不是 bs4 库所擅长的,很多时候需要其他库的协同工作。

那么 bs4 库是用来干什么的呢?你可能会听到这么一种回答:解析、遍历、维护“标签树”的功能库

HTML 标签

完成 html 标签的操作你需要先了解 html 标签的基本内容,你可以参考 w3cschool 上的相关介绍了解标签的具体用法。

标签树

标签树并不是一个严谨的说法,但用树的概念能方便我们理解对它的操作

标签相关 Part1

页面获取

请打开命令行,导入 requests 库和 bs4 库再次完成对百度主页的爬取,如果你尚未关闭之前打开的命令行,那么可以直接继续操作

python3

在命令行内:

import requestsfrom bs4 import BeautifulSoupres=requests.get("http://www.baidu.com")res.encoding='utf-8'soup=BeautifulSoup(res.text,'html.parser')

查看标签

标签是 HTML 中段落的标签

soup.p

看看能得到什么

关于百度 About Baidu

只有一个标签里的内容被输出了出来,但我们知道,百度首页不止这一个 p 标签

在 Python 命令行中执行

soup.find_all('p')

查看输出,所有

标签都被输出了出来,并且是以一个列表的形式

进一步尝试

既然 find_all 返回的是一个列表,那么就可以方便的把它用到循环里

for i in soup.find_all('a'): print(i)

这样就依次输出了所有的 标签

Part2

我们已经得到了所有 标签的内容,但一个问题摆在我们面前,并不是所有的这样的标签都是我们所需要的

那么如何从中进行筛选,请先根据示例完成,之后再来学习相关知识

for i in soup.find_all('a',attrs={"class":"mnav"}): print(i.string + ' ' + i.attrs['href'])

得到的输出是这样的:

新闻 http://news.baidu.comhao123 http://www.hao123.com地图 http://map.baidu.com视频 http://v.baidu.com贴吧 http://tieba.baidu.com

这样就达到了这样一个目的,从网页中提取类为 mnav 的标签,并输出了标签文字部分和 href 属性内容

举一反三

请依据之前的内容在此基础上继续完成:

*输出所有

标签中所包含的文字信息

完成后请使用 exit() 或 Ctrl+D 退出 Python 命令行

Part3

有了前面的内容,让我们了解一下 Beautiful Soup 的一些基本元素

Name

标签的名字,

的Name是 'p', .name

Attributes

标签的属性,字典形式组织,.attrs

你可以用如同上面的例子一样操作字典的方式来操作标签的属性

NavigableString

标签内非属性字符串,.string

.text 也能起到类似效果

Comment

标签内字符串的注释部分,一种特殊的Comment类型,可以处理 中的数据

Part4(选)

本部分介绍标签遍历方法,需要你对数图有一定了解,如果你觉得这一部分难以理解,可以暂时忽略

你可以在学习数据结构相关知识后再进行学习,在此之前,你可以通过 find_all 全遍历再配合条件判断能实现相同的功能

下行遍历

.contents 子节点的列表,将 所有子节点存入列表

.children 子节点的迭代类型,与 .contents 类似,用于循环遍历子节点

.descendants 子孙节点的迭代类型,包含所有子孙节点,用于循环遍历

上行遍历

.parent 父节点

.parents 父节点标签迭代,用于循环遍历父节点

平行遍历

.next_sibling 返回按照 HTML 文本顺序的下一个平行节点标签

.next_siblings 迭代类型,返回按照 HTML 文本顺序的后续所有平行节点标签

.previous_sibling 返回按照 HTML 文本顺序的上一个平行节点标签

.previous_siblings 迭代类型,返回按照 HTML 文本顺序的前续所有平行节点标签

值得注意的一些事

注意:bs4 库将任何 HTML 输入都变成 utf‐8 编码

当你在实际爬取页面过程中,编码往往不总是 utf-8, 对于编码的处理就非常关键

建议如果您对编码处理了解的并不全面,可以再次复习Python编码解码部分内容。

在解决遇到的问题过程中进行学习也是很有效的

爬虫实战:云+社区专栏文章

实战要求

在这一部分教程会给出一定的提示,请尝试自行完成,如果有很难理解的地方,可以参考示例代码

为了方便多次修改与调试,你可以在用户目录下,创建并打开task2.py 在其中编写(注意使用 Python3 环境运行),当然也可以直接在Python命令行

提示:

文章标题位于 com-article-panel-title 类的

标签下的 标签里

标签的使用可以嵌套,如你可以使用类似 soup.h3.a 这样的方式选择在

标签里的 标签

参考代码

示例代码:/home/ubuntu/task2.py

import requestsfrom bs4 import BeautifulSoupurl="https://cloud.tencent.com/developer/column/2061"res=requests.get(url)res.encoding=res.apparent_encodingsoup=BeautifulSoup(res.text,'html.parser')for h3 in soup.find_all('h3',attrs={"class":"com-article-panel-title"}): print("https://cloud.tencent.com" + h3.a.attrs['href']) print(h3.a.string,end="\n\n")

Python 爬虫未完待续

简要回顾

至此,你已经有了爬取一个网页并从中提取信息的能力,利用 Python 爬虫能给我们带来很多便利

再次我需要再次提醒正在实验的各位,爬虫有利有弊,很多网站所有者并不喜欢爬虫,爬虫也会给网站带来运维压力

如果涉及到企业数据、隐私相关信息,无限制的爬取甚至需要承担一定的责任

同时请不要在非学习交流为目的情况下爬取网站 robots 协议所禁止爬取的内容

当我们完成了这些,还有一些问题困扰着我们

Beautiful Soup 库能方便的处理网页标签

但是 HTML 是很宽松的语言,经常会发现网页并不严格按照标签的规范来完成,或者你想要的信息所在的标签没有简单的定位方式

你所知道的只有你所需要信息的格式,那么该怎么办?

这时候就需要我们配合正则表达式库来完成我们的任务了