这是上周五在微信群里看到的问题:

之前曾尝试过对知乎和微博热榜的简单爬虫,算是小有经验但仍需锻炼,于是趁着这个机会,主动包揽了爬虫代码,并在这回顾整理一番。

对于爬虫的概念,往复杂说会涉及很多技术点,但最核心的点很简单:爬虫就是按照我们给定的规则自动去网上把数据抓取下来。对应到上面的需求,想统计当地所有医院的信息,同时已经筛选好相关网站了,那么我们只要对应其网站对抓取数据的过程进行设计编码,即可最终实现爬虫任务。

#1 初步探索

那首先,我们先去瞅瞅要爬的网站什么样。对方选定的是家庭医生在线网,想要获取网站上列出的所有西安地区医院的信息。

# 家庭医生在线网、陕西西安地区链接
https://yyk.familydoctor.com.cn/area_305_0_0_0_1.html

通过链接,我们点开的网页如下:

网页展示面向的对象是人,它的设计是方便观众点击浏览。那么传统方式上我们如果想统计这些数据,就可以逐个点开来复制粘贴汇总到一起。

但爬虫是由计算机实现的,它并不需要这些加过装饰、设计的页面,它只关心其中最重要的数据。我们既然要为爬虫制定规则,那么直接围绕着页面的代码和数据来进行分析是最高效的。

右键点击页面,选择“显示网页源代码”:

刚我们提到网页对数据进行装饰设计,网页源代码所展示的就是网页如何通过前端代码(HTML,JavaScript,CSS)加工数据的过程;而爬虫要做的就是在这些代码中提取出目标数据。既然加工数据应用到了前端语言,那么爬虫自然也需要些前端基础才好操作。

比如上图中,当我们下拉到 1369 行时看到了第一组目标数据:从莲湖区到高陵县,每个地区前面的 href="链接" 都对应了各地区的链接。因为我们想要获取西安本地所有医院信息,那么西安所有地区的医院名单肯定是要抓取的。当然,我们也可以继续向下看,页面中针对不同地区列举了相应的具体医院信息。但这些数据都只是摘要,且页面中并没有完全展示所有医院信息,所以我们先忽略这些不全的具体数据,目光回到刚刚收集到的地区链接上。

我们点开莲湖区的链接 ,同样查看网页源代码,向下翻找有用信息。

#莲湖区链接
https://yyk.familydoctor.com.cn/area_305_0_0_0_1.html

翻找过程可以比对着页面中所展示的医院信息来快速定位,很快我们发现 2197 行开始,正是对“西安市红会医院”信息的展现。但别高兴太早,我们想要的信息是医院名称、医院地址、医院等级以及咨询电话,但很不凑巧,信息中缺失了医院地址。眼尖的话可以看到“西安市红会医院”字样前面还有个链接,没错,这就是具体到该医院的专页了,我们继续打开搜寻。

# 西安市红会医院链接
https://yyk.familydoctor.com.cn/17097/

这下数据比较清晰了,473行源代码开始,我们想要的医院类型、等级、地址、咨询电话逐一列在眼前,把这些数据取到任务就完成了。

#2 设计爬虫规则

探索完整个过程,接下来我们要按照相应的流程来进行编码设计。上述过程可以分解为三步:

  1. 在最初给定的陕西西安的链接中获取各地区链接

  2. 通过每个地区链接,获取该地区每家医院的专页链接

  3. 通过医院的专页链接,抓取医院的具体信息

具体的爬虫代码实现规则,则要依赖 requests 库,该库如其名是一个常用的 http 请求库,用来发起 http 请求并获取响应结果,整个过程出奇简单:

# 导入 requests 库
import requests
# 模拟 headers
headers = {"User-Agent":"","Cookie":""}
# 最初的西安医院链接
xian_url="https://yyk.familydoctor.com.cn/area_305_0_0_0_1.html"
# 通过 requests 的 get 获取访问链接返回结果
content = requests.get(xian_url,headers=headers)
# 打印返回结果
print(content.text)

