本篇文章是使用 Python 抓取萬家醫(yī)療上面的診所信息,并且對關(guān)鍵信息進行分析逢勾,實現(xiàn)數(shù)據(jù)可視化牡整。由于時間和能力的問題,能抓取的數(shù)據(jù)類型較少敏沉,分析的維度也不足果正。但是嘗試去剖析在國家倡導(dǎo)分級診療的大環(huán)境下炎码,移動醫(yī)療在社區(qū)診所上的發(fā)展情況盟迟。所以抓取了萬家醫(yī)療網(wǎng)站里面的診所數(shù)據(jù),并從診所區(qū)域分布潦闲、科室類型以及是否支持醫(yī)保上進行了數(shù)據(jù)分析和可視化攒菠。
<strong>準備工作</strong>
首先是開始抓取前準備工作,導(dǎo)入需要使用的庫文件歉闰,爬蟲主要使用的是requests和BeautifulSoup兩個庫辖众,數(shù)據(jù)分析主要使用 Numpy 和 Pandas 兩個庫,外加 matplotlib 庫實現(xiàn)數(shù)據(jù)可視化和敬。
<pre>import requests
from bs4 import BeautifulSoup
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
</pre>
<strong>抓取診所列表信息</strong>
在抓取前需要先觀察下萬家醫(yī)療診所列表頁面的的結(jié)構(gòu)凹炸,URL為“"https://www.pinganwj.com/clinic/pa1”,其中 ”pg1”為頁面數(shù)昼弟,共有846個頁面啤它,預(yù)計診所有8460家左右,可以使用循環(huán)遍歷所有的頁面舱痘,獲取信息变骡。
<pre>#設(shè)置 url 的前面部分
url = "https://www.pinganwj.com/clinic/"
</pre>
確定了 URL 鏈接之后,還需要設(shè)置瀏覽器頭部(headers)信息芭逝,否則系統(tǒng)會識別爬蟲程序塌碌,從而阻止訪問頁面。
<pre>#設(shè)置url的前面部分
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
'Accept':'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, /; q=0.01',
'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Accept-Encoding':'utf-8',
'Connection':'keep-alive',
'Referer':'http://www.baidu.com/link?url=_andhfsjjjKRgEWkj7i9cFmYYGsisrnm2A-TN3XZDQXxvGsM9k9ZZSnikW2Yds4s&wd=&eqid=c3435a7d00006bd600000003582bfd1f'
}
</pre>
使用 for 循環(huán)生成 1-847 的數(shù)字旬盯,轉(zhuǎn)化格式后與前面的 URL 固定部分拼成要抓取的 URL台妆。這里我們設(shè)置每兩個頁面間隔 0.5 秒。抓取到的頁面保存在 html 中胖翰。
<pre>#循環(huán)抓取列表頁信息
for i in range(1,847):
if i == 1:
i=str(i)
a=(url+'pg'+i)
r=requests.get(url=a,headers=headers)
html=r.text
else:
i=str(i)
a=(url+'pg'+i)
r=requests.get(url=a,headers=headers)
html2=r.text
html = html + html2
#每次間隔0.5秒
time.sleep(0.5)
#在頁面打印爬取進度
print ('正在爬取第'+i+"頁")
</pre>
<strong>解析頁面并提取信息</strong>
頁面爬取下來之后接剩,需要使用 BeautifulSoup 對頁面進行解析,變成我們在瀏覽器查看源代碼中看到的樣子泡态,這樣我們才能提取關(guān)鍵信息搂漠。
<pre>#使用 BeautifulSoup 解析抓取的頁面內(nèi)容
wj = BeautifulSoup(html,'html.parser')
</pre>
到目前為止,我們已經(jīng) 800+ 多個頁面的信息爬取下來某弦,并且通過 BeautifulSoup 解釋為我們常見的源代碼方式桐汤。下面就是通過分析爬取字段中 <code>Div</code>的 id 或者 class 提取關(guān)鍵信息而克。
<pre>#將診所列表中的信息保存在 hospital 中,其中 find_all 獲取的是一個 list,就是每個診所就是list上的一個對應(yīng)元素怔毛。
hospital = wj.find_all('div',attrs = {"class":"cli-list left"})
</pre>
繼續(xù)在<code>hospital</code>中提取診所名稱员萍、醫(yī)保信息、科室和地區(qū)信息拣度,將各項信息存儲到各自的<code>list</code>中碎绎。使用到的方法基本一樣,需要自行調(diào)整一下定位就好抗果。
<pre>#獲取診所名稱
hn = []
for a in hospital:
hospital_name = a.h1.get_text()
hn.append(hosptal_name)
獲取診所醫(yī)保信息
yb = []
for c in hospital:
yibao_info = c.find_all('span', attrs = {'class':'medicare'})
yibao = yibao_info
yb.append(yibao)
獲取診所科室
ks = []
for b in hospital:
keshi = b.p.get_text()
ks.append(keshi)
獲取診所地址
address = []
for d in hospital:
address_info = d.find_all('script')
address.append(address_info)
</pre>
<strong>數(shù)據(jù)分析和數(shù)據(jù)可視化</strong>
將拿到的數(shù)據(jù)使用 Pandas 庫生成數(shù)據(jù)表筋帖,方便后面分析。
<pre>#將診所名稱冤馏、醫(yī)保信息日麸、科室和地區(qū)等信息生成數(shù)據(jù)表
hospital_list=pd.DataFrame({'hospital_name':hn,'hospital_keshi':ks,'hospital_yibao':yb,'hospital_address':address})
</pre>
<strong>診所分布的省份分析:</strong>
通過使用 groupby 對診所所在省份進行匯總,通過條形圖展示每個省份的診所數(shù)量逮光。
<pre>#對每個省份的診所數(shù)量進行匯總
prov = wj.groupby('hospital_address')['hospital_address'].agg('count')
對省份數(shù)據(jù)進行排序
prov.sort_values(inplace=True)
生成省份名稱列表代箭,下面用作坐標值
prov_name=prov.index
定義圖表比例
plt.figure(figsize=(16,9))
定義圖表類型并且傳入?yún)?shù)
plt.barh(range(len(prov)),prov,tick_label=prov_name)
標注X軸的標簽
plt.xlabel(u'診所數(shù)量',fontsize ="14")
用來正常顯示中文標簽
plt.rcParams['font.sans-serif']=['SimHei']
plt.show()
</pre>
有上面的圖片可以看出,河南涕刚、河北嗡综、黑龍江三個省份的診所數(shù)量最多《拍可能的原因是萬家醫(yī)療在不同省份推廣資源的分配導(dǎo)致的极景。但是跟深層次的去考慮:為什么不是北京上海廣東這些大城市呢?其實很好理解碑幅,北京戴陡、上海、廣東可以說是中國醫(yī)療資源最密集的地方沟涨,但是這些地方都被大型三甲醫(yī)院占據(jù)恤批,民營的、小型的社區(qū)診所要發(fā)展就比較困難裹赴。
<strong>診所分布的科室類型分析:</strong>
使用相同的方式喜庞,對不同診所的科室類型進行分析,分析方法和展示形式基本一樣棋返。但是需要強調(diào)的是延都,因為有的診所擁有多個科室,所以對于這類診所睛竣,我將它們定義為綜合類型診所晰房。
<pre>#對各種科室的診所數(shù)量進行匯總
keshi = wj.groupby("hospital_keshi")["hospital_keshi"].agg("count")
對科室類型數(shù)據(jù)進行排序
keshi.sort_values(inplace=True)
生成科室名稱列表,下面用作坐標值
keshi_name=keshi.index
定義圖表比例
plt.figure(figsize=(9,6))
定義圖表類型并且傳入?yún)?shù)
plt.barh(range(len(keshi)),keshi,tick_label=keshi_name)
標注X軸的標簽
plt.xlabel(u'診所數(shù)量',fontsize ="14")
用來正常顯示中文標簽
plt.rcParams['font.sans-serif']=['SimHei']
展示圖表
plt.show()
</pre>
從上面的圖表可以看出,占比最大的診所類型是口腔科類型的診所殊者,這些診所大多是民營的与境,并且傾向私人經(jīng)營較多。還有中醫(yī)科主要就是一些私人開辦的中醫(yī)館猖吴。
<strong>診所是否支持醫(yī)保:</strong>
對于社區(qū)診所來說摔刁,患者還是比較看重是否支持醫(yī)保支付的,所以醫(yī)保信息也是相當關(guān)鍵海蔽。獲取得到的醫(yī)保數(shù)據(jù)中共屈,支持醫(yī)保的顯示“是”,不支持醫(yī)保的為空党窜。統(tǒng)計醫(yī)保支付的占比拗引,并且制作稱餅圖。
<pre>#統(tǒng)計匯總醫(yī)保數(shù)量
yibaoinfo = wj.groupby("hospital_yibao")["hospital_yibao"].agg("count")
計算支持醫(yī)保和非醫(yī)保數(shù)量
yibaoinfo = np.array([yibaoinfo.values,8460-yibaoinfo.values])
定義圖表大小
plt.figure(figsize=(9,6))
定義標簽值
labels = ['有醫(yī)保', '無醫(yī)保']
定義數(shù)據(jù)值的大小刑然,獲取上面的列表信息
size = [yibaoinfo[0],yibaoinfo[1]]
定義圖表類型為餅圖
plt.pie(size, labels=labels)
plt.axis('equal')
plt.show()
</pre>
從上圖可以看到寺擂,不到一半的診所支持醫(yī)保暇务,也可能是網(wǎng)站信息更新不全泼掠,看來醫(yī)保的路還要繼續(xù)走呢。
以上就是萬家醫(yī)療診所信息爬取和分析的總過程垦细,因為能力的原因择镇,所以爬取數(shù)據(jù)的維度較少,代碼質(zhì)量和圖表也是沒有經(jīng)過美化括改,顯得稍微簡陋了一些腻豌。如果后面有時間,還會分享更多關(guān)于移動醫(yī)療+爬蟲+數(shù)據(jù)科學(xué)+數(shù)據(jù)可視化的文章嘱能,感謝大家多多關(guān)注吝梅。
本文為原創(chuàng)文章,如需轉(zhuǎn)載請注明原文出處:<a >http://wp.me/p86ISR-gO</a>