爬虫学习笔记二:网络爬虫之提取(MOOC北京理工大学)

单元四 Beautiful Soup库入门

Beautiful Soup库的基本元素

  • Beautiful Soup库是解析、遍历、维护“标签树”的功能库(beautifulsoup4或bs4)
<p class="title">...</p>
在上面语句中,<p>...</p>:标签Tag
		     ​p:名称Name,成对出现
			 class=“title”:属性Attribute,0个或多个,属性是由键值对构成的,用来定义标签的特点
  • BeautifulSoup库引用方式:from bs4 inport BeautifulSoup
    需要对BeautifulSoup库里基本变量进行判断的时候:import bs4
  • HTML文档 <=> 标签树 <=> Beautiful Soup类
    BeautifulSoup对应一个HTML/xml文档的全部内容
  • Beautiful Soup库解析器
    ① bs4 的 HTML 解析器:BeautifulSoup(mk,“html.parser”)
    ② lxml 的 HTML 解析器(pip install lxml):BeautifulSoup(mk,“lxml”)
    ③ lxml 的 XML 解析器(同上):BeautifulSoup(mk,“xml”)
    ④ html5lib 的解析器(pip install html5lib):BeautifulSoup(mk,“html5lib”)
  • Beautiful Soup类的基本元素
    ① Tag:标签,最基本的信息组织单元,分别用<>和</>标明开头和结尾
    ② Name:标签的名字,格式:.name
    ③ Attributes:标签的属性,字典形式组织,格式:.attrs
    ④ NavigableString:标签内非属性字符串,<>…</>中字符串,格式.string
    ⑤ Comment:标签内字符串的注释部分,一种特殊的Comment类型

基于bs4库的HTML内容遍历方法

  • 标签树的下行遍历
    .contents:子节点的列表,将所有儿子节点存入列表,返回的是列表类型(下一层)
    .children:子节点的迭代类型,与.contents类似,用于循环遍历儿子节点(下一层)
    .descendants:子孙节点的迭代类型,包括所有子孙节点,用于循环遍历
for child in soup.body.children:		# 遍历儿子节点
	print(child)
	
for child in soup.body.descendants:		# 遍历子孙节点
	print(child)

  • 标签树上行遍历
    ① parent:节点的父亲标签
    ② parents:节点的先辈标签的迭代类型,用于循环遍历先辈节点
>>> soup=BeautifulSoup(open("D://demo.html"),"html.paeser")
>>> for parent in soup.a.parents:		# 对soup的a标签所有的先辈名字进行打印
		if parent in None:		# 会遍历到soup本身,soup先辈并不存在.name信息
			print(parent)		
		else:
			print(parent.name)
  • 标签树的平行遍历(发生在同一个父亲节点下的各节点间)
    ① .next_sibling:返回按照HTML文本顺序的下一个平行节点标签
    ② .previous_sibling:返回按照HTML文本顺序的上一个平行节点标签
    ③ .next_siblings:迭代类型,返回按照HTML文本顺序的后续所有平行节点标签
    ④ .previous_siblings:迭代类型,返回按照HTML文本顺序的前续所有平行节点标签
for sibling in soup.a.next_siblings:		# 遍历后续节点
	print(sibling)
	
for sibling in soup.a.previous_siblings:	# 遍历前序节点
	print(sibling)

基于表bs4库的HTML格式输出

  • .prettify()函数可以为HTML文本的标签以及内容增加换行符,也可以对每一个标签进行相关的处理
print(soup.prettify())
print(soup.a.prettify())
  • bs4库将任何读入的HTML文件或字符串都转换成了UTF-8编码

单元五 信息组织与提取方法

信息标记的三种形式

  • 信息的标记
    ​ 标记后的信息可形成信息组织结构,增加了信息维度
    ​ 标记后的信息可用于通信、存储或展示
    ​ 标记的结构与信息一样具有重要价值
    ​ 标记后的信息更利于程序理解和运用

  • HTML的信息标记
    ​ HTML通过预定义的<>…</>标签形式组织不同类型的信息

  • 信息标记的三种形式:XML、JSON、YAML

XML:扩展标记语言<name>...</name>、<name />、< !--  -->

JSON:有类型的键值对key:value构建的信息表达方式(对信息类型的定义叫键key,对信息值得描述叫值value)

"name":["北京理工大学","延安自然科学院"]		# 当值的部分有多个信息的时候用逗号分隔

键值对可以嵌套使用,如