通过 requests.get() 获取到的返回结果与我们在网页上查看源代码大致差不多,下图是我运行代码获取的结果:

接下来是通过 BeautifulSoup 库来对获取的返回结果进行解析,简单说就是它可以根据代码的规则便捷定位提取我们的目标数据。

# 导入 BeautifulSoup
from bs4 import BeautifulSoup
# 使用该库解析上面代码中得到的返回结果 content
xian_soup = BeautifulSoup(content.text,"html.parser")
# 根据返回结果中特定的代码位置找到相应的数据
target = xian_soup.find("div",class_="selection")
# 找到所有的地区
area_list = target.find_all("li")[1:]
# 为不同地区新建字典用于后续储存
area_dict={}
# 对获取到的地区进行遍历
for area in area_list:# 首先拿到地区名字area_name = area.get_text(strip=True)print (area_name)# 获取该地区前面对应的链接print (area.a["href"])area_dict[area_name]=area.a["href"]
# 输出地区字典
print(area_dict)

运行代码,我们获得如下打印的结果:

这样我们拿到了第一步中西安各地区对应的链接。接下来我们同样是继续用 requests 和 BeautifulSoup 对各地区链接进行请求与解析,拿到地区内所有医院对应的链接。这里要注意的是,同一地区内所有的医院一个页面可能展示不完,这时要对后续页面进行请求获取。

因为每个地区都会重复这个获取过程,我们可以将该过程写成一个函数:

# 给出地区链接 zone_url 和用来存医院链接d额字典 hospital_dict
def get_hospital(zone_url, hospital_dict):headers2 = {"User-Agent": "", "Cookie": ""}# 通过 requests 库获取地区链接的返回结果zone_content = requests.get(zone_url, headers=headers2)# 通过 BeautifulSoup 来解析返回结果zone_soup = BeautifulSoup(zone_content.text, "html.parser")# 定位到医院链接位置zone_target = zone_soup.find_all("div", class_="listItem")# 接下来将筛选出的医院链接存到 hospital_dict 字典中for item in zone_target:name = item.a.get_text(strip=True)# print(name)a_label = item.find_all("a")[0]# print(a_label['href'])hospital_dict[name] = a_label['href']# print()# 检测是否存在下一页next_url = Nonenext_page = zone_soup.find("div", class_="endPage")if next_page:next_link = next_page.find("a", class_="next")if next_link:next_url = next_link["href"]# 将获取到的医院链接地址字典和下一页的检测结果返回return hospital_dict, next_url

针对每个地区,我们都使用该函数进行相应地操作,如果该地区存在第二页,则继续调用该函数对下一页进行提取:

hospitals = {}
for zone in area_dict:hospitals,next_page = get_hospital(area_dict[zone],hospitals)# 如果存在下一页while next_page:# 继续使用该函数进行提取hospitals,next_page = get_hospital(next_page,hospitals)print(f"{zone} 医院信息已获取完毕...")
# 最终打印所有的地区链接字典
print(hospitals)

拿到所有医院对应的专页链接后,我们继续用 requests 和 BeautifulSoup 来请求和解析,从中提取我们想要获取的医院信息。通常我们都会将结果结果存入 Excel 表格中,那么就需要相应的库比如 pandas 来将数据写入 Excel 表格。

