python爬取济南市驾校的情况(数据可视化+分析)

亲爱的朋友们,我已经好久没有更新文章了

我一直以为自己在学习新的东西,学习更加深奥的东西 却没有注重积累 有点眼高手低了

这几天忙着做期末作业 需要用到python 自己写了个爬虫

不太擅长,但是最后自我感觉良好

介绍一下我用的编辑器 VS code  微软主推的跨平台编辑器 

使用了很久(感觉啥文件都能兼容)问题总是有的,譬如插件拓展、无法识别文件

源码地址https://github.com/liyu19981212/python-

也可以复制下面的

用到了requests BeautifulSoup、re、pandas库

requests库用来请求网页数据

BeautifulSoup用来进行网页解析

re为正则表达式,因为从网页获取的文本可能会有格式问题

pandas是用来存储数据的

我爬取的网站是驾考宝典(后天我要考科目四了)

学会对url进行分析,每一个界面是如何变化的

第一页

第二页

写个循环就可以把所有的页面遍历了

jinan改成其他地面就是另一套数据了,自行发挥

里面涉及到库的使用都很简单

百度教程很多,希望深入一下,毕竟拿来主义还是不靠谱的

给大家贴一下我的源码

# -*- coding: utf-8 -*-
import requests
import re
from bs4 import BeautifulSoup
import pandas as pd

#代码框架
def getText(url,d,pages):
    try:
        name = []
        address = []
        price = []
        score = []
        stu_num = []
        for k,v in d.items():
            for p in range(1,pages+1):
                new_url = url+k+'/school'+'/'+str(p)+'f.html'
                headers = {'User-Agent':'Mozilla/5.0 Chrome/46.0.2490.80 '}
                print(new_url)
                r = requests.get(new_url,headers=headers, timeout=30)
                r.raise_for_status #如果状态不是200,引发HTTPERROR异常
                r.encoding = "utf-8"
               # return r.text
                soup = BeautifulSoup(r.text,'lxml')
                #print(soup)
                allinfo = soup.find('div',{'class','com-school-list com-part'})
                allinfo = soup.find_all('li',{'class','clearfix'})
                #print(allinfo)
                #对每一个驾校的区块进行操作,获取驾校信息
                
                for info in allinfo:
                    #驾校的名字
                    name1 = info.find_all('a',{'class':'title'})[0].get_text()
                    name1 = name1.replace('\n','').replace(' ','')
                    name.append(name1)
                    print(name1)
                    #驾校的地址
                    address1 = info.find_all('p',{'class':'field'})[0].get_text()
                    address1 = address1.replace('\n','').replace(' ','')
                    address.append(address1)
                    print(address1)

                    #学员数量
                    stu_num1 = info.find_all('span',{'class':'student'})[0].get_text()
                    stu_num1 = stu_num1.replace('\n','').replace(' ','')
                    stu_num.append(stu_num1)
                    print(stu_num1)
                    #驾校的价格
                    price1 = info.find_all('span',{'class':'price'})[0].get_text()
                    price1 == price1.replace('\n','').replace(' ','')
                    price.append(price1)
                    print(price1)
                    
                    #驾校的评分
                    score1 = info.find_all('span',{'class':'score'})[0].get_text()
                    score1 == score1.replace('\n','').replace(' ','')
                    score.append(score1)
                    print(score1)
        return name,address,price,score,stu_num
                    
    except Exception as e:
        print(e)

#存储数据
def save_data(name,address,price,score,stu_num):
    result = pd.DataFrame()
    #result['v'] = v
    result['name'] = name
    result['address'] = address
    result['price'] = price
    result['score'] = score
    result['stu_num'] = stu_num
    result.to_csv('result.csv',encoding='utf-8_sig')

#主任务
def run():
    first_url = "http://www.jiakaobaodian.com/"
    d = {'jinan':'济南市'}
    name,address,price,score,stu_num=getText(first_url,d,4)
    save_data(name,address,price,score,stu_num)

#执行
if __name__ == '__main__':
    run()
    #fillUnivList(html)

内容不多,希望大家多多支持

现在是北京时间2019年12月24日

之前做完了后面的数据可视化和聚类分析但是没有时间上传

在不弄以后就没了

给大家分享一下后面的部分

