本文主要使用Python對鏈家網(wǎng)廣州二手房信息進行數(shù)據(jù)抓取存皂,并從中提取二手房價格西潘、面積嚼沿、戶型和二手房關注度等數(shù)據(jù),然后對提取的數(shù)據(jù)進行相應的數(shù)據(jù)分析與及對二手房進行分群聚類车柠。
數(shù)據(jù)獲取
網(wǎng)頁分析
由上圖可知剔氏,我們需要的數(shù)據(jù)都在網(wǎng)頁源代碼中,所以不需要抓包對網(wǎng)頁進行分析竹祷。
提取網(wǎng)頁中的特定信息
偽裝瀏覽器
#-*- coding:utf-8 -*-
import urllib.request
from bs4 import BeautifulSoup
import pandas as pd
def Disguise():
'''偽裝瀏覽器訪問'''
header = ('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36')
#@偽裝瀏覽器
opener = urllib.request.build_opener()
opener.addheaders = [header]
#將偽裝瀏覽器設為全局谈跛,這樣在后續(xù)對網(wǎng)頁的訪問就可以直接使用urlopen
urllib.request.install_opener(opener)
獲取網(wǎng)頁的內(nèi)容
def Get_page(url,num):
'''@獲取網(wǎng)頁內(nèi)容'''
try:
#獲取網(wǎng)頁的內(nèi)容,并使用BeautifulSoup解析以便后面的信息提取
page = urllib.request.urlopen(url).read()
soup = BeautifulSoup(page, 'lxml')
print('--------第%d頁抓取成功--------'%num)
return soup
except urllib.request.URLError as e:
if hasattr(e,'code'):
print('錯誤原因:',e.code)
if hasattr(e,'reason'):
print('錯誤原因:',e.reason)
提取網(wǎng)頁中的信息
這里我們使用python3中BeautifulSoup4模塊對網(wǎng)頁中的信息進行提取塑陵。由于要提取的信息都是以‘|‘或’‘/’相互連接在一起感憾,所以提取的時候需要對信息進行相應的分割。
def Get_House_info(page):
'''@提取網(wǎng)頁中的房子信息令花,并把信息以DataFrame的形式返回'''
item = {}
item['house_name'] = [i.get_text().strip().split('|')[0] for i in page.select('div[class="houseInfo"]')] # 房名
item['house_type'] = [i.get_text().strip().split('|')[1] for i in page.select('div[class="houseInfo"]')] #戶型
item['house_area'] = [i.get_text().strip().split('|')[2] for i in page.select('div[class="houseInfo"]')] #面積
item['house_interest'] = [i.get_text().strip().split('/')[0] for i in page.select('div[class="followInfo"]')] #關注人數(shù)
item['house_see'] = [i.get_text().strip().split('/')[1] for i in page.select('div[class="followInfo"]')] #帶看人數(shù)
item['house_issuedate'] = [i.get_text().strip().split('/')[2] for i in page.select('div[class="followInfo"]')] #發(fā)布時間
item['house_price'] = [i.get_text().strip() for i in page.select('div[class="totalPrice"] span')] #房價
item['house_unit_price'] = [i.get_text().strip() for i in page.select('div[class="unitPrice"] span')] #單位價格
return pd.DataFrame(item)
將各個模塊進行組裝阻桅,然后對二手房信息進行爬取
def main():
'''@主函數(shù)'''
filename = 'E:/py3_project/GZlian_jia_analysis/house_data.csv'
Disguise()
house_data = []
#二手房網(wǎng)頁總共只有100頁,這里可以使用一個for循環(huán)對網(wǎng)址進行更新
for pg in range(1,101):
lianjia_url = 'http://gz.lianjia.com/ershoufang/pg' + str(pg) +'/'
page = Get_page(lianjia_url,pg)
if len(page) > 0:
house_info = Get_House_info(page)
#把每一頁提取到的信息都存在一個list里面
house_data.append(house_info)
#對list里的DataFrame進行縱向拼接
data = pd.concat(house_data, ignore_index = True)
#將信息保存到CSV文件中
data.to_csv(filename, encoding = 'gbk', index = False)
print('------寫入完畢------')
if __name__ == '__main__':
main()
部分爬取的內(nèi)容
數(shù)據(jù)分析
導入儲存信息的文件
import pandas as pd
import os
import house_spider
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
def check_file(filename):
'''@檢查文件是否存在兼都,不存在則運行爬蟲程序獲得數(shù)據(jù)'''
if os.path.exists(filename):
print('------數(shù)據(jù)文件已存在------')
house_data = pd.read_csv(filename, encoding = 'gbk', sep = ',')
return house_data
else:
print('------文件不存在嫂沉,運行爬蟲程序?qū)π畔⑦M行爬取------')
house_spider.main()
house_data = pd.read_csv(filename, encoding = 'gbk', sep= ',')
return house_data
查看數(shù)據(jù)集的基本信息
def data_info(data_set):
'''@查看數(shù)據(jù)集的基本信息'''
print('-----數(shù)據(jù)集基本信息-----')
data_set.info()
print('-----預覽數(shù)據(jù)-----\n',data_set.head())
有上述的部分數(shù)據(jù)可知,有一些需要的數(shù)據(jù)是包含在字符串中扮碧,所以需要對字符串進行切分趟章。
將數(shù)據(jù)從字符串提取出來
def data_adj(area_data, str):
'''@將字符串轉(zhuǎn)換成數(shù)字'''
if str in area_data :
return float(area_data[0 : area_data.find(str)])
else :
return None
對處理好的數(shù)據(jù)進行分析
def main():
'''主函數(shù)'''
filename = 'E:/py3_project/GZlian_jia_analysis/house_data.csv'
#查看數(shù)據(jù)文件是否存在
house_data = check_file(filename)
#查看數(shù)據(jù)基本信息
data_info(house_data)
#將數(shù)據(jù)從字符串提取出來
house_data['area_adj'] = house_data['house_area'].apply(data_adj,str = '平米')
house_data['interest_adj'] = house_data['house_interest'].apply(data_adj,str = '人')
#畫圖時顯示中文和負號
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False```
###戶型和關注人數(shù)分析
```python
'''戶型和關注人數(shù)分布'''
fig, ax1 = plt.subplots(1,1)
type_interest_group = house_data['interest_adj'].groupby(house_data['house_type']).agg([('戶型', 'count'), ('關注人數(shù)', 'sum')])
#取戶型>50的數(shù)據(jù)進行可視化
ti_sort = type_interest_group[type_interest_group['戶型'] > 50].sort_values(by='戶型')
ti_sort.plot(kind='barh', alpha=0.7, grid=True, ax=ax1)
plt.title('二手房戶型和關注人數(shù)分布')
plt.ylabel('戶型')
plt.show() ```
![二手房戶型和關注人數(shù)分布](http://upload-images.jianshu.io/upload_images/4043796-c0dd3dd1c64444e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
由上圖可以知道,廣州二手房戶型都集中在3室2廳、2室1廳和2室2廳尤揣,而且它們的關注人數(shù)也是最多的搔啊。其中可以看到2室1廳雖然數(shù)量比3室2廳少,但是關注人數(shù)卻比3室2廳多北戏。
###二手房面積分析
```python
'''面積分布'''
fig,ax2 = plt.subplots(1,1)
area_level = [0, 50, 100, 150, 200, 250, 300, 500]
label_level = ['小于50', '50-100', '100-150', '150-200', '200-250', '250-300', '300-350']
area_cut = pd.cut(house_data['area_adj'], area_level, labels=label_level)
area_cut.value_counts().plot(kind='bar', rot=30, alpha=0.4, grid=True, fontsize='small', ax=ax2)
plt.title('二手房面積分布')
plt.xlabel('面積')
plt.legend(['數(shù)量'])
plt.show() ```
![二手房面積分布](http://upload-images.jianshu.io/upload_images/4043796-1bcf27f753f15ff9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
從二手房的面積分布可以知道负芋,廣州二手房面積在50平米-100平米的占比最大。
###聚類分析
對二手房價格嗜愈、關注人數(shù)旧蛾、面積進行Kmeans聚類
```'''聚類分析'''
print('-----開始聚類分析-----')
# 缺失值處理:直接將缺失值去掉
cluster_data = house_data[['interest_adj','area_adj','house_price']].dropna()
#將簇數(shù)設為3
K_model = KMeans(n_clusters=3)
alg = K_model.fit(cluster_data)
print('------聚類中心------')
center = pd.DataFrame(alg.cluster_centers_, columns=['關注人數(shù)','面積','房價'])
cluster_data['label'] = alg.labels_ print(center)
if __name__ == '__main__':
main()
聚類中心
從聚類中心的結(jié)果可知,可以將二手房從房價蠕嫁、關注人數(shù)锨天、面積三方面分為3類,分別為
| 類別 | 關注人數(shù) | 面積 |房價|
| : -------- | :-----: | :----: | :----: |
| 1 | 高 | 低 | 低|
| 2 | 中 | 中 | 中|
| 3 | 低 | 高 | 高|
由上述整理結(jié)果可以知道剃毒,廣州二手房面積低(75平米)病袄、房價低(155萬)的房源關注人數(shù)最高。從側(cè)面也可以推斷廣州二手房的房價水平大多集中在155萬上下赘阀。
所以從營銷和用戶體驗的角度來看益缠,網(wǎng)站應該在廣告和列表頁的默認排序中應該給予總價155萬,面積75屬性的二手房源更高的權(quán)重基公。這個類別的房源可以吸引最多的用戶關注幅慌。