首页 前端知识 03、Python爬虫——以爬取官方医院信息为例(HTML基本结构框架 正则表达式)

03、Python爬虫——以爬取官方医院信息为例(HTML基本结构框架 正则表达式)

2024-09-01 23:09:37 前端知识 前端哥 904 45 我要收藏

内容简介

本篇文章主要围绕HTML基本结构框架正则表达式基础内容进行讲解,后期将会详细对HTML结构框架进行介绍,由于本篇博客主题是爬虫,简单的普及一下HTML的基础知识。

HTML基本结构框架

由于考虑到为大家讲解知识点比较枯燥,因此在讲解HTML基本结构框架的时候将会结合医院的网页结构进行讲解

图1

根据第一张图,了解整体的框架结果,在<div class="mw-parser-output"></div>标签下,包含着需要爬取的所有信息   

可以看到<ul></ul>这个标签中包含很多<li></li>标签,在图中已经说明这两个标签的含义

图2

现在再来看打开<li></li>标签以后,在<li>标签中包含什么  

可以在图中看到含有<b>和<ul>标签   在<b>标签中存放的是医院的名称 

<li>标签中存放的是医院中的详细信息

图3

分别打开图2中的<b>和<ul>标签,可以发现<b>标签对应是这个医院的URL和医院名称

<ul>标签对应的是许多<li>标签,这个<li>标签就是分别代表了:医院地址、联系电话、医院等级等医院信息。

相信大家在这里并不是很难理解

需要注意一点的就是在医院地址、联系电话和医院等级这些医院信息的<li>标签中,心细的小伙伴可以发现在<li>标签中含有<b>标签

<li>

       <b>医院地址</b>

       :北京市东城区帅府园1号(东院)/西城区大木仓胡同41号(西院)

</li>

这里是爬取医院信息的核心,为了方便大家理解,用两种方式进行讲解

1、学过python的小伙伴应该会知道字典吧(没学过的可以直接看第二种方式),字典是由键值对构成的,这里的<b>医院地址</b>可以看做键, :北京市东城区帅府园1号(东院)/西城区大木仓胡同41号(西院)可以看做值    在数据爬取的时候,可以理解成键值对的方式进行爬取

2、Excel大家都知道吧,<b>医院地址</b>可以看做表头,:北京市东城区帅府园1号(东院)/西城区大木仓胡同41号(西院)可以看该表头下的信息    举个例子说,有一个Excel表格,A列的表头是姓名,下面对应的信息:张三、李四、王五等等  

大家可以看到在数据进行保存的时候,就是按照Excel表格的形式进行保存的

到这里,相信大家对于HTML的基本结构框架已经有一个初步的了解

正则表达式

什么是正则表达式?

正则表达式是一种用于匹配和查找文本模式的工具。 是由一系列字符和特殊符号组成的字符串,可以用来描述、识别和提取符号某种模式的文本数据。

正则表达式的语法相对复杂,但一旦掌握,就可以成为处理文本数据的强大工具

当时我进行这项工作时,系统的学习过正则表达式,但是过一段时间以后不用,就会遗忘,在我看来爬虫时,只需要牢记正则表达式几个常用的元字符即可

为了方便大家更好的去理解正则表达式,我将会依据代码带着大家着步了解代码中的正则表达式

pattern = r'<li><b><a href=".+?" title=".+?">(.+?)</b>\s*<ul>' \
          r'<li><b>医院地址</b>:(.+?)</li>\s*' \
          r'(<li><b>联系电话</b>:(.+?)</li>)?\s*' \
          r'(<li><b>医院等级</b>:(.+?)</li>)?\s*' \
          r'(<li><b>重点科室</b>:(.+?)</li>)?\s*' \
          r'(<li><b>经营方式</b>:(.+?)</li>)?\s*' \
          r'(<li><b>传真号码</b>:(.+?)</li>)?\s*' \
          r'(<li><b>电子邮箱</b>:(.+?)</li>)?'

以上这个代码就是正则表达式获取信息的全部代码,下面将会对每行代码进行分析:

第一行