# -*- coding: utf-8 -*-
import requests
import re
from bs4 import BeautifulSoup
import pandas as pd
from sklearn.cluster import KMeans #导入K均值聚类算法
import matplotlib.pyplot as plt

#从网页获取数据
def getText(url,d,pages): 
    #传入的三个参数分别为初始网页、数据字典、页码
    try:
        area = []
        #驾校名称
        name = []
        #驾校地址
        address = []
        #价格
        price = []
        #评分
        score = []
        #学员数量
        stu_num = []
        #循环遍历
        for k,v in d.items():
            for p in range(1,pages+1):
                #获取新的url
                new_url = url+'jinan/school/'+k+'/'+str(p)+'f.html'
                #模拟浏览器
                headers = {'User-Agent':'Mozilla/5.0 Chrome/46.0.2490.80 '}
                print(new_url)
                #使用requests库
                r = requests.get(new_url,headers=headers, timeout=30)
                #状态码200
                r.raise_for_status #如果状态不是200,引发HTTPERROR异常
                #设置编码格式
                r.encoding = "utf-8"
               # return r.text
                soup = BeautifulSoup(r.text,'lxml') #使用lxml解析
                #print(soup)
                #在这里用到的是beautifulsoup库
                #定位到列表
                allinfo = soup.find('div',{'class','com-school-list com-part'})
                allinfo = soup.find_all('li',{'class','clearfix'})
                #print(allinfo)
                #对每一个驾校的区块进行操作,获取驾校信息
                
                #遍历标签li
                for info in allinfo:
                    #驾校的名字
                    name1 = info.find_all('a',{'class':'title'})[0].get_text()
                    #这里使用get_text()方法获取文本 去除文本中的标签元素
                    name1 = name1.replace('\n','').replace(' ','')
                    #正则表达式规范化格式
                    #将获取的数据放入name
                    name.append(name1)
                    print(name1)
                    
                    #驾校的地址
                    address1 = info.find_all('p',{'class':'field'})[0].get_text()
                    address1 = address1.replace('\n','').replace(' ','')
                    address.append(address1)
                    print(address1)

                    #学员数量
                    stu_num1 = info.find_all('span',{'class':'student'})[0].get_text()
                    stu_num1 = stu_num1.replace('\n','').replace(' ','').replace('名学员','')
                    stu_num.append(stu_num1)
                    print(stu_num1)
                    
                    #驾校的价格
                    price1 = info.find_all('span',{'class':'price'})[0].get_text()
                    price1 = price1.replace('¥','').replace(' ','').replace('面议','')
                    price.append(price1)
                    print(price1)
                    
                    #驾校的评分
                    score1 = info.find_all('span',{'class':'score'})[0].get_text()
                    score1 = score1.replace('\n','').replace(' ','').replace('分','')
                    score.append(score1)
                    print(score1)
                    area.append(v)
        return area,name,address,price,score,stu_num
                    
    except Exception as e:
        print(e)

#存储数据
def save_data(area,name,address,price,score,stu_num):
    #pandas中的DataFrame
    result = pd.DataFrame()
    #result['v'] = v
    result['area'] = area
    result['name'] = name
    result['address'] = address
    result['price'] = price
    result['score'] = score
    result['stu_num'] = stu_num
    result.to_csv('result.csv',encoding='utf-8_sig') #此处的编码格式设置为utf-8_sig
    
#数据处理
def clean():
    datafile= './result.csv' 
    #原始数据,第一行为属性标签
    cleanedfile = './data_cleaned.csv' 
    #数据清洗后保存的文件
    data = pd.read_csv(datafile,encoding='utf-8') 
    #读取原始数据,指定UTF-8编码
    data = data[data['price'].notnull()&data['score'].notnull()] 
    #非空值才保留
    #只保留非零的
    index1 = data['price'] != 0
    index2 = data['score'] != 0
    index3 = data['stu_num'] != 0
    data = data[index1 | index2 | index3] #该规则是“或”
    data.to_csv(cleanedfile,encoding='utf-8_sig') 
    #导出结果
