在链家网上爬取北京、上海、广州、深圳、天津、青岛的房价,绘制热力图、箱线图。
首先爬取房价信息。
from urllib import request
from bs4 import BeautifulSoup as bs
import re
import pandas as pd
temp0 = []
temp0 = {"price": temp0}
df = pd.DataFrame(temp0) #建立空dataframe用来后续存储数据
region = "hz" #地名简写
pages = 73 #链家网的房价页数
for i in range(1, pages+1):
res = request.urlopen('https://' + region +'.fang.lianjia.com/loupan/pg' + str(i) + '/')
html_data = res.read().decode('utf-8')
Soup = bs(html_data, 'html.parser')
print(i, "/", pages) #观察进度
p1 = Soup.find_all('div', class_="main-price") # 找到价格标签,class后面要加下划线
price_str = str(p1)
pattern = re.compile(r'.+\s.+元') #有些房子是按套卖,排除这些房子,只找按平米卖的房子
temp = re.findall(pattern, price_str)
temp2 = "".join(temp) #将list转为str
pattern2 = re.compile(r'\d{5,6}') #找出房价数据
price = re.findall(pattern2, temp2)
dic_price = {"price": price}
df_temp = pd.DataFrame(dic_price)
df = pd.concat([df, df_temp], axis=0, ignore_index=True) #按行合并两个dataframe
region = region.upper()
file_name = region + "HousePrice.csv"
df.to_csv(file_name)
热力图使用folium包绘制使用pip安装folium
pip3 install folium
导入需要的包
import pandas as pd
import numpy as np
import folium
import webbrowser
from folium.plugins import HeatMap
import matplotlib.pyplot as plt
整理爬取的房价数据,并平均值,画出箱线图。
df.columns = (["Beijing", "Shanghai", "Guangzhou", "Shenzhen", "Tianjin", "Qingdao", "Hangzhou"])
df.boxplot()
plt.show()
df.columns = (["北京市", "上海市", "广州市", "深圳市", "天津市", "青岛市", "杭州市"]) #设置列名
mean_price = df.mean() #求每列平均值
mean_price = pd.DataFrame(mean_price, columns=["price"]) #将求出的平均值存为dataframe并设置列名
下载中国城市的经纬度信息点击打开链接,保存为csv。
cities = pd.read_csv("Cities.csv", sep=",")
cities = cities[["cities", "lon", "lat"]]
cities.set_index("cities", inplace=True) #修改index方便后面检索
将城市经纬度信息与房价均值放在一个dataframe中。
my_cities = pd.DataFrame(columns=["lon", "lat"]) #新建空dataframe保存城市经纬度和房价数据
for i in mean_price.index:
new_position = []
lat = cities["lat"][i] #获取纬度值
lon = cities["lon"][i] #获取精度值
new_position.append(lat)
new_position.append(lon)
my_cities.loc[i] = new_position
my_cities = pd.concat([my_cities, mean_price], axis=1) #将经纬度与房价均价合并在一个dataframe
my_cities.to_csv("mean_price.csv", encoding="utf_8_sig") #加上encoding="utf_8_sig"解决中文乱码问题
绘制热力图
lst = np.array(my_cities).tolist() #转化dataframe为list,为后面画热力图用,先转成ndarray,在用tolist()
map_osm = folium.Map(location=[35,110],zoom_start=5) #绘制Map,开始缩放程度是5倍
HeatMap(lst).add_to(map_osm) # 将热力图添加到前面建立的map里
file_path = r"house_price.html"
map_osm.save(file_path) # 保存为html文件
webbrowser.open(file_path) # 默认浏览器打开