"name":{
	"newName":"北京理工大学",
	"oldName":"延安自然科学院"
}		# 键值对嵌套{,}
YAML:无类型键值对key:value

​ 通过缩进的关系表示所属关系

​ 用”-“表达并列关系

​ ”|“表达整块数据

​ ”#“表示注释

name:北京理工大学		#仅字符串
# 键值对嵌套(通过缩进的关系表示所属关系)
name:
	newName:北京理工大学
	oldName:延安自然科学院
	
# "-"表达并列关系
name:
-北京理工大学
-延安自然科学院

# 表达整块数据/注释
text:|		# 学校介绍
多行文本

三种信息标记形式的比较

  • XML:最早的通用信息标记语言,可扩展性好,但繁琐(Internet上的信息交互与传递)

  • JSON:信息有类型,适合程序处理(js),较XML简洁(移动应用云端和节点的信息通信,无注释)

  • YAML:信息无类型,文本信息比例最高,可读性好(各类系统的配置文件,有注释易读)

信息提取的一般方法

  • 方法一:完整解析信息的标记形式,再提取关键信息
    ​ 需要标记解析器(eg:bs4库的标签树遍历)
    ​ 优点:信息解析准确
    ​ 缺点:提取过程繁琐,速度慢

  • 方法二:无视标记形式,直接搜索关键信息
    ​ 对信息的文本查找函数即可
    ​ 优点:提取过程简洁,速度较快
    ​ 缺点:提取结果准确性与信息内容相关

  • 融合方法:结合形式解析与搜索方法,提取关键信息
    ​ 需要标记解析器及文本查找函数

· 实例:提取HTML中所有URL链接

思路:1)搜索到所有<a>标签
​	  2)解析<a>标签格式,提取href后的链接内容
>>> from bs4 import BeautifulSoup
>>> soup=BeautifulSoup(open("D://demo.html"),"html.parser")
>>> for link in soup.find_all('a'):
	print(link.get('href'))

基于bs4库的HTML内容查找方法

  • <>.find_all(name,attrs,recursive,string,**kwargs):返回一个列表类型,存储查找的结果
    ​ name:对标签名称的检索字符串
    ​ attrs:对标签属性值的检索字符串,可标注属性检索
    ​ recursive:是否对子孙全部检索,默认True
    ​ string:<>…</>中字符串区域的检索字符串
soup.find_all('a')

soup.find_all(['a','b'])

for tag in soup.find_all(True):			# 显示所有的标签信息
	print(tag.name)
	
for rag in soup.find_all(re.compile('b')):		# 引入正则表达式库,打印所有b开头的标签
	print(tag.name)


soup.find_all('p','course')		#返回一个列表类型

soup.find_all(id='link1')		#返回一个列表

soup.find_all(id='link')		#返回一个空列表,因为没有link元素,要用正则表达式库

soup.find_all(id=re.compile('link'))	#用了正则表达式,返回包含link的列表


soup.find_all(string="Basic Python")
soup.find_all(string=re.compile('Python'))
  • < tag>(…)等价于.find_all(…)
    ​ soup(…)等价于soup.find_all(…)

  • find_all()方法的扩展方法
    ​ ① <>.find():搜索且只返回一个结果,字符串类型,同.find_all()参数
    ​ ② <>.find_parents():在先辈节点中搜索,返回列表类型,同.find_all()参数
    ​ ③ <>.find_parent():在先辈节点中返回一个结果,字符串类型,同.find()参数
    ​ ④ <>.find_next_siblings():在后续平行节点中搜索,返回列表类型,同.find_all()参数
    ​ ⑤ <>.find_next_sibling():在后续平行节点中返回一个结果,字符串类型,同.find()参数
    ​ ⑥ <>.find_previous_siblings():在前序平行节点中搜索,返回列表类型,同.find_all()参数
    ​ ⑦ <>.find_previous_sibling():在前序平行节点中返回一个结果,字符串类型,同.find()参数

实例:大学排名爬取

  • 输入:大学排名URL链接

  • 输出:大学排名信息的屏幕输出(排名、大学名称、总分)

  • 技术路线:requests-bs4

  • 定向爬虫:仅对输入URL进行爬取,不扩展爬取

优化

  • 当中文字符宽度不够时,采用希文字符填充;中西文字符占用宽度不同

  • 采用中文字符的空格填充chr(12288)

实例代码链接:https://blog.csdn.net/qq_44838702/article/details/104985096

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值