#可视化
def plot():
    data = pd.read_csv('data_cleaned.csv',encoding='utf-8_sig')
    d = data['area']
    area = data['area'].drop_duplicates()
    avgp = []
    avgs = []
    avgn = []
    for a in area:
        data1 = data[data['area']==a]
        #平均价格取两位小数
        avgp1 = round(float(data1['price'].mean()),2)
        avgp.append(avgp1)
        #平均评分
        avgs1 = round(float(data1['score'].mean()),2)
        avgs.append(avgs1)
        #平均人数
        avgn1 = data1['stu_num'].mean()
        avgn.append(avgn1)
        #print(a,avgp1,avgs1,avgn1)  
    #求各个区平均分
    plt.rcParams['font.family'] = ['sans-serif']
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.bar(area,avgs,color='SkyBlue')
    plt.title('济南市各个区驾校平均评分(满分5分)')
    plt.grid(True)
    #plt.legend(lqu)
    plt.xlabel('区名')
    plt.ylabel('评分')
    plt.show()
    #求各个区平均价格
    plt.rcParams['font.family'] = ['sans-serif']
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.bar(area,avgp,color='SkyBlue')
    plt.title('济南市各个区驾校平均价格')
    plt.grid(True)
    #plt.legend(lqu)
    plt.xlabel('区名')
    plt.ylabel('元')
    plt.show()
    #求各个区平均学员数量
    plt.rcParams['font.family'] = ['sans-serif']
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.bar(area,avgn,color='SkyBlue')
    plt.title('济南市各个区驾校平均学员数量')
    plt.grid(True)
    #plt.legend(lqu)
    plt.xlabel('区名')
    plt.ylabel('人')
    plt.show() 
      
          
#K-means聚类分析
def Kmeans():
    inputfile = './data_cleaned.csv' 
    #待聚类的数据文件
    outputfile = './fenlei.xlsx'
    k = 3                       
    #需要进行的聚类类别数
   # iteration = 500             
    #聚类最大循环数
    #读取数据并进行聚类分析
    data = pd.read_csv(inputfile) 
    #读取数据
    data = data[['price','score','stu_num']]
    #调用k-means算法,进行聚类分析
    kmodel = KMeans(n_clusters = k, n_jobs = 4) 
    #n_jobs是并行数,一般等于CPU数较好
    kmodel.fit(data) 
    #训练模型
    r1 = pd.Series(kmodel.labels_).value_counts()  
    #统计各个类别的数目
    r2 = pd.DataFrame(kmodel.cluster_centers_)     
    #找出聚类中心
    r = pd.concat([r2, r1], axis = 1) 
    #横向连接(0是纵向),得到聚类中心对应的类别下的数目
    r.columns = list(data.columns) + [u'类别数目'] 
    #重命名表头
    print("聚类表结果:")
    print (r)
    
    r = pd.concat([data, pd.Series(kmodel.labels_, index = data.index)], axis = 1) 
    #详细输出每个样本对应的类别
    r.columns = list(data.columns) + [u'聚类类别'] 
    #重命名表头
    r.to_excel(outputfile) 
    #保存分类结果
    print("聚类图结果:")
    p = data.plot(kind='kde', linewidth = 2, subplots = True, sharex = False)
    [p[i].set_ylabel('density') for i in range(k)]
    plt.legend()
   # pic_output = 'D://mypy/' #概率密度图文件名前缀
    #for i in range(k):
   #     density_plot(data[r[u'聚类类别']==i]).savefig(u'%s%s.png' %(pic_output, i))

#主任务
def run():
    #url
    first_url = "http://www.jiakaobaodian.com/"
    #d可自由设定 需要理解key和value
    d = {'q_lixia':'历下区','q_shizhong':'市中区','q_huaiyin':'槐荫区','q_tianqiao':'天桥区','q_licheng0':'历城区','q_changqing0':'长清区','q_pingyin':'平阴县','q_jiyang0':'济阳县','q_shanghe':'商河县','q_zhangqiu':'章丘市'}
    #调用def
    #获取数据
    area,name,address,price,score,stu_num=getText(first_url,d,4)
    #存储数据
    save_data(area,name,address,price,score,stu_num)
    #数据清洗
    clean()
    #绘图
    plot()
    #聚类分析
    Kmeans()
#执行
if __name__ == '__main__':
    
    run()
    #fillUnivList(html)

运行结果如下:

 

希望有用

有缘关注一下

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章