import requests
from bs4 import BeautifulSoup
from pandas import DataFrameexcel_dict={}
df = DataFrame(columns=["医院名称","医院类型","医院等级","医院地址","咨询电话"])
for hospital in hospitals:print("医院名称:",hospital)hospital_link=hospitals[hospital]headers = {"User-Agent":"","Cookie":""}hospital_info = requests.get(hospital_link,headers=headers)hospital_soup = BeautifulSoup(hospital_info.text,"html.parser")temp = hospital_soup.find_all("div",class_="introPic")if temp:hospital_intro = temp[0]#print(hospital_intro)detail = hospital_intro.find_all("dl")#print(detail)temp_dict={}for subitem in detail:title = subitem.dt.get_text(strip=True)if "医院地址" in title:answer = subitem.dd.get_text(strip=True)[:-4]else:answer = subitem.dd.get_text(strip=True)temp_dict[title]=answerprint(title,answer)excel_dict[hospital]=temp_dictprint(temp_dict)# 将目标数据存入 df 数据结构中df=df.append({"医院名称":hospital,"医院类型":temp_dict["医院类型:"],"医院等级":temp_dict["医院等级:"],"医院地址":temp_dict["医院地址:"],"咨询电话":temp_dict["咨询电话:"]},ignore_index=True)print("======================")print(df)
# 将数据写入 result.xls 表格
df.to_excel("result.xls")
print("结果写入 result.xls")

将以上步骤串联起来,运行代码,即可得到最终爬虫结果:

#3 过程回顾

由于整个过程经过三轮请求、解析返回结果,导致代码运行时间较长,从获取到的表格数据中看,总共拿到了 219 条数据,但代码运行时长 6 分钟(最快一次)到 20 分钟(最慢一次)。时间长度也取决于网络状况,毕竟要全部请求并解析完才会出结果。

因为整个过程比较长,且前后依赖性较强,我并没有用 Pycharm 在一份 py 代码中来编辑运行,而是用 Jupyter Notebook 分步骤来步步执行的。这样执行完第一部分后,再设计第二部分时就可以直接拿第一部分的结果用,避免再跑一轮代码浪费时间。

我是采用的 pandas 库来写入表格,但运行到最后一步发现,这个写代码的电脑里装了 pandas 库却没装 xlwt 库,写入 Excel 表格的函数是依赖该库的。得出的教训就是,为了避免浪费时间,可以先准备简单的数据串一下流程。

最终写入表格时,起初我采用直接将医院数据字典转化为 DataFrame 格式,结果输出的表格行列正好反着,也是赶着最后一点完成任务,对网上关于行列互换的方法没能深入研究。为了完成任务,采用了比较简单粗暴的逐行写入 DataFrame 的方法,这个后续有机会可以再琢磨琢磨。

好久没写 Python,乍一写都有些手生了,惭愧。。

公众号后台回复 医院爬虫 可以获取 GitHub 代码下载链接,py 代码和 ipynb 代码均已上传。

以上,感谢你的阅读~

