杭州,是我毕业找工作的首选地,了解到租房价格较高,现通过所学知识对杭州租房价格进行分析。进行数据分析,就要实现对房产信息的可视化,必须拿到数据,后通过numpy,pandas,matplotlib等一些科学计算包进行计算。此项目需要用到爬虫知识,Scrapy框架,数据分析基础。
Scrapy抓取房产信息
1.进入链家官网,分析请求地址
杭州链家租房地址:https://hz.lianjia.com/zufang/
2.创建Scrapy项目
scrapy stratproject lianjia
cd lianjia
scrapy genspider -t crawl zufang lianjia.com
3.编写item
import scrapy
class LianjiaItem(scrapy.Item):
# 租房标题
title = scrapy.Field()
# 租房链接
link = scrapy.Field()
# 租房地址
address = scrapy.Field()
# 租房户型
zone = scrapy.Field()
# 租房大小
meters = scrapy.Field()
# 租房朝向
direction = scrapy.Field()
# 房屋价格
price = scrapy.Field()
# 更新日期
update_date = scrapy.Field()
# 看房人数
num = scrapy.Field()
# 其他信息
other = scrapy.Field()
4.利用xpath解析字段,以房产列表的其中一个为例
我使用的是CrawlSpider,/spiders/zufang.py如下
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from lianjia.items import LianjiaItem
class ZufangSpider(CrawlSpider):
name = 'zufang'
allowed_domains = ['lianjia.com']
start_urls = ['https://hz.lianjia.com/zufang/']
rules = (
Rule(LinkExtractor(allow=r'zufang/'), callback='parse_item', follow=True),
)
def parse_item(self, response):
for each in response.xpath('//li[@data-el="zufang"]/div[@class="info-panel"]'):
item = LianjiaItem()
item["title"] = each.xpath('//h2/a/text()').extract()[0]
item["link"] = each.xpath('//h2/a/@href').extract()[0]
item["address"] = each.xpath('//div[@class="where"]/a/span/text()').extract()[0].replace('\xa0\xa0', '')
item["zone"] = each.xpath('//div[@class="where"]/span[@class="zone"]/span/text()').extract()[0].replace('\xa0\xa0', '')
item["meters"] = each.xpath('//div[@class="where"]/span[@class="meters"]/text()').extract()[0].replace('\xa0\xa0', '')[:-2]
item["direction"] = each.xpath('//div[@class="where"]/span[3]/text()').extract()[0]
item["price"] = each.xpath('//div[@class="price"]/span/text()').extract()[0]
item["update_date"] = each.xpath( '//div[@class="price-pre"]/text()').extract()[0][:-2]
item["num"] = each.xpath('//div[@class="square"]//span[@class="num"]/text()').extract()[0]
item["other"] = each.xpath('string(//div[@class="con"])').extract()[0]
yield item
5.将抓取的数据保存为csv格式
命令如下:
scrapy crawl zufang -o zufang.csv
还有另一个问题,直接通过命令保存csv的话,会发现输出item的顺序不是在items.py或者在scrapy中的顺序,所以要指定csv格式按顺序输出,可参考:scrapy指定item输出项顺序到csv
最后数据就被保存在了zufang.csv中,打开文件,可看到
分析房产信息
1.基本信息统计
利用保存的csv格式文件,使用pandas对其进行统计
import pandas as pda
# 读取数据
data = pda.read_csv('zufang.csv')
# 查看data的类型
print(data.info())
# 自动进行格式转化
data = data.convert_objects(convert_numeric=True)
# 基本统计
print(data.describe())
运行结果:
meters price num
count 5338.000000 5338.000000 5338.000000 # 统计个数
mean 118.945107 9608.551892 0.828962 # 平均数
std 80.278900 10903.589102 1.519768 # 标准差
min 5.500000 1190.000000 0.000000 # 最小值
25% 59.870000 3825.000000 0.000000 # 前分位数
50% 92.270000 5500.000000 0.000000 # 中分位数
75% 174.000000 10000.000000 1.000000 # 后分位数
max 378.000000 68000.000000 8.000000 # 最大值
2.可视化分析可通过折线图和直方图来体现
import pandas as pda
from matplotlib import pylab as pyl
# 读取数据
data = pda.read_csv('zufang.csv')
# 自动进行格式转化
data = data.convert_objects(convert_numeric=True)
# 按meters排序
data = data.sort_values(by=['meters'])
# 将行与列进行转置
data = data.T
# 显示折线图
pyl.subplot(2, 1, 1)
pyl.title('meters/price')
pyl.xlabel('meters')
pyl.ylabel('price')
x1 = data.values[2]
y1 = data.values[6]
pyl.plot(x1, y1)
pyl.subplot(2, 1, 2)
pyl.title('meters/num')
pyl.xlabel('meters')
pyl.ylabel('num')
x2 = data.values[2]
y2 = data.values[7]
pyl.plot(x2, y2)
pyl.show()
# 显示直方图
pyl.subplot(2, 1, 1)
x1 = list(data.values[2])[:-1]
pyl.hist(x1)
pyl.subplot(2, 1, 2)
x2 = list(data.values[6])[:-1]
pyl.hist(x2)
pyl.show()
3.可视化图像
4.将以上代码抽象成Analyzer类
import pandas as pda
from matplotlib import pylab as pyl
class Analyzer(object):
def __init__(self, filename):
# 读取数据
self.data = pda.read_csv(filename)
def convert(self):
try:
# 自动进行格式转化
self.data = self.data.convert_objects(convert_numeric=True)
except FutureWarning:
pass
# 查看data的类型
print('----打印数据类型----')
print(self.data.info())
def tongji(self):
"""基本统计"""
self.convert()
print(self.data.describe())
def sort_by_meters(self):
"""按meters排序"""
self.data = self.data.sort_values(by=['meters'])
def line_chart(self):
"""显示折线图"""
self.sort_by_meters()
# 将行与列进行转置
self.data = self.data.T
pyl.subplot(2, 1, 1)
pyl.title('meters/price')
pyl.xlabel('meters')
pyl.ylabel('price')
x1 = self.data.values[2]
y1 = self.data.values[6]
pyl.plot(x1, y1)
pyl.subplot(2, 1, 2)
pyl.title('meters/num')
pyl.xlabel('meters')
pyl.ylabel('num')
x2 = self.data.values[2]
y2 = self.data.values[7]
pyl.plot(x2, y2)
pyl.show()
def histogram(self):
"""显示直方图"""
# self.sort_by_meters()
pyl.subplot(2, 1, 1)
x1 = list(self.data.values[2])[:-1]
pyl.hist(x1)
pyl.subplot(2, 1, 2)
x2 = list(self.data.values[6])[:-1]
pyl.hist(x2)
pyl.show()
if __name__ == "__main__":
analyzer = Analyzer(filename='zufang.csv')
analyzer.tongji()
analyzer.line_chart()
analyzer.histogram()