一、利用python的requests 库爬取链家二手房数据

链家南京二手房url地址:'https://nj.lianjia.com/ershoufang/'

按区查的话,比如鼓楼区,那么url就是'https://nj.lianjia.com/ershoufang/gulou/'

查看发现南京11个区里面,高淳房源太少,所以本次爬虫没有爬取高淳区的。

观察链家网站的页面发现最多显示100页的内容,所以本次爬取数据每个区爬取了100页,3000条数左右进行分析及可视化。

调用url获取到的数据如下:

和页面展示的房源信息一致。

页面上的信息复制粘贴下来会是对人性的压抑,但是我们url既然能调用出结果,那就可以提取出来。

页面展现出来的内容是用前端语言写的,我们用parsel库对网页进行解析,解析出re、xpath、css内容,然后根据css的内容进行匹配。

比如位置信息的元素是positionInfo,那么房子位置就可以根据该元素提取出来。

houseInfo获取到的户型、面积、楼层等等信息是一整块的,为了方便后期数据处理,进行了正则匹配把户型、面积、建成年份等等提取出来。

整体代码如下:

import requests,re
import time,datetime
import pandas as pd
from bs4 import BeautifulSoup
import csv,parsel
import randomurl= 'https://nj.lianjia.com/ershoufang/'
citys = ['gulou','jianye','qinhuai','xuanwu','yuhuatai','qixia','jiangning','pukou','liuhe','lishui']    # 拼接url用
citys_ch = ['鼓楼','河西','秦淮','玄武','雨花台','栖霞','江宁','浦口','六合','溧水']   #保存各区数据用
items = [{'http': 'http://171.35.171.247:9999'},{'http': 'http://114.99.7.122:8752'}
]for i in range(len(citys)):city = citys[i]f = open(str(citys_ch[i])+'二手房信息.csv', mode='a', encoding='utf-8_sig', newline='')csv_writer = csv.DictWriter(f, fieldnames=['标题', '房子位置', '房子信息', '户型','面积','装修','总共楼层','建成年份','房子结构','发布周期', '售价/万', '单价'])csv_writer.writeheader()for page in range(1, 101):print('===========================正在下载第{}页数据================================'.format(page))time.sleep(1)url = 'https://nj.lianjia.com/ershoufang/%s/pg{}/'.format(page) % cityheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}proxies = random.choice(items)response = requests.get(url=url, headers=headers, proxies=proxies)selector = parsel.Selector(response.content.decode('utf-8'))lis = selector.css('.sellListContent li')dit = {}for li in lis:title = li.css('.title a::text').get()dit['标题'] = titlepositionInfo = li.css('.positionInfo a::text').getall()info = '-'.join(positionInfo)dit['房子位置'] = infohouseInfo = li.css('.houseInfo::text').get()dit['房子信息'] = houseInfopartment = re.findall(r'^(\S+室\S+)\s+\|\s+', houseInfo)if partment ==[]:dit['户型'] = ""else:dit['户型'] = partment[0]area = re.findall(r'(\d+\S+平米)\s+\|\s+',houseInfo)if area ==[]:dit['面积'] = ""else:dit['面积'] = area[0]trim = re.findall(r'\s+(精装|简装|其他|毛坯)\s+\|\s+',houseInfo)if trim ==[]:dit['装修'] = ""else:dit['装修'] = trim[0]story = re.findall(r'\s+(\S+层\S+)\s+',houseInfo)if story ==[]:dit['总共楼层'] = ""else:dit['总共楼层'] = story[0]particular = re.findall(r'\s+(\d+)年建\s+',houseInfo)if particular ==[]:dit['建成年份'] = ""else:dit['建成年份'] = particular[0]struct = re.findall(r'\|\s+(板.*|塔.*)$',houseInfo)if struct!=[]:dit['房子结构'] = struct[0]else:dit['房子结构'] = ""followInfo = li.css('.followInfo::text').get()dit['发布周期'] = followInfoPrice = li.css('.totalPrice span::text').get()dit['售价/万'] = PriceunitPrice = li.css('.unitPrice span::text').get()dit['单价'] = unitPricecsv_writer.writerow(dit)

代码执行后,会把10个区的二手房信息爬取下来,我这里爬取的是3月13号的数据。

这是我爬下来的数据:

二、数据可视化

这次可视化用鼓楼的数据为例,用pandas处理数据,pyecharts进行大图显示。

读取第一步中爬取的数据:

data = pd.read_csv('鼓楼二手房信息.csv',encoding='UTF-8')  #GB18030  , errors='ignore'
df = pd.DataFrame(data)

