Python房?jī)r(jià)分析和可視化<房天下二手房>
本文是Python數(shù)據(jù)分析實(shí)戰(zhàn)的房?jī)r(jià)分析系列,本文分析二線城市貴陽(yáng)的二手房。
數(shù)據(jù)獲取
本文的數(shù)據(jù)來(lái)源于2022年8月房天下的二手房數(shù)據(jù)。對(duì)數(shù)據(jù)獲取不感興趣可以跳過(guò)此部分看分析和可視化。
1.訪問(wèn)目標(biāo)頁(yè)面
進(jìn)入網(wǎng)站首頁(yè),點(diǎn)擊選擇城市和二手房進(jìn)入<二手房信息頁(yè)面>,篩選條件(位置、價(jià)格等)都保持默認(rèn),這樣可以查出全部二手房信息。2.分析url變化
拖動(dòng)滾動(dòng)條到翻頁(yè)的地方,點(diǎn)擊幾次<上一頁(yè)>、<下一頁(yè)>翻頁(yè),觀察瀏覽器上方搜索框里url的變化??梢钥吹矫看畏?yè)url只變化一個(gè)數(shù)字,對(duì)應(yīng)當(dāng)前的頁(yè)數(shù)。
所以只要不斷改變url中的頁(yè)數(shù),就可以獲取所有的數(shù)據(jù)。
3.二手房總數(shù)分析
二手房信息很多,已經(jīng)超過(guò)了網(wǎng)站的最大顯示數(shù)量,房天下最多展示100頁(yè)二手房數(shù)據(jù),所以我們要獲取的數(shù)據(jù)總頁(yè)數(shù)為100。每頁(yè)的信息是60條,按計(jì)算可以獲取到6000條信息,但有些頁(yè)面的數(shù)據(jù)沒(méi)有獲取完整,最后共獲取到了3000多條信息(這個(gè)問(wèn)題暫時(shí)不影響我的分析,有空再分析原因)。
4.循環(huán)拼接url獲取所有數(shù)據(jù)
在url中從1開(kāi)始拼接頁(yè)數(shù),直到第100頁(yè),依次獲取所有頁(yè)面的信息。
參考代碼:
import time
for p in range(1, 101):
time.sleep(5)
second_house_url = 'https://gy.esf.fang.com/house/i3{}'.format(p)
try:
res = requests.get(second_house_url, headers=headers) # headers需要自己準(zhǔn)備
print('獲取第{}頁(yè)數(shù)據(jù)成功'.format(p))
except Exception as e:
print('獲取第{}頁(yè)數(shù)據(jù)失敗,報(bào)錯(cuò):{}'.format(p, e))
5.用XPath提取數(shù)據(jù)
二手房信息在返回結(jié)果的HTML文件中,需要使用XPath語(yǔ)法提取。
參考代碼:
from lxml import etree
result = res.text
html = etree.HTML(result)
infos = html.xpath('//dl[@dataflag="bg"]')
XPath快速入門參考:快速入門XPath語(yǔ)法,輕松解析爬蟲(chóng)時(shí)的HTML內(nèi)容
用XPath獲取當(dāng)前頁(yè)的所有二手房信息保存在infos中,infos是一個(gè)Element對(duì)象的列表,每一個(gè)Element對(duì)象里的信息是一條二手房信息,可以繼續(xù)用XPath從中提取具體的信息。
6.將數(shù)據(jù)保存到excel中
使用pandas將解析的數(shù)據(jù)轉(zhuǎn)換成DataFrame,然后保存到excel中。最終獲取到的數(shù)據(jù)共3360條。
數(shù)據(jù)清洗
1.刪除重復(fù)值
import pandas as pd
import numpy as np
df = pd.read_excel('fangtianxia_second_house.xlsx', index_col=False)
print(df.shape)
# 刪除重復(fù)值
df.drop_duplicates('標(biāo)題', inplace=True)
print(df.shape)
(3360, 12)
(2616, 12)
刪除重復(fù)值后,剩下的二手房信息為2616條,重復(fù)值很多,有700多條。
2.填充空值
# 空值填充
print(np.any(df.isnull()))
df.fillna('未知', inplace=True)
print(np.any(df.isnull()))
True
False
數(shù)據(jù)準(zhǔn)備好后,本文開(kāi)始對(duì)獲取的2616條二手房信息進(jìn)行分析。
二手房所屬樓盤Top30
from pyecharts.charts import Bar
from pyecharts import options as opts
# 二手房數(shù)量Top30的樓盤
second_build_name = df['樓盤'].value_counts()[0:30]
bar = Bar(init_opts=opts.InitOpts(width='1000px', height='400px', bg_color='white'))
bar.add_xaxis(
second_build_name.index.to_list()
).add_yaxis(
'', second_build_name.to_list(), category_gap='30%'
).set_global_opts(
title_opts=opts.TitleOpts(title='二手房數(shù)量前30的樓盤', pos_left='400', pos_top='30',
title_textstyle_opts=opts.TextStyleOpts(color='black', font_size=16)),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(font_size=10, distance=0, rotate=30, color='#4863C4'))
).set_colors('#4863C4').render('second_build_name_top30.html')
在二手房的所屬樓盤中,最多的兩個(gè)樓盤是未來(lái)方舟和中鐵逸都國(guó)際,都超過(guò)了100套二手房。
二手房的單價(jià)分布
from pyecharts.charts import Pie
from pyecharts import options as opts
# 獲取各個(gè)價(jià)格區(qū)間的二手房數(shù)量
second_price_unit = df['單價(jià)']
sections = [0, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 15000, 20000, 100000]
group_names = ['less-5k', '5k-6k', '6k-7k', '7k-8k', '8k-9k', '9k-1w', '1w-1w2', '1w2-1w5', '1w5-2w', 'surpass-2w']
cuts = pd.cut(np.array(second_price_unit), sections, labels=group_names)
second_counts = pd.value_counts(cuts, sort=False)
pie = Pie(init_opts=opts.InitOpts(width='800px', height='600px', bg_color='white'))
pie.add(
'', [list(z) for z in zip([gen for gen in second_counts.index], second_counts)],
radius=['20%', '70%'], rosetype="radius", center=['60%', '50%']
).set_series_opts(
label_opts=opts.LabelOpts(formatter=": {c}"),
).set_global_opts(
title_opts=opts.TitleOpts(title='二手房單價(jià)分布情況', pos_left='400', pos_top='30',
title_textstyle_opts=opts.TextStyleOpts(color='black', font_size=16)),
legend_opts=opts.LegendOpts(is_show=False)
).render('second_price_counts.html')
從單價(jià)看,大部分二手房的單價(jià)在1w-1w5之間,如果按1000來(lái)切分最多的是7k-8k,不過(guò)7k-8k的數(shù)量明顯比安居客的少了很多。
對(duì)比安居客的二手房分析可以看歷史文章:Python房?jī)r(jià)分析和可視化<anjuke貴陽(yáng)二手房>
二手房的總價(jià)分布
from pyecharts.charts import Pie
from pyecharts import options as opts
# 獲取二手房總價(jià)各區(qū)間的數(shù)量
second_price_total = df['總價(jià)']
sections = [0, 50, 60, 70, 80, 90, 100, 120, 150, 200, 250, 10000]
group_names = ['less-50w', '50w-60w', '60w-70w', '70w-80w', '80w-90w', '90w-100w', '100w-120w', '120w-150w', '150w-200w', '200w-250w', 'surpass-250w']
cuts = pd.cut(np.array(second_price_total), sections, labels=group_names)
second_counts = pd.value_counts(cuts)
pie = Pie(init_opts=opts.InitOpts(width='800px', height='600px', bg_color='white'))
pie.add(
'', [list(z) for z in zip([gen for gen in second_counts.index], second_counts)],
radius=['20%', '70%'], rosetype="radius", center=['50%', '50%']
).set_series_opts(
label_opts=opts.LabelOpts(formatter=": {c}"),
).set_global_opts(
title_opts=opts.TitleOpts(title='二手房總價(jià)分布情況', pos_left='330', pos_top='20',
title_textstyle_opts=opts.TextStyleOpts(color='black', font_size=16)),
legend_opts=opts.LegendOpts(is_show=False)
).set_colors(
['rgb(0,{g},)'.format(g=100+10*x, b=200-15*x) for x in range(12)]
).render('second_total_price_counts.html')
超過(guò)一半二手房的總價(jià)在100w之上,對(duì)比安居客的數(shù)據(jù),安居客超過(guò)一半是90w之上,說(shuō)明房天下平臺(tái)上的二手房總價(jià)中位數(shù)比安居客上大約高了10w。
二手房戶型分布
from pyecharts.charts import Bar
from pyecharts import options as opts
# 獲取二手房的戶型分布
second_house_type = df['戶型'].value_counts()
unknown = second_house_type['未知']
second_house_type.drop('未知', inplace=True)
second_house_type_parse = second_house_type.loc[second_house_type >= 10]
second_house_type_parse['others'] = second_house_type.loc[second_house_type < 10].sum()
second_house_type_parse['未知'] = unknown
bar = Bar(init_opts=opts.InitOpts(width='1000px', height='400px', bg_color='white'))
bar.add_xaxis(
second_house_type_parse.index.to_list()
).add_yaxis(
'', second_house_type_parse.to_list(), category_gap='30%'
).set_global_opts(
title_opts=opts.TitleOpts(title='二手房戶型數(shù)量分布', pos_left='420', pos_top='30',
title_textstyle_opts=opts.TextStyleOpts(color='black', font_size=16)),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(font_size=12, distance=0, rotate=20, color='#FF9366')),
yaxis_opts=opts.AxisOpts(max_=1400)
).set_colors('#FF9366').render('second_house_type.html')
大部分二手房的戶型都是3室2廳,這與安居客上的分析結(jié)論一致。
二手房面積分布
from pyecharts.charts import Pie
from pyecharts import options as opts
# 獲取二手房的面積分布情況
df_second = df.drop(df.loc[df['面積']=='未知'].index)
second_area = df_second['面積'].copy()
print(second_area)
sections = [0, 50, 80, 90, 100, 110, 120, 130, 140, 150, 200, 10000]
group_names = ['0-50㎡', '50-80㎡', '80-90㎡', '90-100㎡', '100-110㎡', '110-120㎡', '120-130㎡', '130-140㎡', '140-150㎡', '150-200㎡', '200㎡以上']
cuts = pd.cut(np.array(second_area), sections, labels=group_names)
second_area_counts = pd.value_counts(cuts, ascending=True)
pie = Pie(init_opts=opts.InitOpts(width='800px', height='600px', bg_color='white'))
pie.add(
'', [list(z) for z in zip([gen for gen in second_area_counts.index], second_area_counts)],
radius=['20%', '70%'], rosetype="radius", center=['50%', '50%']
).set_series_opts(
label_opts=opts.LabelOpts(formatter=": {c}"),
).set_global_opts(
title_opts=opts.TitleOpts(title='二手房面積分布情況', pos_left='330', pos_top='20',
title_textstyle_opts=opts.TextStyleOpts(color='black', font_size=16)),
legend_opts=opts.LegendOpts(is_show=False)
).set_colors(
['rgb({r},0,)'.format(r=20*x, b=250-15*x) for x in range(12)]
).render('second_area_counts.html')
超過(guò)一半的二手房面積在110平到200平之間,安居客上的數(shù)據(jù)是120平到140平之間,這應(yīng)該也是房天下平臺(tái)的二手房總價(jià)更高的原因。
二手房朝向分布
from pyecharts.charts import Pie
from pyecharts import options as opts
import re
# 處理部分錯(cuò)列的數(shù)據(jù)
def toward_parse(toward):
return '南向' if re.findall(r'(\d+).*', toward) else toward
# 統(tǒng)計(jì)二手房的朝向
df['朝向分布'] = df['朝向'].apply(toward_parse)
second_house_toward = df['朝向分布'].value_counts()
pie = Pie(init_opts=opts.InitOpts(width='800px', height='600px', bg_color='white'))
pie.add(
'', [list(z) for z in zip([gen for gen in second_house_toward.index], second_house_toward)],
radius=['40%', '60%'], center=['50%', '50%']
).set_series_opts(
label_opts=opts.LabelOpts(formatter=": {c}"),
).set_global_opts(
title_opts=opts.TitleOpts(title='二手房朝向分布情況', pos_left='330', pos_top='20',
title_textstyle_opts=opts.TextStyleOpts(color='black', font_size=16)),
legend_opts=opts.LegendOpts(is_show=False)
).render('second_house_toward.html')
南北朝向的二手房接近7成,加上東南和西南朝向,接近了9成,這與安居客的分析結(jié)論一致。
二手房的修建年份
from pyecharts.charts import Bar
from pyecharts import options as opts
# 獲取二手房的修建年份
second_house_build_year = df['年限'].copy().value_counts()
unknown = second_house_build_year['未知']
second_house_build_year.drop(['未知', '南向', '東向', '西向'], inplace=True) # 處理部分錯(cuò)列的數(shù)據(jù)
second_house_build_year.index = [y[0:4] for y in second_house_build_year.index.to_list()]
second_house_build_year = second_house_build_year.sort_index(ascending=False)
second_house_build_year['未知'] = unknown
bar = Bar(init_opts=opts.InitOpts(width='1000px', height='400px', bg_color='white'))
bar.add_xaxis([i for i in second_house_build_year.index]).add_yaxis(
'', second_house_build_year.to_list(), category_gap='20%'
).set_series_opts(
label_opts=opts.LabelOpts(font_size=12)
).set_global_opts(
title_opts=opts.TitleOpts(title='二手房修建年份分布', pos_left='420', pos_top='20',
title_textstyle_opts=opts.TextStyleOpts(color='black', font_size=16)),
yaxis_opts=opts.AxisOpts(max_=400),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(font_size=10, rotate=30, interval=0, color='#4863C4'))
).set_colors(['#4863C4']).render('second_house_build_year.html')
二手房的修建年份除了大部分在15年內(nèi),還有2000年也很多。
二手房信息的標(biāo)題風(fēng)格文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-401702.html
import jieba
from wordcloud import WordCloud
from PIL import Image
second_house_title = df['標(biāo)題']
title_content = ','.join([str(til.replace(' ', '')) for til in second_house_title.to_list()])
cut_text = jieba.cut(title_content)
result = ' '.join(cut_text)
shape = np.array(Image.open("ciyun001.png"))
wc = WordCloud(font_path="simhei.ttf", max_font_size=70, background_color='white', colormap='winter',
prefer_horizontal=1, mask=shape, relative_scaling=0.1)
wc.generate(result)
wc.to_file("second_house_title.png")
在海量的二手房信息中,好標(biāo)題可以吸引更多潛在買家點(diǎn)擊,還有可能提高成交幾率。在這2600多條二手房信息的標(biāo)題中,高頻出現(xiàn)的詞主要有誠(chéng)心出售、幾室?guī)讖d、地鐵口、精裝修、帶車位、帶地暖等。
對(duì)比安居客上的信息,誠(chéng)心出售是房天下上的標(biāo)題高頻詞,帶車位、帶地暖是更多人提到的賣點(diǎn),而使用急售、南北通透、領(lǐng)包入住、隨時(shí)看房的明顯比安居客上少,整體來(lái)看,房天下上的標(biāo)題起得比安居客上的更好。
總結(jié)
本文獲取了房天下貴陽(yáng)市的二手房數(shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行各個(gè)維度的分析,并用Python進(jìn)行可視化。
從安居客和房天下的二手房信息分析結(jié)論來(lái)看,有一部分?jǐn)?shù)據(jù)是兩個(gè)平臺(tái)重復(fù)的,但也有很大一部分只在其中一個(gè)平臺(tái)有。
文中用到的Python庫(kù)和工具以后會(huì)專門寫文章詳細(xì)介紹,對(duì)代碼有疑問(wèn)可以關(guān)注和聯(lián)系我一起交流討論,歡迎點(diǎn)贊、評(píng)論和收藏。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-401702.html
到了這里,關(guān)于Python房?jī)r(jià)分析和可視化<房天下二手房>的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!