pattern = r'<li><b><a href=".+?" title=".+?">(.+?)</b>\s*<ul>' \

大家首先来看这里的pattern,这个大家可以理解成正则表达式的一种方法(可以理解为一个模版,当引用这个模版的时候,就会从大量的信息中提取有用的信息) 所有绿色的代码都被赋值给pattern这个变量   (除了最后一行代码以外,其余行的代码都有 \ 进行一个换行的操作)

现在就开始代码进行详细的介绍

正则表达式是依据与HTML标签进行提取信息的:

<li><b><a href=".+?" title=".+?">(.+?(?<!<a))</b>\s*<ul>

 

这里的<li>标签就是该医院下的所有信息,<b>标签是这个医院的一个名称,大家可以看到在<b>标签中包含了一个<a>标签,这个a标签中是该医院的一个跳转超链接,<a>标签中有两个属性,分别是是href和title属性,<a href=".+?" title=".+?">,这两个属性的后方都有.+?,这个正则表达式的名称是非贪婪模式匹配符(尽可能的少匹配字符)

举个例子方便理解非贪婪   

在字符串 "abcabc" 中使用正则表达式 ".+?b",它将匹配 "ab" 而不是整个字符串。

那么在咱们代码中所需要提取的信息,并不包括href和title属性   大家就会想如果<a href=".+?" title=".+?">这样写的话,这两个属性信息是不是就被提取出来了? 答案是不是的,在正则表达式中,需要使用  ()  对正则表达式进行一个包裹,也就是说如果是(.+?)就可以将属性给提取出来了

  () 这个符号在正则表达式中称为捕获组,简单理解就是,所有需要爬取出来的信息,都需要在正则表达式的最外层加上一个捕获组  ()

还有小伙伴就想了,既然我不提取医院链接和title这个属性,我是不是可以将<a href=".+?" title=".+?">这一块代码进行删除?答案是不可以的,因为正则表达式是一个遍历的过程,如果删除这一段代码以后,那么就会自动将这一段文字全部提取出来。也就是说正则表达式是一个将无用信息使用正则表达式删除,将有用信息进行一个提取的一个过程。

下面将为大家讲解第一行代码的后半段

(.+?)</b>\s*<ul>    这一块代码依旧是结合HTML代码进行理解,在</b>之前就是对医院名称进行一个提取了  也就是下方标红的这一块代码

 (.+?)这一块代码是对:北京协和医院</a>(协和医院)  这一块信息进行的一个提取 (这里需要注意一点,(.+?)这个捕获组中,捕获了</a>这一块信息,在将所有信息全部提取来以后,再将这个</a>进行删除,后续代码中有介绍)

\s*的作用是允许匹配可能存在的空白字符,如空格、制表符、换行符等。  在上图中,可以看到在(协和医院)的末尾可以发现会有很多空白字符,因此,\s*是来匹配这些空白字符的

在第一行代码的末尾有<ul>标识着对下方医院的具体信息,进行识别开始

第二行

r'<li><b>医院地址</b>:(.+?)</li>\s*' \     

在第一行代码的末尾有<ul>说明对该医院的详细信息,开始进行爬取

每一个<li>都代表着 医院各种信息   li标签的下属b标签代表着某一项医院信息的名称

(.+?)捕获了该医院地址的具体信息    (大家有可能会好奇为什么在捕获组前会有:,如果没有这个冒号的话,在匹配的结果中,会含有:这个标识:北京市东城区帅府园1号(东院)/西城区大木仓胡同41号(西院))因此在捕获组前加上:,在最后获取信息时就不会有这个:了

第三行 

r'(<li><b>联系电话</b>:(.+?)</li>)?\s*' \     

这一行代码和第二行代码相比多了一个 ()?   是由于联系电话这个医院属性,部分医院没有联系电话,因此()?代表可选项  (要注意一点就是,这个可选项是包裹在最外围的在<li>标签的最外方)

后续代码就不再一一解释了,都和第三行代码同样的道理

下期博客将会讲解完剩余的全部代码

转载请注明出处或者链接地址:https://www.qianduange.cn//article/17497.html
标签
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!