我这里做了五张可视化的图,分别是直方图显示单价区间的房源数,饼图显示面积区间内的房源数,饼状图显示总价,直方图显示房龄,直方图显示面积+价格区间内的房源数。

求区间内的房源数的方法是用pd.cut函数:

cuts = pd.cut(prices,range_num,labels=labes)

prices就是区域3000条房源信息的单价,range_num是设定的房价区间范围,我这里按2~2.4万,2.4~2.8万,4千一个区间分的,labes就是要在x轴显示的区间的标签。最终得到如下图:

从图可以看出鼓楼区学区房较多,房价在整个市区中最高,8万/平以上的就占8%。

按照区间统计数据的方法,统计出各个房屋面积区间段内的房源数量,及其占比,统计出5年内、5~10年等范围内房源数量。总价范围内的房源数量等等。不再赘述。

最后是groupby的方法,同时统计房屋面积+总价范围内的房源数量。

level_area = ['0-30平','30-60平','60-90平','90-120平','120-150平','150-200平','200-300平','300-400平','400-800平']
level_sales = ['150万以下','150-200万','200-300万','300-400万''400-500万','500-600万','600-800万','800-1000万','1千-4千万','大于4千万']
group = df.groupby(['面积区间','售价区间'],as_index=False)

groupby在sql语句中用到,pandas中也有该用法,得到的结果如下:

如果在这两个条件下匹配不到,就会返回nan,我们用group.size(),就能把groupby用到的条件和统计出的数量显示出来,剔除掉0的部分,就能得出面积、总价内的房源数量,虽然看起来无用,但是对于宁飘,有买房计划的人来说,多少大洋能买起一套房心中至少会有个底吧。

用该语句grouped[~grouped['size'].isin([0])],剔除结果为0的行。

这是去除没匹配到的结果: 

最后是把所有结果放到一张大图上显示:

page = Page(layout=Page.DraggablePageLayout)
page.add(bar_unitprice(),area_pie(),saleprice_pie(),hourseage_bar(),clusete_bar())page.render("test.html")
用到的是Page方法,先把可视化的函数写好,然后加到一张页面中,先保存成html文件,然后把各个视图拖动,拖动到你想要的地方,save config后,得到一个json文件,把该json文件放到目录下,注释掉render("test.html")
Page.save_resize_html("test.html",cfg_file = "chart_config.json",dest = "鼓楼二手房信息可视化.html")

就能得到所有可视化结果在一张图上的视图。

代码如下:

