精华内容
下载资源
问答
  • 本文章使用的数据来源,可以自己下载试一下,代码在原文用有
  • Python实现全国二手房数据抓取+地图展示.pdf
  • leftlet给R语言提供了很好用的交互式动态地图接口,其在Python中得API接口包名为folium(不知道包作者为何这样起名字,和leaflet已经扯不上关系了),可以满足我们平时常用的热力图、填充地图、路径图、散点标记等...

    leftlet给R语言提供了很好用的交互式动态地图接口,其在Python中得API接口包名为folium(不知道包作者为何这样起名字,和leaflet已经扯不上关系了),可以满足我们平时常用的热力图、填充地图、路径图、散点标记等高频可视化场景。

    关于folium在热力图上的用法,可以参考这一篇分享:

    使用Python中的folium包创建热力密度图

    本篇主要介绍其在point、line、polygon这三个地理信息场景下得应用:import pandas as pdimport numpy as npimport osimport foliumfrom folium import pluginsimport webbrowserimport geopandas as gp

    Point:full = pd.read_excel("D:/Python/File/Cities2015.xlsx")

    full = full.dropna()

    默认情况下folium.Marker函数用于在空间范围内标记点,点得样式是雨滴形状,但是也可以使用folium.RegularPolygonMarker函数来自定义点样式:schools_map = folium.Map(location=[full['lat'].mean(), full['lon'].mean()], zoom_start=10)

    marker_cluster = plugins.MarkerCluster().add_to(schools_map)for name,row in full.iterrows():

    folium.Marker([row["lat"], row["lon"]], popup="{0}:{1}".format(row["cities"], row["GDP"])).add_to(marker_cluster) #folium.RegularPolygonMarker([row["lat"], row["lon"]], popup="{0}:{1}".format(row["cities"], row["GDP"]),number_of_sides=10,radius=5).add_to(marker_cluster)display(schools_map)#schools_map.save('schools_map.html')#webbrowser.open('schools_map.html')

    rtzmwmcuxi.webp

    rcniqfgpoq.webp

    display用于在编辑器内展示交互地图,save方法可以将交互地图以html文件得形式保存至本地磁盘,webbrowser.open方法可以调用默认浏览器打开本地html格式的交互地图。

    polygon:

    因为leaflet使用的在线地图并不开放地址匹配功能,也就意味着我们无法通过直接输入行政区名称来获取行政区划边界,所以在制作填充地图时,仍然需要我们构建本地素材。mydata = pd.read_csv("D:/R/rstudy/Province/geshengzhibiao.csv", encoding = 'gb18030')

    china_map = gp.GeoDataFrame.from_file("D:/R/rstudy/CHN_adm/bou2_4p.shp", encoding = 'gb18030')#china_map = gp.GeoDataFrame.from_file("D:/R/mapdata/State/china.geojson", encoding = 'gb18030')China_map = folium.Map(location=[35,120], zoom_start=4)

    China_map.choropleth(

    geo_data=open('D:/R/mapdata/State/china.geojson',encoding = 'utf-8').read(),

    data=mydata,

    columns=['province', 'zhibiao'],

    key_on= 'feature.properties.name',

    fill_color='YlGn',

    fill_opacity=0.7,

    line_opacity=0.2)

    display(China_map)

    China_map.save("China_map.html")

    hkqdvoxzyb.webp

    好在folium的choropleth函数直接支持json格式地图,仅需提供素材地址即可,data中应该包含与json素材中的属性表和地理信息边界保持一致得映射表,columns用于指定要用到的字段名称。key_on用于指定json地图数据中和你指定得data中对应得连接键(相当于主键)。

    fill_color可以指定用于配色的colorBrewer调色板。

    polyline

    folium中得线图制作也较为简单,仅需提供给folium.PolyLine函数一组带有嵌套列表或者元组得经纬度点即可。mydata1 =full.sample(20).loc[:,["lat","lon"]].values.tolist()

    mydata2 =[(i,j) for i,j in full.sample(20).loc[:,["lat","lon"]].values.tolist()]

    oneUserMap = folium.Map(location=[40.0764,116.2786],zoom_start=4)

    folium.PolyLine(mydata1,color = 'black').add_to(oneUserMap)

    display(oneUserMap)

    oneUserMap = folium.Map(location=[40.0764,116.2786],zoom_start=4)

    folium.PolyLine(mydata2,color = 'black').add_to(oneUserMap)

    display(oneUserMap)

    dzempgvrdj.webp

    稍微增加一些循环条件就可以构造出来实用的路径图场景:def map_fun():

    myresult = full.loc[:,["lat","lon","cities","pop"]].values

    oneUserMap = folium.Map(location=[40.0764,116.2786],zoom_start=4) for e in myresult:

    folium.RegularPolygonMarker(

    [e[0],e[1]],

    popup=str(e[2])+":"+str(e[3]),

    fill_color='#769d96',

    number_of_sides=10,

    radius=10

    ).add_to(oneUserMap)

    others = full.loc[full['cities']!='郑州市',["lat","lon"]].values.tolist() for i in range(len(others)):

    zhengzhou = full.loc[full['cities']=='郑州市',["lat","lon"]].values.tolist()

    zhengzhou.append(others[i])

    folium.PolyLine(

    locations = zhengzhou,

    color = 'black'

    ).add_to(oneUserMap)

    display(oneUserMap) return Noneif __name__ == '__main__':

    map_fun()

    rpewjlepbi.webp

    展开全文
  • Python爬虫与数据可视化

    万次阅读 多人点赞 2019-06-12 20:57:09
    数据可视化这里特别强调,pyecharts包千万别装新版的,我这里装的是0.5.9版的其次如果要做地理坐标图,热力图啥的,必须安装地图包,比如世界地图包,中国地图包,城市地图包啥的 1.数据挖掘 代码所需包 # -*- ...

    之前写过篇爬取前程无忧职位信息并保存到Excel的博客,
    这里仔细的讲讲并且增加可视化内容

    1.数据挖掘

    代码所需包

    import urllib.request
    import xlwt
    import re
    import urllib.parse
    import time
    

    进入前程无忧官网
    我这里以搜索大数据职位信息
    在这里插入图片描述
    打开开发者模式
    Request Headers 里面是我们用浏览器访问网站的信息,有了信息后就能模拟浏览器访问
    这也是为了防止网站封禁IP,不过前程无忧一般是不会封IP的。
    在这里插入图片描述
    模拟浏览器

    header={
        'Host':'search.51job.com',
        'Upgrade-Insecure-Requests':'1',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    

    在这里插入图片描述
    这些基本数据都可以爬取:
    为了实现交互型爬取,我写了一个能够实现输入想了解的职位就能爬取相关内容的函数

    def getfront(page,item):       #page是页数,item是输入的字符串,见后文
         result = urllib.parse.quote(item)					#先把字符串转成十六进制编码
         ur1 = result+',2,'+ str(page)+'.html'
         ur2 = 'https://search.51job.com/list/000000,000000,0000,00,9,99,'
         res = ur2+ur1															#拼接网址
         a = urllib.request.urlopen(res)
         html = a.read().decode('gbk')          # 读取源代码并转为unicode
         return html
    
    def getInformation(html):
        reg = re.compile(r'class="t1 ">.*? <a target="_blank" title="(.*?)" href="(.*?)".*? <span class="t2"><a target="_blank" title="(.*?)" href="(.*?)".*?<span class="t3">(.*?)</span>.*?<span class="t4">(.*?)</span>.*?<span class="t5">(.*?)</span>.*?',re.S)#匹配换行符
        items=re.findall(reg,html)
        return items
    

    这里我除了爬取图上信息外,还把职位超链接后的网址,以及公司超链接的网址爬取下来了。
    这里先不讲,后面后面会说到,
    接下来就需要储存信息,这里使用Excel,虽然比较麻烦,不过胜在清晰直观

    #新建表格空间
    excel1 = xlwt.Workbook()
    # 设置单元格格式
    sheet1 = excel1.add_sheet('Job', cell_overwrite_ok=True)
    sheet1.write(0, 0, '序号')
    sheet1.write(0, 1, '职位')
    sheet1.write(0, 2, '公司名称')
    sheet1.write(0, 3, '公司地点')
    sheet1.write(0, 4, '公司性质')
    sheet1.write(0, 5, '薪资')
    sheet1.write(0, 6, '学历要求')
    sheet1.write(0, 7, '工作经验')
    sheet1.write(0, 8, '公司规模')
    sheet1.write(0, 9, '公司类型')
    sheet1.write(0, 10,'公司福利')
    sheet1.write(0, 11,'发布时间')
    

    爬取代码如下,这里就能利用双层循环来实现换页爬取与换行输出
    我这里为了获得大量数据所以爬取了1000页,调试时可以只爬取几页

    number = 1
    item = input()
    for j in range(1,1000):   #页数自己随便改
        try:
            print("正在爬取第"+str(j)+"页数据...")
            html = getfront(j,item)      #调用获取网页原码
            for i in getInformation(html):
                try:
                    url1 = i[1]          #职位网址
                    res1 = urllib.request.urlopen(url1).read().decode('gbk')
                    company = re.findall(re.compile(r'<div class="com_tag">.*?<p class="at" title="(.*?)"><span class="i_flag">.*?<p class="at" title="(.*?)">.*?<p class="at" title="(.*?)">.*?',re.S),res1)
                    job_need = re.findall(re.compile(r'<p class="msg ltype".*?>.*?&nbsp;&nbsp;<span>|</span>&nbsp;&nbsp;(.*?)&nbsp;&nbsp;<span>|</span>&nbsp;&nbsp;(.*?)&nbsp;&nbsp;<span>|</span>&nbsp;&nbsp;.*?</p>',re.S),res1)
                    welfare = re.findall(re.compile(r'<span class="sp4">(.*?)</span>',re.S),res1)
                    print(i[0],i[2],i[4],i[5],company[0][0],job_need[2][0],job_need[1][0],company[0][1],company[0][2],welfare,i[6])
                    sheet1.write(number,0,number)
                    sheet1.write(number,1,i[0])
                    sheet1.write(number,2,i[2])
                    sheet1.write(number,3,i[4])
                    sheet1.write(number,4,company[0][0])
                    sheet1.write(number,5,i[5])
                    sheet1.write(number,6,job_need[1][0])
                    sheet1.write(number,7,job_need[2][0])
                    sheet1.write(number,8,company[0][1])
                    sheet1.write(number,9,company[0][2])
                    sheet1.write(number,10,("  ".join(str(i) for i in welfare)))
                    sheet1.write(number,11,i[6])
                    number+=1
                    excel1.save("51job.xls")
                    time.sleep(0.3) #休息间隔,避免爬取海量数据时被误判为攻击,IP遭到封禁
                except:
                    pass
        except:
            pass
    

    结果如下:
    在这里插入图片描述
    在这里插入图片描述

    2.数据清洗

    首先要打开文件

    #coding:utf-8
    import pandas as pd
    import re
    #除此之外还要安装xlrd包
    
    data = pd.read_excel(r'51job.xls',sheet_name='Job')
    result = pd.DataFrame(data)
    

    清洗思路:
    1、出现有空值(NAN)得信息,直接删除整行

    a = result.dropna(axis=0,how='any')
    pd.set_option('display.max_rows',None)     #输出全部行,不省略
    

    2、职位出错(很多职位都是与大数据无关的职业)
    在这里插入图片描述

    b = u'数据'
    number = 1
    li = a['职位']
    for i in range(0,len(li)):
        try:
            if b in li[i]:
                #print(number,li[i])
                number+=1
            else:
                a = a.drop(i,axis=0)
        except:
            pass
    

    3、其他地方出现的信息错位,比如在学历里出现 ‘招多少人’
    在这里插入图片描述

    b2= u'人'
    li2 = a['学历要求']
    for i in range(0,len(li2)):
        try:
            if b2 in li2[i]:
                #print(number,li2[i])
                number+=1
                a = a.drop(i,axis=0)
        except:
            pass
    

    4、转换薪资单位
    如上图就出现单位不一致的情况

    b3 =u'万/年'
    b4 =u'千/月'
    li3 = a['薪资']
    #注释部分的print都是为了调试用的
    for i in range(0,len(li3)):
        try:
            if b3 in li3[i]:
                x = re.findall(r'\d*\.?\d+',li3[i])
                #print(x)
                min_ = format(float(x[0])/12,'.2f')              #转换成浮点型并保留两位小数
                max_ = format(float(x[1])/12,'.2f')
                li3[i][1] = min_+'-'+max_+u'万/月'
            if b4 in li3[i]:
                x = re.findall(r'\d*\.?\d+',li3[i])
                #print(x)
                #input()
                min_ = format(float(x[0])/10,'.2f')
                max_ = format(float(x[1])/10,'.2f')
                li3[i][1] = str(min_+'-'+max_+'万/月')
            print(i,li3[i])
    
        except:
            pass
    

    保存到另一个Excel文件

    a.to_excel('51job2.xlsx', sheet_name='Job', index=False)
    

    这里只是简单的介绍了一些数据清理的思路,并不是说只要清理这些就行了
    有时候有的公司网页并不是前程无忧类型的,而是他们公司自己做的网页,这也很容易出错
    不过只要有了基本思路,这些都不难清理

    3.数据可视化

    数据可视化可以说是很重要的环节,如果只是爬取数据而不去可视化处理,那么可以说数据的价值根本没有发挥
    可视化处理能使数据更加直观,更有利于分析
    甚至可以说可视化是数据挖掘最重要的内容

    同样的我们先看代码需要的包

    # -*- coding: utf-8 -*-
    import pandas as pd
    import re
    from pyecharts import Funnel,Pie,Geo
    import matplotlib.pyplot as plt
    

    在这里插入图片描述

    若找不到或者安装失败,可用源码安装的方式

    在这里插入图片描述
    https://github.com/pyecharts/pyecharts

    在这里插入图片描述
    接下来就是正戏
    一样的先要打开文件

    file = pd.read_excel(r'51job2.xls',sheet_name='Job')
    f = pd.DataFrame(file)
    pd.set_option('display.max_rows',None)
    

    1、创建多个列表来单独存放【‘薪资’】【‘工作经验’】【‘学历要求’】【‘公司地点’】等信息

    add = f['公司地点']
    sly = f['薪资']
    edu = f['学历要求']
    exp = f['工作经验']
    address =[]
    salary = []
    education = []
    experience = []
    for i in range(0,len(f)):
        try:
            a = add[i].split('-')
            address.append(a[0])
            #print(address[i])
            s = re.findall(r'\d*\.?\d+',sly[i])
            s1= float(s[0])
            s2 =float(s[1])
            salary.append([s1,s2])
            #print(salary[i])
            education.append(edu[i])
            #print(education[i])
            experience.append(exp[i])
            #print(experience[i])
        except:
           pass
    

    2、matploblib库生成 工作经验—薪资图 与 学历—薪资图

    min_s=[]							#定义存放最低薪资的列表
    max_s=[]							#定义存放最高薪资的列表
    for i in range(0,len(experience)):
        min_s.append(salary[i][0])
        max_s.append(salary[i][0])
    
    my_df = pd.DataFrame({'experience':experience, 'min_salay' : min_s, 'max_salay' : max_s})				#关联工作经验与薪资
    data1 = my_df.groupby('experience').mean()['min_salay'].plot(kind='line')
    plt.show()
    my_df2 = pd.DataFrame({'education':education, 'min_salay' : min_s, 'max_salay' : max_s})				#关联学历与薪资
    data2 = my_df2.groupby('education').mean()['min_salay'].plot(kind='line')
    plt.show()
    

    在这里插入图片描述
    在这里插入图片描述
    3、学历要求圆环图

    def get_edu(list):
        education2 = {}
        for i in set(list):
            education2[i] = list.count(i)
        return education2
    dir1 = get_edu(education)
    # print(dir1)
    
    attr= dir1.keys()
    value = dir1.values()
    pie = Pie("学历要求")
    pie.add("", attr, value, center=[50, 50], is_random=False, radius=[30, 75], rosetype='radius',
            is_legend_show=False, is_label_show=True,legend_orient='vertical')
    pie.render('学历要求玫瑰图.html')
    

    在这里插入图片描述
    在这里插入图片描述
    4、大数据城市需求地理位置分布图

    def get_address(list):
        address2 = {}
        for i in set(list):
            address2[i] = list.count(i)
        address2.pop('异地招聘')
        # 有些地名可能不合法或者地图包里没有可以自行删除,之前以下名称都会报错,现在好像更新了
        #address2.pop('山东')
        #address2.pop('怒江')
        #address2.pop('池州')
        return address2
    dir2 = get_address(address)
    #print(dir2)
    
    geo = Geo("大数据人才需求分布图", title_color="#2E2E2E",
              title_text_size=24,title_top=20,title_pos="center", width=1300,height=600)
    attr2 = dir2.keys()
    value2 = dir2.values()
    geo.add("",attr2, value2, type="effectScatter", is_random=True, visual_range=[0, 1000], maptype='china',symbol_size=8, effect_scale=5, is_visualmap=True)
    geo.render('大数据城市需求分布图.html')
    

    在这里插入图片描述
    在这里插入图片描述
    5、工作经验要求漏斗图

    def get_experience(list):
        experience2 = {}
        for i in set(list):
             experience2[i] = list.count(i)
        return experience2
    dir3 = get_experience(experience)
    #print(dir3)
    
    attr3= dir3.keys()
    value3 = dir3.values()
    funnel = Funnel("工作经验漏斗图",title_pos='center')
    funnel.add("", attr3, value3,is_label_show=True,label_pos="inside", label_text_color="#fff",legend_orient='vertical',legend_pos='left')
    funnel.render('工作经验要求漏斗图.html')
    

    在这里插入图片描述
    在这里插入图片描述
    当然,pyecharts里面的图还有很多种,就靠大家去自己发掘了。

    【反馈】

    接到部分人反应的乱码情况,主要可能是因为网站规则变动。我去重新更新了一下代码,并且改进了一些地方,如果遇到爬取过程中途停下的情况,可能是网络问题或者陷入阻塞,可以重新运行一次代码

    所有代码如下:

    # -*- coding:utf-8 -*-
    import urllib.request
    import xlwt
    import re
    import urllib.parse
    import time
    header={
        'Host':'search.51job.com',
        'Upgrade-Insecure-Requests':'1',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    def getfront(page,item):       #page是页数,item是输入的字符串
         result = urllib.parse.quote(item)					#先把字符串转成十六进制编码
         ur1 = result+',2,'+ str(page)+'.html'
         ur2 = 'https://search.51job.com/list/000000,000000,0000,00,9,99,'
         res = ur2+ur1															#拼接网址
         a = urllib.request.urlopen(res)
         html = a.read().decode('gbk')          # 读取源代码并转为unicode
         return html
    def getInformation(html):
        reg = re.compile(r'class="t1 ">.*? <a target="_blank" title="(.*?)" href="(.*?)".*? <span class="t2"><a target="_blank" title="(.*?)" href="(.*?)".*?<span class="t3">(.*?)</span>.*?<span class="t4">(.*?)</span>.*?<span class="t5">(.*?)</span>.*?',re.S)#匹配换行符
        items=re.findall(reg,html)
        return items
    #新建表格空间
    excel1 = xlwt.Workbook()
    # 设置单元格格式
    sheet1 = excel1.add_sheet('Job', cell_overwrite_ok=True)
    sheet1.write(0, 0, '序号')
    sheet1.write(0, 1, '职位')
    sheet1.write(0, 2, '公司名称')
    sheet1.write(0, 3, '公司地点')
    sheet1.write(0, 4, '公司性质')
    sheet1.write(0, 5, '薪资')
    sheet1.write(0, 6, '学历要求')
    sheet1.write(0, 7, '工作经验')
    sheet1.write(0, 8, '公司规模')
    sheet1.write(0, 9, '公司类型')
    sheet1.write(0, 10,'公司福利')
    sheet1.write(0, 11,'发布时间')
    number = 1
    item = input()
    for j in range(1,10000):   #页数自己随便改
        try:
            print("正在爬取第"+str(j)+"页数据...")
            html = getfront(j,item)      #调用获取网页原码
            for i in getInformation(html):
                try:
                    url1 = i[1]          #职位网址
                    res1 = urllib.request.urlopen(url1).read().decode('gbk')
                    company = re.findall(re.compile(r'<div class="com_tag">.*?<p class="at" title="(.*?)"><span class="i_flag">.*?<p class="at" title="(.*?)">.*?<p class="at" title="(.*?)">.*?',re.S),res1)
                    job_need = re.findall(re.compile(r'<p class="msg ltype".*?>.*?&nbsp;&nbsp;<span>|</span>&nbsp;&nbsp;(.*?)&nbsp;&nbsp;<span>|</span>&nbsp;&nbsp;(.*?)&nbsp;&nbsp;<span>|</span>&nbsp;&nbsp;.*?</p>',re.S),res1)
                    welfare = re.findall(re.compile(r'<span class="sp4">(.*?)</span>',re.S),res1)
                    print(i[0],i[2],i[4],i[5],company[0][0],job_need[2][0],job_need[1][0],company[0][1],company[0][2],welfare,i[6])
                    sheet1.write(number,0,number)
                    sheet1.write(number,1,i[0])
                    sheet1.write(number,2,i[2])
                    sheet1.write(number,3,i[4])
                    sheet1.write(number,4,company[0][0])
                    sheet1.write(number,5,i[5])
                    sheet1.write(number,6,job_need[2][0])
                    sheet1.write(number,7,job_need[1][0])
                    sheet1.write(number,8,company[0][1])
                    sheet1.write(number,9,company[0][2])
                    sheet1.write(number,10,("  ".join(str(i) for i in welfare)))
                    sheet1.write(number,11,i[6])
                    number+=1
                    excel1.save("51job.xls")
                    time.sleep(0.3) #休息间隔,避免爬取海量数据时被误判为攻击,IP遭到封禁
                except:
                    pass
        except:
            pass
    
    #coding:utf-8
    import pandas as pd
    import re
    
    data = pd.read_excel(r'51job.xls',sheet_name='Job')
    result = pd.DataFrame(data)
    
    a = result.dropna(axis=0,how='any')
    pd.set_option('display.max_rows',None)     #输出全部行,不省略
    
    b = u'数据'
    number = 1
    li = a['职位']
    for i in range(0,len(li)):
        try:
            if b in li[i]:
                #print(number,li[i])
                number+=1
            else:
                a = a.drop(i,axis=0)  #删除整行
        except:
            pass
    
    b2 = '人'
    li2 = a['学历要求']
    for i in range(0,len(li2)):
        try:
            if b2 in li2[i]:
                # print(number,li2[i])
                number += 1
                a = a.drop(i, axis=0)
        except:
            pass
    
    b3 =u'万/年'
    b4 =u'千/月'
    li3 = a['薪资']
    #注释部分的print都是为了调试用的
    for i in range(0,len(li3)):
        try:
            if b3 in li3[i]:
                x = re.findall(r'\d*\.?\d+',li3[i])
                #print(x)
                min_ = format(float(x[0])/12,'.2f')              #转换成浮点型并保留两位小数
                max_ = format(float(x[1])/12,'.2f')
                li3[i][1] = min_+'-'+max_+u'万/月'
            if b4 in li3[i]:
                x = re.findall(r'\d*\.?\d+',li3[i])
                #print(x)
                #input()
                min_ = format(float(x[0])/10,'.2f')
                max_ = format(float(x[1])/10,'.2f')
                li3[i][1] = str(min_+'-'+max_+'万/月')
            print(i,li3[i])
    
        except:
            pass
    a.to_excel('51job2.xls', sheet_name='Job', index=False)
    #############################################################################################
    import pandas as pd
    import re
    from pyecharts import Funnel,Pie,Geo
    import matplotlib.pyplot as plt
    
    file = pd.read_excel(r'51job2.xls',sheet_name='Job')
    f = pd.DataFrame(file)
    pd.set_option('display.max_rows',None)
    
    add = f['公司地点']
    sly = f['薪资']
    edu = f['学历要求']
    exp = f['工作经验']
    address =[]
    salary = []
    education = []
    experience = []
    for i in range(0,len(f)):
        try:
            a = add[i].split('-')
            address.append(a[0])
            #print(address[i])
            s = re.findall(r'\d*\.?\d+',sly[i])
            s1= float(s[0])
            s2 =float(s[1])
            salary.append([s1,s2])
            #print(salary[i])
            education.append(edu[i])
            #print(education[i])
            experience.append(exp[i])
            #print(experience[i])
        except:
           pass
    
    min_s=[]							#定义存放最低薪资的列表
    max_s=[]							#定义存放最高薪资的列表
    for i in range(0,len(experience)):
        min_s.append(salary[i][0])
        max_s.append(salary[i][0])
    #matplotlib模块如果显示不了中文字符串可以用以下代码。
    plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
    
    my_df = pd.DataFrame({'experience':experience, 'min_salay' : min_s, 'max_salay' : max_s})				#关联工作经验与薪资
    data1 = my_df.groupby('experience').mean()['min_salay'].plot(kind='line')
    plt.show()
    my_df2 = pd.DataFrame({'education':education, 'min_salay' : min_s, 'max_salay' : max_s})				#关联学历与薪资
    data2 = my_df2.groupby('education').mean()['min_salay'].plot(kind='line')
    plt.show()
    
    def get_edu(list):
        education2 = {}
        for i in set(list):
            education2[i] = list.count(i)
        return education2
    dir1 = get_edu(education)
    # print(dir1)
    
    attr= dir1.keys()
    value = dir1.values()
    pie = Pie("学历要求")
    pie.add("", attr, value, center=[50, 50], is_random=False, radius=[30, 75], rosetype='radius',
            is_legend_show=False, is_label_show=True,legend_orient='vertical')
    pie.render('学历要求玫瑰图.html')
    
    def get_address(list):
        address2 = {}
        for i in set(list):
            address2[i] = list.count(i)
        address2.pop('异地招聘')
        # 有些地名可能不合法或者地图包里没有可以自行删除,之前以下名称都会报错,现在好像更新了
        #address2.pop('山东')
        #address2.pop('怒江')
        #address2.pop('池州')
        return address2
    dir2 = get_address(address)
    #print(dir2)
    
    geo = Geo("大数据人才需求分布图", title_color="#2E2E2E",
              title_text_size=24,title_top=20,title_pos="center", width=1300,height=600)
    attr2 = dir2.keys()
    value2 = dir2.values()
    geo.add("",attr2, value2, type="effectScatter", is_random=True, visual_range=[0, 1000], maptype='china',symbol_size=8, effect_scale=5, is_visualmap=True)
    geo.render('大数据城市需求分布图.html')
    
    def get_experience(list):
        experience2 = {}
        for i in set(list):
             experience2[i] = list.count(i)
        return experience2
    dir3 = get_experience(experience)
    #print(dir3)
    
    attr3= dir3.keys()
    value3 = dir3.values()
    funnel = Funnel("工作经验漏斗图",title_pos='center')
    funnel.add("", attr3, value3,is_label_show=True,label_pos="inside", label_text_color="#fff",legend_orient='vertical',legend_pos='left')
    funnel.render('工作经验要求漏斗图.html')
    
    

    在这里插入图片描述
    HTML文件最好用谷歌浏览器打开,如果点开没反应可以在文件夹里找到该文件然后打开
    在这里插入图片描述

    最近比较多人说爬取数据没有动静,我去看了下,其实不是什么问题,就是网页源码有更改,之前python爬取到的信息是用HTML写的,而现在数据那里是JavaScript写的,这样的话正则肯定就不匹配了。我也花时间改了改。有些东西也去的去,加的加,不过不影响后面数据可视化。

    # -*- coding:utf-8 -*-
    import urllib.request
    import xlwt
    import re
    import urllib.parse
    import time
    header={
        'Host':'search.51job.com',
        'Upgrade-Insecure-Requests':'1',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    def getfront(page,item):       #page是页数,item是输入的字符串
         result = urllib.parse.quote(item)					#先把字符串转成十六进制编码
         ur1 = result+',2,'+ str(page)+'.html'
         ur2 = 'https://search.51job.com/list/000000,000000,0000,00,9,99,'
         res = ur2+ur1    #拼接网址
         a = urllib.request.urlopen(res)
         html = a.read().decode('gbk')      # 读取源代码并转为unicode
         html = html.replace('\\','')       # 将用于转义的"\"替换为空
         html = html.replace('[', '')
         html = html.replace(']', '')
         #print(html)
         return html
    
    def getInformation(html):
        reg = re.compile(r'\{"type":"engine_search_result","jt":"0".*?"job_href":"(.*?)","job_name":"(.*?)".*?"company_href":"(.*?)","company_name":"(.*?)","providesalary_text":"(.*?)".*?"updatedate":"(.*?)".*?,'
                         r'"companytype_text":"(.*?)".*?"jobwelf":"(.*?)".*?"attribute_text":"(.*?)","(.*?)","(.*?)","(.*?)","companysize_text":"(.*?)","companyind_text":"(.*?)","adid":""},',re.S)#匹配换行符
        items=re.findall(reg,html)
        print(items)
        return items
    
    #新建表格空间
    excel1 = xlwt.Workbook()
    # 设置单元格格式
    sheet1 = excel1.add_sheet('Job', cell_overwrite_ok=True)
    sheet1.write(0, 0, '序号')
    sheet1.write(0, 1, '职位')
    sheet1.write(0, 2, '公司名称')
    sheet1.write(0, 3, '公司地点')
    sheet1.write(0, 4, '公司性质')
    sheet1.write(0, 5, '薪资')
    sheet1.write(0, 6, '学历要求')
    sheet1.write(0, 7, '工作经验')
    sheet1.write(0, 8, '公司规模')
    #sheet1.write(0, 9, '公司类型')
    sheet1.write(0, 9,'公司福利')
    sheet1.write(0, 10,'发布时间')
    number = 1
    item = input()
    
    for j in range(1,10):   #页数自己随便改
        try:
            print("正在爬取第"+str(j)+"页数据...")
            html = getfront(j,item)      #调用获取网页原码
            for i in getInformation(html):
                try:
                    #url1 = i[1]          #职位网址
                    #res1 = urllib.request.urlopen(url1).read().decode('gbk')
                    #company = re.findall(re.compile(r'<div class="com_tag">.*?<p class="at" title="(.*?)"><span class="i_flag">.*?<p class="at" title="(.*?)">.*?<p class="at" title="(.*?)">.*?',re.S),res1)
                    #job_need = re.findall(re.compile(r'<p class="msg ltype".*?>.*?&nbsp;&nbsp;<span>|</span>&nbsp;&nbsp;(.*?)&nbsp;&nbsp;<span>|</span>&nbsp;&nbsp;(.*?)&nbsp;&nbsp;<span>|</span>&nbsp;&nbsp;.*?</p>',re.S),res1)
                    #welfare = re.findall(re.compile(r'<span class="sp4">(.*?)</span>',re.S),res1)
                    #print(i[0],i[2],i[4],i[5],company[0][0],job_need[2][0],job_need[1][0],company[0][1],company[0][2],welfare,i[6])
                    sheet1.write(number,0,number)
                    sheet1.write(number,1,i[1])
                    sheet1.write(number,2,i[3])
                    sheet1.write(number,3,i[8])
                    sheet1.write(number,4,i[6])
                    sheet1.write(number,5,i[4])
                    sheet1.write(number,6,i[10])
                    sheet1.write(number,7,i[9])
                    sheet1.write(number,8,i[12])
                    #sheet1.write(number,9,i[7])
                    sheet1.write(number,9,i[7])
                    sheet1.write(number,10,i[5])
                    number+=1
                    excel1.save("51job.xls")
                    time.sleep(0.3) #休息间隔,避免爬取海量数据时被误判为攻击,IP遭到封禁
                except:
                    pass
        except:
            pass
    

    顺便放上源码:https://github.com/haohaizhi/51job_spiders

    因为有了自己的博客网站,后续若有修改将在新的链接中体现
    https://blog.mehoon.com/107.html

    展开全文
  • Python疫情数据爬取与可视化展示

    万次阅读 多人点赞 2021-03-19 22:16:26
    使用Python爬取腾讯新闻疫情数据,并使用pyecharts可视化,绘制国内、国际日增长人数地图,matplotlib绘制方寸图。 随笔记录所的所学,此博客为我记录文章所用,发布到此,仅供网友阅读参考。作者:北山啦 现在...

    疫情数据爬取与可视化展示

    使用Python爬取腾讯新闻疫情数据,并使用pyecharts可视化,绘制国内、国际日增长人数地图,matplotlib绘制方寸图。

    随笔记录所的所学,此博客为我记录文章所用,发布到此,仅供网友阅读参考。作者:北山啦

    写在前面:这个已经不是什么新鲜的话题了,所以请大佬勿喷

    导入相关模块

    import time
    import json
    import requests
    from datetime import datetime
    import pandas as pd
    import numpy as np
    

    1. 疫情数据抓取

    通过腾讯新闻公布的数据进行爬取

    网址:https://news.qq.com/zt2020/page/feiyan.htm#/

    对于静态网页,我们只需要把网页地址栏中的url传到get请求中就可以轻松地获取到网页的数据。 对于动态网页抓取的关键是先分析网页数据获取和跳转的逻辑,再去写代码 。

    右击检查,选择Network,Ctrl+R即可
    在这里插入图片描述

    记得安装快速第三方库

    pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名
    

    快速下载模块

    # 定义抓取数据函数:https://beishan.blog.csdn.net/
    def Domestic():
        url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'
        reponse = requests.get(url=url).json()
        data = json.loads(reponse['data'])
        return data
    
    
    def Oversea():
        url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign'
        reponse = requests.get(url=url).json()
        data = json.loads(reponse['data'])
        return data
    
    
    domestic = Domestic()
    oversea = Oversea()
    
    print(domestic.keys())
    print(oversea.keys())
    
    dict_keys(['lastUpdateTime', 'chinaTotal', 'chinaAdd', 'isShowAdd', 'showAddSwitch', 'areaTree'])
    dict_keys(['foreignList', 'globalStatis', 'globalDailyHistory', 'importStatis', 'countryAddConfirmRankList', 'countryConfirmWeekCompareRankList', 'continentStatis'])
    

    2. 初步分析

    提取各地区数据明细

    # 提取各地区数据明细
    areaTree = domestic['areaTree']
    # 查看并分析具体数据
    areaTree
    

    提取国外地区数据明细

    # 提取国外地区数据明细
    foreignList = oversea['foreignList']
    # 查看并分析具体数据
    foreignList
    

    就可以看到在json数据存储的结构了

    3. 数据处理

    3.1 国内各省疫情数据提取

    # Adresss:https://beishan.blog.csdn.net/
    china_data = areaTree[0]['children'] 
    china_list = []
    for a in range(len(china_data)):
        province = china_data[a]['name']  
        confirm = china_data[a]['total']['confirm'] 
        heal = china_data[a]['total']['heal']  
        dead = china_data[a]['total']['dead']  
        nowConfirm = confirm - heal - dead 
        china_dict = {} 
        china_dict['province'] = province  
        china_dict['nowConfirm'] = nowConfirm 
        china_list.append(china_dict) 
    
    china_data = pd.DataFrame(china_list) 
    china_data.to_excel("国内疫情.xlsx", index=False) #存储为EXCEL文件
    china_data.head()
    
    provincenowConfirm
    0香港323
    1上海40
    2四川34
    3台湾30
    4广东29

    3.2 国际疫情数据提取

    world_data = foreignList  
    world_list = []  
    
    for a in range(len(world_data)):
        # 提取数据
        country = world_data[a]['name']
        nowConfirm = world_data[a]['nowConfirm']  
        confirm = world_data[a]['confirm']
        dead = world_data[a]['dead']  
        heal = world_data[a]['heal'] 
        # 存放数据
        world_dict = {}
        world_dict['country'] = country
        world_dict['nowConfirm'] = nowConfirm
        world_dict['confirm'] = confirm
        world_dict['dead'] = dead
        world_dict['heal'] = heal
        world_list.append(world_dict)
    
    world_data = pd.DataFrame(world_list)
    world_data.to_excel("国外疫情.xlsx", index=False)
    world_data.head()
    
    countrynowConfirmconfirmdeadheal
    0美国72826113035888055247022523799
    1西班牙1939763212332729102945446
    2法国2166003240525557671181581
    3秘鲁11194042218319408290835
    4英国9001110414513759375

    3.3 数据整合

    将国内数据和海外数据合并

    查询数据中是否含有中国疫情数据

    world_data.loc[world_data['country'] == "中国"]
    
    countrynowConfirmconfirmdeadheal

    从新增areaTree中提取中国数据,并添加至world_data

    confirm = areaTree[0]['total']['confirm']  # 提取中国累计确诊数据
    heal = areaTree[0]['total']['heal']  # 提取中国累计治愈数据
    dead = areaTree[0]['total']['dead']  # 提取中国累计死亡数据
    nowConfirm = confirm - heal - dead  # 计算中国现有确诊数量
    
    world_data = world_data.append(
        {
            'country': "中国",
            'nowConfirm': nowConfirm,
            'confirm': confirm,
            'heal': heal,
            'dead': dead
        },
        ignore_index=True)
    

    再次查询数据中是否含有中国疫情数据

    world_data.loc[world_data['country'] == "中国"]
    
    countrynowConfirmconfirmdeadheal
    161中国518102479484997112

    4. 可视化展示

    4.1 国内疫情态势可视化

    导入pyecharts相关库

    快速掌握数据可视化工具pyecharts

    import pyecharts.options as opts
    from pyecharts.charts import Map
    from pyecharts.globals import CurrentConfig, NotebookType
    CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB
    

    国内各地区现有确诊人数地图

    m = Map()
    m.add("", [
        list(z)
        for z in zip(list(china_data["province"]), list(china_data["nowConfirm"]))
    ],
          maptype="china",
          is_map_symbol_show=False)
    m.set_global_opts(
        title_opts=opts.TitleOpts(title="COVID-19中国现有地区现有确诊人数地图"),
        visualmap_opts=opts.VisualMapOpts(
            is_piecewise=True,
            pieces=[
                {
                    "min": 5000,
                    "label": '>5000',
                    "color": "#893448"
                },  # 不指定 max,表示 max 为无限大
                {
                    "min": 1000,
                    "max": 4999,
                    "label": '1000-4999',
                    "color": "#ff585e"
                },
                {
                    "min": 500,
                    "max": 999,
                    "label": '500-1000',
                    "color": "#fb8146"
                },
                {
                    "min": 101,
                    "max": 499,
                    "label": '101-499',
                    "color": "#ffA500"
                },
                {
                    "min": 10,
                    "max": 100,
                    "label": '10-100',
                    "color": "#ffb248"
                },
                {
                    "min": 1,
                    "max": 9,
                    "label": '1-9',
                    "color": "#fff2d1"
                },
                {
                    "max": 1,
                    "label": '0',
                    "color": "#ffffff"
                }
            ]))
    m.render_notebook()
    

    在这里插入图片描述

    4.2 国际疫情态势可视化

    将各国的中文名称转换成英文名称,使用pandas中的merge方法

    pd.merge( left, right, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=(’_x’, ‘_y’), copy=True, indicator=False, validate=None,)

    how: One of ‘left’, ‘right’, ‘outer’, ‘inner’. 默认inner。inner是取交集,outer取并集

    world_name = pd.read_excel("国家中英文对照表.xlsx")
    world_data_t = pd.merge(world_data,
                            world_name,
                            left_on="country",
                            right_on="中文",
                            how="inner")
    
    world_data_t
    
    countrynowConfirmconfirmdeadheal英文中文
    0美国72826113035888055247022523799United States美国
    1西班牙1939763212332729102945446Spain西班牙
    2法国2166003240525557671181581France法国
    3秘鲁11194042218319408290835Peru秘鲁
    4英国9001110414513759375United Kingdom英国
    ........................
    164伯利兹2200Belize伯利兹
    165东帝汶1100Timor-Leste东帝汶
    166东帝汶1100East Timor东帝汶
    167巴布亚新几内亚1100Papua New Guinea巴布亚新几内亚
    168中国518102479484997112China中国

    169 rows × 7 columns

    世界各国现有确诊人数地图

    m2 = Map()
    m2.add("", [
        list(z)
        for z in zip(list(world_data_t["英文"]), list(world_data_t["nowConfirm"]))
    ],
           maptype="world",
           is_map_symbol_show=False)
    m2.set_global_opts(title_opts=opts.TitleOpts(title="COVID-19世界各国现有确诊人数地图"),
                       visualmap_opts=opts.VisualMapOpts(is_piecewise=True,
                                                         pieces=[{
                                                             "min": 5000,
                                                             "label": '>5000',
                                                             "color": "#893448"
                                                         }, {
                                                             "min": 1000,
                                                             "max": 4999,
                                                             "label": '1000-4999',
                                                             "color": "#ff585e"
                                                         }, {
                                                             "min": 500,
                                                             "max": 999,
                                                             "label": '500-1000',
                                                             "color": "#fb8146"
                                                         }, {
                                                             "min": 101,
                                                             "max": 499,
                                                             "label": '101-499',
                                                             "color": "#ffA500"
                                                         }, {
                                                             "min": 10,
                                                             "max": 100,
                                                             "label": '10-100',
                                                             "color": "#ffb248"
                                                         }, {
                                                             "min": 0,
                                                             "max": 9,
                                                             "label": '0-9',
                                                             "color": "#fff2d1"
                                                         }]))
    """取消显示国家名称"""
    m2.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
    m2.render_notebook()
    

    在这里插入图片描述

    4.3 国内疫情方寸间

    单独取出中国疫情数据

    # 单独取出中国疫情数据
    China_data = world_data.loc[world_data['country'] == "中国"]
    
    # 使索引从0开始递增
    China_data.reset_index(drop=True, inplace=True)
    
    China_data
    
    countrynowConfirmconfirmdeadheal
    0中国518102479484997112

    提取China_data的累计确诊、累计治愈与累计死亡数据

    # 提取China_data的累计确诊、累计治愈与累计死亡数据
    # data.at[n,'name']代表根据行索引和列名,获取对应元素的值
    w_confirm = China_data.at[0, 'confirm']
    w_heal = China_data.at[0, 'heal']
    w_dead = China_data.at[0, 'dead']
    

    导入matplotlib相关库

    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    

    构建国内疫情方寸间图示

    # -*- coding: utf-8 -*-
    %matplotlib inline
    
    fig1 = plt.figure()
    
    ax1 = fig1.add_subplot(111, aspect='equal', facecolor='#fafaf0')
    ax1.set_xlim(-w_confirm / 2, w_confirm / 2)
    ax1.set_ylim(-w_confirm / 2, w_confirm / 2)
    ax1.spines['top'].set_color('none')
    ax1.spines['right'].set_color('none')
    ax1.spines['bottom'].set_position(('data', 0))
    ax1.spines['left'].set_position(('data', 0))
    ax1.set_xticks([])
    ax1.set_yticks([])
    
    p0 = patches.Rectangle((-w_confirm / 2, -w_confirm / 2),
                           width=w_confirm,
                           height=w_confirm,
                           facecolor='#29648c',
                           label='confirm')
    p1 = patches.Rectangle((-w_heal / 2, -w_heal / 2),
                           width=w_heal,
                           height=w_heal,
                           facecolor='#69c864',
                           label='heal')
    p2 = patches.Rectangle((-w_dead / 2, -w_dead / 2),
                           width=w_dead,
                           height=w_dead,
                           facecolor='#000000',
                           label='dead')
    
    plt.gca().add_patch(p0)
    plt.gca().add_patch(p1)
    plt.gca().add_patch(p2)
    plt.title('COVID-19 Square - China', fontdict={'size': 20})
    plt.legend(loc='best')
    plt.show()
    

    在这里插入图片描述

    4.4 国际疫情方寸间

    重新排序数据

    world_data.sort_values("confirm", ascending=False, inplace=True)
    world_data.reset_index(drop=True, inplace=True)
    world_data
    
    countrynowConfirmconfirmdeadheal
    0美国72826113035888055247022523799
    1西班牙1939763212332729102945446
    2法国2166003240525557671181581
    3秘鲁11194042218319408290835
    4英国9001110414513759375
    ..................
    157利比里亚3300
    158几内亚比绍2200
    159伯利兹2200
    160东帝汶1100
    161巴布亚新几内亚1100

    162 rows × 5 columns

    构建国际疫情方寸间图示

    # -*- coding: utf-8 -*-
    plt.rcParams['font.sans-serif'] = [u'SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    fig1 = plt.figure(figsize=(25, 25))
    for a in range(20):
    
        w_confirm = world_data.at[a, 'confirm']
        w_heal = world_data.at[a, 'heal']
        w_dead = world_data.at[a, 'dead']
        ax1 = fig1.add_subplot(20 / 4,
                               4,
                               a + 1,
                               aspect='equal',
                               facecolor='#fafaf0')
        ax1.set_xlim(-w_confirm / 2, w_confirm / 2)
        ax1.set_ylim(-w_confirm / 2, w_confirm / 2)
    
        ax1.spines['top'].set_color('none')
        ax1.spines['right'].set_color('none')
        ax1.spines['bottom'].set_position(('data', 0))
        ax1.spines['left'].set_position(('data', 0))
        ax1.set_xticks([])
        ax1.set_yticks([])
        p0 = patches.Rectangle((-w_confirm / 2, -w_confirm / 2),
                               width=w_confirm,
                               height=w_confirm,
                               alpha=w_confirm / 90000,
                               facecolor='#29648c',
                               label='confirm')
        p1 = patches.Rectangle((-w_heal / 2, -w_heal / 2),
                               width=w_heal,
                               height=w_heal,
                               alpha=1,
                               facecolor='#69c864',
                               label='heal')
        p2 = patches.Rectangle((-w_dead / 2, -w_dead / 2),
                               width=w_dead,
                               height=w_dead,
                               alpha=1,
                               facecolor='black',
                               label='dead')
        plt.gca().add_patch(p0)
        plt.gca().add_patch(p1)
        plt.gca().add_patch(p2)
    
    
        plt.title(world_data.at[a, 'country'], fontdict={'size': 20})
    
    
        plt.legend(loc='best')
    
    plt.show()
    

    在这里插入图片描述
    这样就可以清楚的看到各个国家新冠确诊人数、治愈和死亡人数的关系了

    推荐阅读

    1. 冰冰B站视频弹幕爬取原理解析
    2. Python建立时间序列ARIMA模型实战案例
    3. 使用xpath爬取数据
    4. jupyter notebook使用
    5. BeautifulSoup爬取豆瓣电影Top250
    6. 一篇文章带你掌握requests模块
    7. Python网络爬虫基础–BeautifulSoup

    参考链接

    1. 腾讯疫情动态
    2. Python 制作全国疫情地图
    3. 利用Python实现新冠疫情数据可视化
    4. 欢迎关注

    在这里插入图片描述

    到这里就结束了,如果对你有帮助,欢迎点赞关注评论,你的点赞对我很重要。

    在这里插入图片描述

    展开全文
  • Python链家租房信息爬虫和高德地图展示

    千次阅读 热门讨论 2019-04-15 12:19:50
    Python链家租房信息爬虫和高德地图展示 工具:Pycharm,Win10,Python3.6.4,高德API 1.数据爬取 首先我们明确要获取的信息。我们要北京的东城,西城,朝阳,海淀,丰台这5个地区的租房信息。打开链家租房网站,...

    Python链家租房信息爬虫和高德地图展示

    工具:Pycharm,Win10,Python3.6.4,高德API

    1.数据爬取

    首先我们明确要获取的信息。我们要北京的东城,西城,朝阳,海淀,丰台这5个地区的租房信息。打开链家租房网站,选择东城地区的第二页信息我们发现网址有如下规律

    下面就是分析页面,以东城为例,我们发现数据直接在源代码中,很简单,直接正则或者xpath获取即可。

    import csv
    import requests
    import re
    from lxml import etree
    import csv
    import urllib3
    urllib3.disable_warnings()
    headers = {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
    'Connection': 'close',
    }
    '''
    函数功能:
        获取索引页信息
    输    入:
        url - 索引页网址
    输    出:
        html - 网页源码
    '''
    def get_index_html(url):
        try:
            response = requests.get(url,headers=headers,timeout=60)
            response.encoding = response.apparent_encoding
            html = response.text
            return html
        except:
            get_index_html(url)
    '''
    函数功能:
        解析索引页
    输    入:
        html - 网页源码
    输    出:
        all_data - 所有信息
            describe - 描述
            area - 小区位置
            square - 面积
            direction - 朝向
            type - 类型
            floor - 楼层
            detail_url - 详情链接 
        advantage - 优势
    '''
    def parse_index_html(html):
        advantages = []
        all_data = []
        html_xpath = etree.HTML(html)
        for j in range(1,31):
            advantage = ''
            try:
                html_data = html_xpath.xpath('//*[@id="content"]/div[1]/div[1]/div['+str(j)+']/div/p[5]//i/text()')
                for i in html_data:
                    advantage += i
                    advantage += ','
                advantages.append(advantage)
            except:
                advantages.append(advantage)
                '//*[@id="content"]/div[1]/div[1]/div[2]/div/p[1]'
        infos_pattern = re.compile('twoline">.*?href="(.*?)">'        #url
                                         +'(.*?)</a>'                        #describe
                                         +'.*?a target.*?">(.*?)</a>'       #分区
                                         +'.*?target="_blank">(.*?)</a>'    #local
                                         +'.*?</i>(.*?)㎡'                   #square
                                         +'.*?</i>(.*?)<i>'                  #direction
                                         +'.*?</i>(.*?)<span'                #type
                                         +'.*?</i>(.*?)</span>'              #floor
                                          '.*?content__list--item-price"><em>(.*?)</em' # money
                                         ,re.S)
        infos = re.findall(infos_pattern,html)
        for info in infos:
            info = list(info)
            all_data.append(info)
        # print(all_data)
        return advantages,all_data
    
    '''
    函数功能:
        获取详情页信息
    输    入:
        url - 详情页网址
    输    出:
        html - 网页源码
    '''
    def get_detail_url(url):
        try:
            response = requests.get(url,headers=headers,timeout=60)
            response.encoding = response.apparent_encoding
            html = response.text
            # print(html)
            return html
        except:
            get_detail_url()
    
    '''
    函数功能:
        解析详情页
    输    入:
        html - 网页源码
    输    出:
        longitude - 经度
        latitude - 维度
    '''
    def parse_detail_html(html):
        longitude_pattern = re.compile('longitude: \'(.*?)\',',re.S)
        longitude = re.findall(longitude_pattern,html)
        latitude_pattern = re.compile('latitude: \'(.*?)\'',re.S)
        latitude = re.findall(latitude_pattern,html)
        name_pattern = re.compile('g_conf.name = \'(.*?)\';',re.S)
        name = re.findall(name_pattern,html)
        return longitude[0],latitude[0],name[0]
    
    
    def write2csv(info,local):
        with open(local+'.csv','a',encoding='utf-8-sig',newline='') as f:
            writer = csv.writer(f)
    
            writer.writerow(info)
    if __name__ == '__main__':
        local_list = ['fengtai']
        for local in local_list:
            for page in range(1,30):
                print(local,page)
                url = 'https://bj.lianjia.com/zufang/'+str(local)+'/pg'+str(page)
                # url = 'https://bj.lianjia.com/zufang/BJ2225173257978920960.html?nav=0'
                html = get_index_html(url)
                advantages,all_data = parse_index_html(html)
                for j in range(len(all_data)):
                    detail_url = 'https://bj.lianjia.com'+all_data[j][0]
                    detail_html = get_detail_url(detail_url)
                    longitude, latitude,name = parse_detail_html(detail_html)
                    all_data[j].append(advantages[j])
                    all_data[j].append(longitude)
                    all_data[j].append(latitude)
                    all_data[j].insert(1,name)
                    for k in range (len(all_data[j])):
                            # print(all_data[j][k])
                        all_data[j][k] = all_data[j][k].strip().replace(' ','')
                    write2csv(all_data[j],local)
    

    我们获取了5个地区数据之后合并在一起获得如下数据

    2.数据分析

    数据获取了之后我们要进行数据分析,主要分析三个。一是价格和面积的散点图,面积的直方图。二是5个地区的平均租价(元/平方米)的直方图。三是房源描述的词云图。

    from matplotlib import  pyplot as plt
    import pandas as pd
    import jieba
    import wordcloud
    from scipy.misc import imread
    
    plt.rcParams['font.family'] = 'SimHei' #配置中文字体
    plt.rcParams['font.size'] = 15   # 更改默认字体大小
    data = pd.read_csv('all_data.csv',encoding='utf-8-sig') #读取数据
    
    #均价统计
    dongcheng = data.iloc[:,9] /   data.iloc[:,5]
    data.insert(12,'average',dongcheng)
    grouped = data['average'].groupby(data['local'])
    print(grouped.mean().keys())
    plt.bar(list(grouped.mean().keys()),list(grouped.mean().values))
    plt.show()
    
    
    #房屋面积和价格的分析
    plt.figure(figsize=(30,10))
    plt.subplot(1,2,1) #一行两列第一个图
    size = data.iloc[:,5]
    price = data.iloc[:,9]
    plt.scatter(size,price)
    plt.xlabel('房屋面积')
    plt.ylabel('价格')
    
    plt.subplot(1,2,2) #一行两列第一个图
    plt.title('面积统计',fontsize=20,)
    plt.hist(size,bins = 15) #bins指定有几条柱状
    plt.xlabel('房屋面积')
    plt.show()
    
    
    
    
    #title词云分析
    title = data.iloc[:,2]
    
    color_mask = imread("123.jpg") #读取背景图片,
    
    title = str(title)
    for ch in "'\n'' '!?。。"#$%&'()*+,-/:;<=>@[\]^_`{|>}~⦅⦆「」、、〃》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏.":
        title = title.replace(ch,"")
    # 生成词云
    ls = jieba.lcut(title)
    txt = " ".join(ls)
    a = wordcloud.WordCloud(font_path = "msyh.ttc", width = 1000, height = 700, background_color = "black",mask=color_mask,)
    a.generate(txt)
    a.to_file("title.png")

    3.高德地图展示

    这部分去高德API示例中心找找就有相应结果我直接贴出代码

    <html>
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
            <title>毕业生租房</title>
            <link rel="stylesheet" href="http://cache.amap.com/lbs/static/main1119.css" />
            <link rel="stylesheet" href="http://cache.amap.com/lbs/static/jquery.range.css" />
            <script src="http://cache.amap.com/lbs/static/jquery-1.9.1.js"></script>
            <script src="http://cache.amap.com/lbs/static/es5.min.js"></script>
            <script src="http://webapi.amap.com/maps?v=1.3&key=22d3816e107f199992666d6412fa0691&plugin=AMap.ArrivalRange,AMap.Scale,AMap.Geocoder,AMap.Transfer,AMap.Autocomplete"></script>
            <script src="http://cache.amap.com/lbs/static/jquery.range.js"></script>
            <style>
            .control-panel {
                position: absolute;
                top: 30px;
                right: 20px;
            }
    
            .control-entry {
                width: 280px;
                background-color: rgba(119, 136, 153, 0.8);
                font-family: fantasy, sans-serif;
                text-align: left;
                color: white;
                overflow: auto;
                padding: 10px;
                margin-bottom: 10px;
            }
    
            .control-input {
                margin-left: 120px;
            }
    
            .control-input input[type="text"] {
                width: 160px;
            }
    
            .control-panel label {
                float: left;
                width: 120px;
            }
    
            #transfer-panel {
                position: absolute;
                background-color: white;
                max-height: 80%;
                overflow-y: auto;
                top: 30px;
                left: 20px;
                width: 250px;
            }
            </style>
        </head>
    
        <body>
            <div id="container"></div>
            <div class="control-panel">
                <div class="control-entry">
                    <label>选择工作地点:</label>
                    <div class="control-input">
                        <input id="work-location" type="text">
                    </div>
                </div>
                <div class="control-entry">
                    <label>选择通勤方式:</label>
                    <div class="control-input">
                        <input type="radio" name="vehicle" value="SUBWAY,BUS" onClick="takeBus(this)" checked/> 公交+地铁
                        <input type="radio" name="vehicle" value="SUBWAY" onClick="takeSubway(this)" /> 地铁
                    </div>
                </div>
                <div class="control-entry">
                    <label>导入房源文件:</label>
                    <div class="control-input">
                        <input type="file" name="file" onChange="importRentInfo(this)" />
                    </div>
                </div>
            </div>
            <div id="transfer-panel"></div>
            <script>
            var map = new AMap.Map("container", {
                resizeEnable: true,
                zoomEnable: true,
                center: [116.397428, 39.90923],
                zoom: 11
            });
            var scale = new AMap.Scale();
    map.addControl(scale);
    
    var arrivalRange = new AMap.ArrivalRange();
    var x, y, t, vehicle = "SUBWAY,BUS";
    var workAddress, workMarker;
    var rentMarkerArray = [];
    var polygonArray = [];
    var amapTransfer;
    
    var infoWindow = new AMap.InfoWindow({
        offset: new AMap.Pixel(0, -30)
    });
    
    var auto = new AMap.Autocomplete({
        input: "work-location"
    });
    AMap.event.addListener(auto, "select", workLocationSelected);
    
    
    function takeBus(radio) {
        vehicle = radio.value;
        loadWorkLocation()
    }
    
    function takeSubway(radio) {
        vehicle = radio.value;
        loadWorkLocation()
    }
    
    function importRentInfo(fileInfo) {
        var file = fileInfo.files[0].name;
        loadRentLocationByFile(file);
    }
    
    function workLocationSelected(e) {
        workAddress = e.poi.name;
        loadWorkLocation();
    }
    
    function loadWorkMarker(x, y, locationName) {
        workMarker = new AMap.Marker({
            map: map,
            title: locationName,
            icon: 'http://webapi.amap.com/theme/v1.3/markers/n/mark_r.png',
            position: [x, y]
    
        });
    }
    
    
    function loadWorkRange(x, y, t, color, v) {
        arrivalRange.search([x, y], t, function(status, result) {
            if (result.bounds) {
                for (var i = 0; i < result.bounds.length; i++) {
                    var polygon = new AMap.Polygon({
                        map: map,
                        fillColor: color,
                        fillOpacity: "0.4",
                        strokeColor: color,
                        strokeOpacity: "0.8",
                        strokeWeight: 1
                    });
                    polygon.setPath(result.bounds[i]);
                    polygonArray.push(polygon);
                }
            }
        }, {
            policy: v
        });
    }
    
    function addMarkerByAddress(address) {
        var geocoder = new AMap.Geocoder({
            city: "北京",
            radius: 1000
        });
        geocoder.getLocation(address, function(status, result) {
            if (status === "complete" && result.info === 'OK') {
                var geocode = result.geocodes[0];
                rentMarker = new AMap.Marker({
                    map: map,
                    title: address,
                    icon: 'http://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
                    position: [geocode.location.getLng(), geocode.location.getLat()]
                });
                rentMarkerArray.push(rentMarker);
    
                rentMarker.content = "<div>房源:<a target = '_blank' href='https://bj.lianjia.com" + address + "'>" + address + "</a><div>"
                rentMarker.on('click', function(e) {
                    infoWindow.setContent(e.target.content);
                    infoWindow.open(map, e.target.getPosition());
                    if (amapTransfer) amapTransfer.clear();
                    amapTransfer = new AMap.Transfer({
                        map: map,
                        policy: AMap.TransferPolicy.LEAST_TIME,
                        city: "北京市",
                        panel: 'transfer-panel'
                    });
                    amapTransfer.search([{
                        keyword: workAddress
                    }, {
                        keyword: address
                    }], function(status, result) {})
                });
            }
        })
    }
    
    function delWorkLocation() {
        if (polygonArray) map.remove(polygonArray);
        if (workMarker) map.remove(workMarker);
        polygonArray = [];
    }
    
    function delRentLocation() {
        if (rentMarkerArray) map.remove(rentMarkerArray);
        rentMarkerArray = [];
    }
    
    function loadWorkLocation() {
        delWorkLocation();
        var geocoder = new AMap.Geocoder({
            city: "北京",
            radius: 1000
        });
    
        geocoder.getLocation(workAddress, function(status, result) {
            if (status === "complete" && result.info === 'OK') {
                var geocode = result.geocodes[0];
                x = geocode.location.getLng();
                y = geocode.location.getLat();
                loadWorkMarker(x, y);
                loadWorkRange(x, y, 60, "#3f67a5", vehicle);
                map.setZoomAndCenter(12, [x, y]);
            }
        })
    }
    
    function loadRentLocationByFile(fileName) {
        delRentLocation();
        var rent_locations = new Set();
        $.get(fileName, function(data) {
            data = data.split("\n");
            data.forEach(function(item, index) {
                rent_locations.add(item.split(",")[1]);
            });
            rent_locations.forEach(function(element, index) {
                addMarkerByAddress(element);
            });
        });
    }
    
            </script>
        </body>
    </html>
    

     

     

    展开全文
  • python最全画地图,可视化数据

    万次阅读 多人点赞 2018-08-17 18:56:23
    有时我们会很希望把数据展示地图上,来做数据可视化,使数据更加清晰明了,可谓一图胜百文。先说说我用地图做什么了:微信好友全国分布,显示票房省份数据,全国评分显示等等,我这个语言能力很是头疼啊,进入正.....
  • 当我们日常使用地图APP或者在网页上浏览地图信息的时候,会不会有一种想把地图信息直接抓取下来的想法呢?一般做分析的都想这么干啦,而地图服务商也开放了api接口,你们这些爬爬们不要再用乱七八糟的方式ping我的...
  • 本文使用Python3.6+Pyecharts1.7实现 制作步骤 1.环境搭建 ①Python 3.6.10 安装教程 Python可安装pip方便安装Python包 ②Pyechart1.7.0 安装下载地址 我之前有的pyecharts0.5版本,因为我的Python是3.5的,...
  • 小伙伴,我又来了,这次我们写的是用python爬虫爬取乌鲁木齐的房产数据展示地图上,地图工具我用的是 BDP个人版-免费在线数据分析软件,数据可视化软件 ,这个可以导入csv或者excel数据。 首先还是分析思路,...
  • 本文通过调用百度地图接口,实现用户可视化展示,便于更清楚地了解用户。注册百度地图开放平台帐号Python调用通过http调用接口格式如下:http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=E...
  • Python图表分析和展示疫情历史数据

    千人学习 2020-02-15 18:52:58
    使用Python分析2019-nCov疫情数据 数据工程师、数据挖掘人员 爱国人士、疫情关注人员 Python程序员、编程爱好者 课程优势: - 接口稳定,永久有效 - ...折线图展示数据内容,挖掘疫情变化情况
  • python绘制世界地图,进行文件数据处理
  • Python地图可视化库有大家熟知的pyecharts、plotly、folium,还有稍低调的bokeh、basemap、geopandas,也是地图可视化利器。首先介绍下bokehbokeh擅长制作交互式图表,当然在地图展示方面也毫不逊色。Bokeh支持...
  • 该资源是针对这次肺炎疫情写个Python数据分析系列博客,包括网络爬虫、可视化分析、GIS地图显示、情感分析、舆情分析、主题挖掘、威胁情报溯源、知识图谱、预测预警及AI和NLP应用等。希望该系列线上远程教学对您...
  • python和百度地图API实现数据地图标注

    千次阅读 热门讨论 2018-10-24 15:54:50
    先上效果图: 在上海地区测试了下批量经纬度在百度地图...先用python进行数据处理 data_html = pd.DataFrame(columns=['content']) for indexs in group.index: data_html.loc[indexs,'content'] = '{' + \ ...
  • 基于python语言,实现OSM开源地图数据解析,获取交通网路数据
  • Python+pyecharts在地图上呈现数据

    千次阅读 2020-10-21 09:34:57
    本文主要内容前言一、 地图的基本使用方法二、 地图数据结合1、各省GDP在地图展示2、去除地图上的数据信息3、用颜色区别数据大小4、自己定义颜色区间5、修改点的显示效果6、修改地图的色彩三、 Pyecharts制作...
  • 18年中国GPD可视化图表中国自上世纪80年代全国各省市GDP排名香港人口密度图全国各省市地图地图不显示类别信息连续型数据地图带有移动线的3D地图显示数据点的3D地图显示3D柱状图的3D地图全国行政区划地图世界人口分布...
  • 目前高德的边界没法批量爬取,不过可以采用百度地图的接口来替代,目前用着还可以,参见这里: http://www.mapboxx.cn/article/boundary/ 为了方便大家,不用再为安装环境,以及运行报错等问题困扰,目前已经将POI...
  • Plotly是新一代的数据可视化神器,TopQ扩展开源团队,虽然plotly功能强大,却一直没有得到广泛应用,大部分py开发人员,还在使用陈旧的matplotlib,其中最重要的原因,就是plotly的设置过于繁琐。折射率,plotly推出...
  • 一、先申请百度开发者AK码 二、由于百度opi查询每页只能返回20条记录,最多查询20页,所以超出400条记录就...本次我通过91地图查询到分块的坐标。 三、使用python代码编辑器编写代码程序 # -*- coding: ...
  • 百度地图信息采集器-----含UI 界面展示数据展示: 技术点: requests — 用于对页面发起请求 threading — 线程库 解决了页面爬取的速度 os — 创建文件以及打开指定文件 xlwt — 将数据写入excel 表中 pyqt5...
  • 今天我们来讲讲如何在Python里面调用申请的API接口,然后利用Python进行相关的数据处理,最终得到我们想要的信息。最近大家还是要响应号召,不出门!在家好好学习吧~地点检索方式目前百度地图的地点检索服务有以下4...
  • python地理地图可视化:folium把百度地图各个城市经纬度解析出来并在地图展示 上一篇把百度地图各个城市的经纬度解析出来了,现在通过folium把各个经纬度点在地图上绘制出来,代码如下: import json import ...
  • 基于python的basemap库,读取并显示凉山市的shp数据地图,并分颜色显示行政区域规划、河流、道路、水库、乡镇及乡镇名等,并显示对应的比例尺。 代码100行,不难
  • python数据可视化 纽约出租车案例分析 ...python最全画地图,可视化数据 Basemap入坑手册 k-means 聚类算法(Python实现) pythonJupyter [python] 基于matplotlib实现树形图的绘制_py..
  • 本期我们利用Python可视化动态展示2001-2019年全国各省市GDP数据,涉及到pandas数据处理、pyechars数据可视化,希望对你有所帮助。 先看看效果: 1. 数据获取 数据来源:国家统计局官网(http://www.stats.gov.cn/...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,091
精华内容 4,036
热门标签
关键字:

python地图展示数据

python 订阅