杭州,是我毕业找工作的首选地,了解到租房价格较高,现通过所学知识对杭州租房价格进行分析。进行数据分析,就要实现对房产信息的可视化,必须拿到数据,后通过numpy,pandas,matplotlib等一些科学计算包进行计算。此项目需要用到爬虫知识,Scrapy框架,数据分析基础。
Scrapy抓取房产信息
1.进入链家官网,分析请求地址
杭州链家租房地址:
2.创建Scrapy项目
scrapy stratproject lianjiacd lianjiascrapy genspider -t crawl zufang lianjia.com
3.编写item
import scrapyclass 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 scrapyfrom scrapy.linkextractors import LinkExtractorfrom scrapy.spiders import CrawlSpider, Rulefrom lianjia.items import LianjiaItemclass 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格式按顺序输出,可参考:
最后数据就被保存在了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 numcount 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 pdafrom 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 pdafrom matplotlib import pylab as pylclass 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()