# -*- coding: utf-8 -*-
import pandas as pd
import csv
import random,re
from pyecharts.charts import Geo,Map,Bar, Line, Page,Pie, Boxplot, WordCloud
from pyecharts.globals import ChartType, SymbolType,ThemeType
from pyecharts import options as optsdata = pd.read_csv('鼓楼二手房信息.csv',encoding='UTF-8')  #GB18030  , errors='ignore'
df = pd.DataFrame(data)def bar_unitprice():price_hourses = df['单价'].values.tolist()prices = []for price in price_hourses:price = float(price.replace("元/平","").replace(",",""))prices.append(price)labes = []range_num = []for i in range(20000,80001,4000):range_num.append(i)labes.append(str(i)+"-"+str(i+4000))range_num.append(200000)labes.pop(-1)labes.append("大于80000")# print(range_num,labes)cuts = pd.cut(prices,range_num,labels=labes)couts_range = cuts.value_counts().values.tolist()bar = Bar(init_opts=opts.InitOpts(width="2000px",height="700px",page_title="二手房价格区间房源数"))bar.add_xaxis(labes)bar.add_yaxis("", couts_range)bar.set_global_opts(xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=20)),title_opts=opts.TitleOpts(title="二手房价格区间房源数", subtitle="所"),datazoom_opts=opts.DataZoomOpts(),)return bardef area_pie():area=(df['面积'].str.replace('平米','').astype(float))sum_a=area.sum()#fanwei=list(range(0,250,30))bins =[0,30,60,90,120,150,200,300,400,800]count=pd.cut(area.values,bins=bins,right=False)area_range=count.value_counts()#series,区间一个数#print(area_range)attr = ["[0-30)", "[30-60)", "[60-90)", "[90-120)", "[120-150)", "[150-200)", "[200-300)", "[300-400)",'[400-800)']area_range=list(area_range)pie = Pie()pie.add("", [list(z) for z in zip(attr, area_range)],radius=["30%", "75%"],center=["40%", "50%"],rosetype="radius")pie.set_global_opts(title_opts=opts.TitleOpts(title="房屋面积占比"),legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%", orient="vertical"),).set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%"))return piedef saleprice_pie():price_sale = df['售价/万'].values.tolist()labes = []range_num = []for i in range(100,1001,50):range_num.append(i)labes.append(str(i)+"-"+str(i+50))range_num.append(3000)labes.pop(-1)labes.append("大于1000")cuts = pd.cut(price_sale,range_num,labels=labes)price_range = cuts.value_counts().values.tolist()c = (Pie(init_opts=opts.InitOpts(theme=ThemeType.LIGHT)).add("",[list(z)for z in zip(labes ,price_range ,)],#设置圆心坐标center=["40%", "57%"],).set_global_opts(title_opts=opts.TitleOpts(title="总价内的房源数"),legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%", orient="vertical",pos_top="15%"),).set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}")))return cdef hourseage_bar():years = (df['建成年份'])years = (2022 - years.dropna(axis=0,how="all").astype(int)).values.tolist()labes = []range_num = []for i in range(0,22,3):range_num.append(i)labes.append(str(i)+"-"+str(i+3))range_num.append(70)labes.pop(-1)labes.append("大于21")cuts = pd.cut(years,range_num,labels=labes)hourse_range = cuts.value_counts().values.tolist()c = (Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))  # 设置主题.add_xaxis(labes)  # x轴为房龄.add_yaxis("房源数", hourse_range)  # y轴为房源数.set_global_opts(title_opts=opts.TitleOpts(title="各个房龄的房子")).set_series_opts(label_opts=opts.LabelOpts(is_show=False),# 插入平均值线markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average", name="平均值"), ]),# 插入最大值最小值点markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max", name="最大值"),opts.MarkPointItem(type_="min", name="最小值"),])))return cdef clusete_bar():bins =[0,30,60,90,120,150,200,300,400,800]level_area = ['0-30平','30-60平','60-90平','90-120平','120-150平','150-200平','200-300平','300-400平','400-800平']sales_step = [0,150,200,300,400,500,600,800,1000,4000]level_sales = ['150万以下','150-200万','200-300万','300-400万''400-500万','500-600万','600-800万','800-1000万','1千-4千万','大于4千万']years_step = [0,5,10,15,20,25,70]level_year = ['5年以下','5-10年','10-15年','15-20年','20-25年','20年以上']area=(df['面积'].str.replace('平米','').astype(float))price_sale = (df['售价/万']).astype(float)years = (df['建成年份'])    #.fillna(0.inplace=True)years = years.fillna(1000)years = (2022 - years.astype(int))df["面积区间"] = pd.cut(area,bins=bins,labels=level_area)df["房龄"] = pd.cut(years,bins=years_step,labels=level_year)df["售价区间"] = pd.cut(price_sale,bins=sales_step,labels=level_sales,right=False)# df2 =  df[['面积区间', '房龄' , '售价区间','标题']]group = df.groupby(['面积区间','售价区间'],as_index=False)# test = group.get_group(('60-90平','200-300万','5年以下'))[['售价/万','面积','房龄','标题']]grouped = group.size()grouped=grouped[~grouped['size'].isin([0])]cluster = grouped.values.tolist()# grouped.drop( index = grouped.size[grouped.size == 0].index )counts = []lables = []for i in range(len(cluster)):counts.append(cluster[i][2])lables.append(str(cluster[i][0]+","+cluster[i][1]))bar = Bar(init_opts=opts.InitOpts(width="2000px",height="700px",page_title="总价+面积聚类",theme=ThemeType.LIGHT))bar.add_xaxis(lables)bar.add_yaxis("", counts)bar.set_global_opts(xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=20)),title_opts=opts.TitleOpts(title="总价+面积聚类", subtitle="所"),datazoom_opts=opts.DataZoomOpts(),)return barpage = Page(layout=Page.DraggablePageLayout)
page.add(bar_unitprice(),area_pie(),saleprice_pie(),hourseage_bar(),clusete_bar())
# page.render("test.html")
Page.save_resize_html("test.html",cfg_file = "chart_config.json",dest = "鼓楼二手房信息可视化.html")

得到的大图如下:

关注页面的小伙伴们可以学习上面大图可视化的方法。

如果只是想关注下数据,那看下面清晰的结果:

