Python 爬虫收集数据以生成可视化图形,看看上海的房租有多高?
pk哥使用Python爬虫分析上海房租。我们用数据来看看上海的租金有多高。
本次出租房源信息来自链家网。使用Python收集数据并制作成可视化图形。
渲染
这次我使用Python对链家网的样本数据进行索引并制作了条形图。从图中可以看到,部分地区房源相对较少,比如崇明、金山以及上海周边地区。
根据样本数据,我取了上海各个区域的平均租金。该图表显示了最高和最低租金。
这个平均租金作为参考意义不大,因为租金还与房屋面积和公寓类型有关。我们用词云图来看看出租物业的主要建筑类型。字体越大,说明该户型所占比例越大。
户型词云图显示,出租物业最受欢迎的户型是3房2厅和2房2厅。如果和熟悉的朋友一起旅行,租这种类型的房子也是不错的选择。这种类型的房子一般位于小区内,环境较好。
所以,为了让数据更具指示性,我用Python计算出了每个区域公寓每平方米的平均月租金,并绘制成条形图。该图显示了每平方米的最高月租金和每平方米的最低月租金。静安区均价最高为160.79元,奉贤区均价最低为29.77元。
项目环境
语言:Python 3
编辑器:Pycharm
主要思想
1.使用Python爬虫收集链家网的房屋信息。
2。根据自己的需要将公寓信息组织成可视化图形。
租房数据采集
租房数据采集来源为链家网。打开链家网页面,按F12打开页面调试功能。页面信息可以在请求库中轻松找到。
代码分析
首先提取一页的租赁信息,并以字典的形式保存。我提取的信息包括出租屋名称、户型、面积、租金、每平方米租金。以字典的形式返回此数据。一些最重要的代码如下。 (左右滑动即可看到所有代码)
def RoomInfo(html):
soup = BeautifulSoup(html, 'lxml')
titles = soup.select('#house-lst div.info-panel h2 a')
styles = soup.select('#house-lst div.info-panel div.col-1 div.where span.zone span')
squares = soup.select('#house-lst div.info-panel div.col-1 div.where span.meters')
prices = soup.select('#house-lst div.info-panel div.col-3 div.price span')
data = []
for ti, st, sq, pr, in zip(titles, styles, squares, prices):
info = {}
title = ti.get_text().strip() # 出租房屋标题
info['标题'] = title
style = st.get_text().strip() # 出租房屋户型
info['户型'] = style
square = sq.get_text().strip()[0:-2] # 出租房屋面积
info['面积(平方)'] = square
price = pr.get_text().strip() # 出租房屋房租
info['房租(元/月)'] = price
price_square = round(float(price)/float(square), 3) # 出租房屋每平米房租
info['每平方房租(元)'] = price_square
data.append(info)
return data
复制代码
接下来,将上面提取的信息保存到 csv 文件中。文件名是通过提取url的元素得到的,因为每个区域的租赁信息链接后面都带有一个汉字。拼音如浦东。
一行代表一组公寓数据,列数据对应上述函数得到的标题、户型、面积、租金和房租。我把所有数据都保存在E盘的“zufang”目录下,这个目录是必须提前创建的。好的目录,保存的部分文件截图如下。
实现csv文件格式的公寓数据存储功能的代码如下。 (左右滑动查看所有代码)
def write2csv(url, data):
name = url.split('/')[-3]
print('正在把数据写入{}文件'.format(name)) # 以链接中的地区拼音给文件命名
with open('E:\\zufang\\{}.csv'.format(name), 'a', newline='', encoding='utf-8-sig') as f:
fieldnames = ['标题', '户型', '面积(平方)', '房租(元/月)', '每平方房租(元)'] # 控制列的顺序
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
print("写入成功")
复制代码
分页时,我们需要指定页数。该区域中的列表数量显示在不同区域的页面上。每页显示30条列表,所以基本情况是页数等于列表数。源总数除以 30。所有地区的最大列表页数为 100 页。然而,在某些区域,列表数量除以 30 会导致超过 100 页。不知道链家多余的房源去哪儿了。如果数量超过 100,则按 100 处理。处理后还有一种情况,有的地方房子比较少,不到30栋,所以只有一页信息。
def get_page_num(url):
html = get_html(url)
soup = BeautifulSoup(html, 'lxml')
nums = soup.select('body div.wrapper div.main-box.clear div.con-box div.list-head.clear h2 span')
for n in nums:
total = int(n.get_text())
if total < 30:
num = 1
return num
else:
num = total / 30
if num > 100:
num = 100
return num
else:
return num
复制代码
接下来,您将获得不同地区的所有房屋信息,包括浦东区、闵行区、宝山区、普陀区、杨浦区、长宁区、松江区、嘉定区、黄浦区、静安区、闸北区、虹口区、青浦区、奉贤区、金山区、崇明区、上海郊区、地铁出租、所有房源。我为每个索引页面设置了随机等待时间,以避免链家服务器过载并阻塞IP地址。 (左右滑动查看所有代码)
for area in ['pudong', 'minhang', 'baoshan', 'putuo', 'yangpu', 'changning', 'songjiang', 'jiading', 'huangpu',
'jingan', 'zhabei', 'hongkou', 'qingpu', 'fengxian', 'jinshan', 'chongming', 'shanghaizhoubian',
'ditiezufang', 'all']:
base_url = 'https://sh.lianjia.com/zufang/{}/pg1/'.format(area)
num = get_page_num(base_url)
for page in range(1, int(num) + 1):
url = 'https://sh.lianjia.com/zufang/{}/pg{}/'.format(area, page)
html = get_html(url)
data = RoomInfo(html)
write2csv(url, data)
time.sleep(int(format(random.randint(0, 5))))
复制代码
数据可视化处理
接下来,我们对接收到的数据进行可视化处理。我将以创建房屋类型的词云图为例,从保存的csv文件中获取所需的列数据并进行计算。一个元素出现了多少次,并消除了不相关的信息以创建词云。文章开头出现的房屋类型。
import csv
import os
from pyecharts import WordCloud
def all_list(arr):
result = {}
for i in set(arr):
result[i] = arr.count(i)
return result
os.chdir('E:\\zufang')
with open('all.csv', 'rt', encoding="utf-8") as csvfile:
reader = csv.reader(csvfile)
column = [row[1] for row in reader]
result = all_list(column)
result.pop('户型') # 去掉字典中的无关信息
key = list(result.keys())
value = list(result.values())
wordcloud = WordCloud(width=1500, height=700)
wordcloud.add('', key, value, word_size_range=[20, 100])
wordcloud.render('E:\\pye\\style.html') # 在指定目录下生成文件
作者:brucepk
来源:掘金
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。