Python 爬虫统计当地所有医院信息相关推荐

  1. python爬虫获取肯德基门店信息

    python爬虫获取肯德基门店信息 1.在谷歌浏览器中打开肯德基官网,进入餐厅查询页面 2.在搜索框中输入地区并按f12打开开发者工具 发现已经抓取到了一条Ajax请求,可以从中获取请求的url,以及 ...

  2. 深圳python爬虫培训南山科技园钽电容回收_记一次python 爬虫爬取深圳租房信息的过程及遇到的问题...

    为了分析深圳市所有长租.短租公寓的信息,爬取了某租房公寓网站上深圳区域所有在租公寓信息,以下记录了爬取过程以及爬取过程中遇到的问题: 爬取代码: import requests from reques ...

  3. linux 定时任务 (python 爬虫统计博客数据)

    linux 定时任务 (python 爬虫统计博客数据) 1. 任务目标 定时任务中,每天统计一下今日博客的各项数据,并以邮件的形式发送给自己. 2. linux 定时任务 (python) 一切复杂 ...

  4. python解决租房问题_记一次python 爬虫爬取深圳租房信息的过程及遇到的问题

    为了分析深圳市所有长租.短租公寓的信息,爬取了某租房公寓网站上深圳区域所有在租公寓信息,以下记录了爬取过程以及爬取过程中遇到的问题: 爬取代码: import requests from reques ...

  5. python爬虫爬取豆瓣电影信息城市_Python爬虫入门 | 2 爬取豆瓣电影信息

    这是一个适用于小白的Python爬虫免费教学课程,只有7节,让零基础的你初步了解爬虫,跟着课程内容能自己爬取资源.看着文章,打开电脑动手实践,平均45分钟就能学完一节,如果你愿意,今天内你就可以迈入爬 ...

  6. 利用Python爬虫获取招聘网站职位信息

    当你学会使用Python爬虫之后就会发现想要得到某些数据再也不用自己费力的去寻找,今天小千就给大家介绍一个很实用的爬虫案例,获取Boss直聘上面的招聘信息,同学们一起来学习一下了. Boss直聘爬虫案 ...

  7. Python 爬虫分析豆瓣 TOP250 之 信息字典 和 马斯洛的锥子

    问题 本文是对<Python 爬虫分析豆瓣 TOP250 告诉你程序员业余该看什么书?> 一文的补充 我们以<追风少年>为例 用chrome的developer tool查看源 ...

  8. python爬虫可以爬取个人信息吗_手把手教你利用Python网络爬虫获取旅游景点信息...

    爬虫系列: 当我们出去旅游时,会看这个地方有哪些旅游景点,景点价格.开放时间.用户的评论等. 本文基于Python网络爬虫技术,以hao123旅游网为例,获取旅游景点信息. 1.项目目标 获取网站的景 ...

  9. Python爬虫之爬取车票信息

    Python爬虫之爬取所有火车站的站台信息 前面我写过一篇关于火车站站台的查询,这篇基于站台的查询写火车车票余额信息查询-- 一.信息获取: 获取请求地址: 在浏览器菜单中找到Web开发者模式,打开网 ...

最新文章

  1. Postgresql 物理热备份 -- PITR 时间点恢复(Point In Time Recovery)
  2. 先给自己定个小目标,比如写个爬虫程序
  3. 【BZOJ 1266】 [AHOI2006]上学路线route
  4. 一行语句让你的浏览器变成记事本
  5. WebStorm使用教程
  6. Word插入页码简单方法
  7. 国产超级英雄逆袭好莱坞
  8. 大学生面试20个经典问题及回答思路
  9. window10 1060 caffe 安装
  10. 愚人节巧用CSS开个极客式玩笑以chrome为例
  11. SuperMap iDesktopX安装 ---(保密机:龙芯CPU+银河麒麟系统)
  12. 简单的nodejs+socket.io给指定的人发送消息
  13. GB 21551.5家用和类似用途电器的抗菌、除菌、净化功能 洗衣机的特殊要求
  14. Scala知识点21---高阶方法
  15. SDCC 2016架构运维技术峰会(成都站)启动,首批讲师披露
  16. docker desktop 运行mysql
  17. 深入理解C++中的循环引用问题及解决方法
  18. C++实验 —— CMatrix类的设计与实现
  19. 代码下载python 简体和繁体的转换
  20. 动力节点-javaweb项目入门到实战教程-下

热门文章

  1. CTrayNotifyIcon新系统托盘图标
  2. lol手游内测服务器什么时候维护好,LOL手游第二次内测开启?网友预测:正式服春节前可以上线...
  3. 堡垒之夜服务器没有响应,堡垒之夜安装不了怎么办_堡垒之夜安装不了解决方法介绍...
  4. 问题解决:opencv(python)将图片转为视频后视频无法打开问题
  5. 上周版面人气及综合利用率排名 2011-11-13
  6. Android通过屏幕方向和摄像头方向实现屏幕预览
  7. 计算机信息技术与幼儿教育论文,【幼儿教育论文】信息技术与幼儿教育的整合(共1505字)...
  8. 腾讯健康系统服务器怎么填,腾讯健康系统实名认证入口及修改方法介绍
  9. U盘插入电脑不显示怎么办 U盘插入电脑不显示解决方法【详解】
  10. 关于Proteus 8仿真STM32串口通信时显示数据错误或乱码问题解决!