pandas+groupby对南京二手房进行数据可视化及大图显示相关推荐

  1. python计算商品总价_GitHub - ideaOzy/data_analysis: 基于Python的南京二手房数据采集及可视化分析...

    基于Python的南京二手房数据采集及可视化分析 1 内容简介 首先通过爬虫采集链家网上所有南京二手房的房源数据,并对采集到的数据进行清洗:然后,对清洗后的数据进行可视化分析,探索隐藏在大量数据背后的 ...

  2. 【毕业设计_课程设计】基于Python的南京二手房数据采集及可视化分析

    文章目录 0 项目说明 1 内容简介 2 应用技术介绍 3 数据采集 3.1 数据清洗 4 数据可视化 5 项目工程 0 项目说明 基于Python的南京二手房数据采集及可视化分析 提示:适合用于课程 ...

  3. 数据清洗python实现箱线图_GitHub - nonefirst/data_analysis: 基于Python的南京二手房数据采集及可视化分析...

    基于Python的南京二手房数据采集及可视化分析 1 内容简介 首先通过爬虫采集链家网上所有南京二手房的房源数据,并对采集到的数据进行清洗:然后,对清洗后的数据进行可视化分析,探索隐藏在大量数据背后的 ...

  4. python网页结构分析_GitHub - Vogdhsaj/data_analysis: 基于Python的南京二手房数据采集及可视化分析...

    基于Python的南京二手房数据采集及可视化分析 1 内容简介 首先通过爬虫采集链家网上所有南京二手房的房源数据,并对采集到的数据进行清洗:然后,对清洗后的数据进行可视化分析,探索隐藏在大量数据背后的 ...

  5. php数据库查询中文方块,解决Python数据可视化中文部分显示方块问题

    一.问题 代码如下,发现标题的中文显示的是方块 import matplotlib import matplotlib.pyplot as plt fig = plt.figure() ax = fi ...

  6. python字体变方格_解决Python数据可视化中文部分显示方块问题

    一.问题 代码如下,发现标题的中文显示的是方块 import matplotlib import matplotlib.pyplot as plt fig = plt.figure() ax = fi ...

  7. 安居客二手房python数据可视化

    继上一篇安居客二手房的数据进行预处理后,接下来就可以对数据进行可视化. 我们需要用到的库有: import os import shutilimport pandas as pd from matpl ...

  8. Pandas+Pyecharts | 40000+条考研信息数据可视化(学校、专业分数分布)

    文章目录 1. 导入模块 2. Pandas数据处理 2.1 读取数据 2.2 查看索引.数据类型和内存信息 2.3 去掉空行 2.4 筛选2020年考研信息 2.5 查看某些列重复的行 3. Pye ...

  9. 基于Python的南京二手房数据采集与可视化分析应用 完整代码+数据+ppt

    下面是项目中完整的ppt展示和本项目主要做的东西 项目包含该ppt和ppt中的内容: 完整项目代码:https://download.csdn.net/download/qq_38735017/873 ...

  10. 基于Python的南京二手房数据可视化分析

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取 python免费学习资 ...

最新文章

  1. Hibernate主键生成种类
  2. 为何说“内容+社交”是奥运发展化趋势?
  3. linkin大话面向对象--多态
  4. 全国计算机等级考试——二级公共基础知识辅导讲义 卿勇军主讲
  5. 5.2.3 OS之I/O设备的分配与回收(DCT-COCT-CHCT-SDT)
  6. django链接数据库报错Error loading MySQLdb module:No module named MySQLdb
  7. 关闭网页自动提示加入收藏
  8. URLDecoder与URLDecoder的简单了解
  9. android 自定义组件 属性值,自定义组件之自定义属性
  10. 阿里云的服务器居然泡在“水”里?| 数据中心参观有感
  11. 【汇编语言】第三章 寄存器(内存访问)
  12. 实时视频传输协议RTP
  13. c语言中怎么表示26个字母,菜鸟求助,写一个随机输出26个英文字母的程序
  14. 使用TMS320F28335控制四位共阳数码管
  15. 梦想经不起等待,今天起就行动吧!
  16. fast-lio 卡尔曼滤波
  17. fiddler——抓苹果手机的包
  18. Unicode编码介绍(手写图片版)
  19. 使用百度API获取地名坐标信息
  20. 单个JVM下支撑100w线程数vm.max_map_count

热门文章

  1. word文档左下方竟然出现无法删除的小横线???
  2. BUCK/BOOST电路
  3. 笔记:修改host文件
  4. 亚马逊运营实用教程 上线前三个月如何做
  5. Django对接微信公众号以实现消息自动回复
  6. c# 两行代码合并pdf文件
  7. 给定一个球体的半径,计算其体积。其中球体体积公式为 V = 4/3*πr3,其中 π= 3.1415926。
  8. Django Django文档
  9. 嵌入式开发(一):嵌入式开发新手入门
  10. 动作识别-Regularization on Spatio-Temporally Smoothed Feature for Action Recognition-CVPR2020