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 是很宽松的语言,经常会发现网页并不严格按照标签的规范来完成,或者你想要的信息所在的标签没有简单的定位方式
你所知道的只有你所需要信息的格式,那么该怎么办?
这时候就需要我们配合正则表达式库来完成我们的任务了
*请认真填写需求信息,我们会在24小时内与您取得联系。