Scrapy爬取二手房成交记录并进行数据分析与展示(一)

  • 前言
  • 数据获取
    • 分析html
    • 创建Item
    • 解析Response
      • Item信息爬取
      • 后续Request
    • 数据清洗
    • 保存到数据库
    • 总结

前言

本文分为三部分。第一部分为数据获取,主要介绍Scrapy爬取大连的二手房信息的成交记录。第二部分简单的介绍如何把现有的爬虫改写成分布式爬虫。第三部分为数据分析,主要介绍通过Python的一些库及Tableau对获取的数据的分析尝试预测下个季度的热点区域。如果还有机会的话,通过下个季度的真实数据验证自己的猜测。个人认为爬虫只是获取数据的一种手段,重点放在数据分析上,刚刚入手,很多知识也是摸索着来的,大家多多指教!

数据获取

通过Scrapy爬取二手房的成交信息,后来改成了分布式爬取,以下会进行详细介绍。

分析html

在想要爬取的网页按下F12打开开发者工具。在Elements Tab下,通过鼠标选择来查看自己想要爬取对应的tag。
注意,Elements下显示的html有时候可能和Response返回的html有出入

发现每个成交记录信息在ListContent下的li中,爬取li下a的href,可以得到对应的详情页面。


在详情页面我们找到了想要的信息,包括标题、成交日期、单价、实际成交金额、期望成交金额、成交周期等。

创建Item

根据我们想要的信息编写Item,如下:

class ShellItem(scrapy.Item):Title = scrapy.Field()DealDate = scrapy.Field()UnitPrice = scrapy.Field()ActualPrice = scrapy.Field()ExpectPrice = scrapy.Field()DealPeriod = scrapy.Field()Orientation = scrapy.Field()BuiltYear = scrapy.Field()Duration = scrapy.Field()Name = scrapy.Field()Structure = scrapy.Field()Area = scrapy.Field()Longitude = scrapy.Field()Latitude = scrapy.Field()

解析Response

我们爬取的逻辑是,先从第一页爬取每个成交记录的详情页地址,再进入对应的详情页地址把想要的信息爬取出来。当第一页爬取完后,继续爬取第二页,以此类推,直到所有页面都被爬取完成。

Item信息爬取

需要事先声明的是一开始我只爬取了每个根页面房源对应的基础信息

后来考虑到之后要改成分布式爬虫,这样不好做去重,所以信息统一从详情页面爬取。
代码如下:

    def parse(self, response):rooms = response.css('.listContent li')for room in rooms:item = ShellItem()detail_url = room.css('.info .title a::attr(href)').extract_first()yield scrapy.Request(url=detail_url, meta={'item': item}, callback=self.parse_detail)def parse_detail(self, response):item = response.meta['item']item['Title'] = response.css('.main::text').extract_first()item['DealDate'] = response.css('.main strong::text').extract_first()item['ActualPrice'] = response.css('.dealTotalPrice i::text').extract_first()item['UnitPrice'] = response.css('.price b::text').extract_first()item['ExpectPrice'] = response.css('.msg span:first-child label::text').extract_first()item['Duration'] = response.css('.msg span:nth-child(2) label::text').extract_first()item['Orientation'] = response.css('.base .content li:nth-child(7)::text').extract_first()item['BuiltYear'] = response.css('.base .content li:nth-child(8)::text').extract_first()return item

需要注意的是,这里我们爬取了二级页面,所以需要把item通过meta的形式传入到parse_detail方法中。

后续Request

以上只爬取了首页,我们还需要爬取下一页内容直到所有页面都被爬取完成。再次查看html中的Elements
发现,如下:

<a href="/chengjiao/pg2" data-page="2">下一页</a>

结果在解析Response中,发现没有下一页节点,这和我们在Elements中看到的是不一样的。在我一筹莫展之际,突然发现它的父节点有page-date的attribute:

<div class="page-box house-lst-page-box" comp-module="page" page-url="/chengjiao/pg{page}"
page-data="{"totalPage":100,"curPage":1}">
...
</div>

通过page-data的信息我们就可以自己组装出下一页的网页地址,实现翻页爬取。我们重写parse方法,代码如下:

    def parse(self, response):rooms = response.css('.listContent li')for room in rooms:item = ShellItem()detail_url = room.css('.info .title a::attr(href)').extract_first()yield scrapy.Request(url=detail_url, meta={'item': item}, callback=self.parse_detail)doc = pq(url=home_url, allow_redirects=False)div = doc('.page-box.house-lst-page-box')pages_string = div.attr('page-data')pages = re.findall('\d+', pages_string)max_page = int(pages[0])current_page = int(pages[1])while current_page <= max_page:url = root_url + str(current_page)yield scrapy.Request(url=url, callback=self.parse)

数据清洗

在爬取到需要的信息后,我们需要进行数据清洗,形成统一的格式方便存储到数据库中。
比如Title是名字、户型及面积的合体,需要拆分成3个子项。再比如成交价格后面有“万”字作为单位,为了以后数据分析方便,需要去掉单位。一般使用正则的方式就可以解决,在这里就不赘述了。
最重要的是,既然是分析热点区域,关于位置的信息是不能少的,我们现在获得了成交小区的名字,但是并不知道它的地理位置即经纬度。为了获得他们的经纬度,我们需要调用高德地图的API。有不少文章都介绍了如何调用高德地图的API,不是很复杂,我们只要传入名字就可以返回对应的经纬度等信息。代码如下:

    def extract_location(self, name):key = 'xxx'name = '大连' + namelocation = quote(name)base = 'https://restapi.amap.com/v3/geocode/geo?address=' + location + '&output=XML&key='url = base + keydoc = pq(requests.get(url).content)str = doc("location").text()return str.split(",")

key是注册高德API服务后提供给你,在这里我使用了Request请求页面,PyQuery解析返回的xml。其实应该是可以直接使用Scrapy.Request和Response.css来请求、解析页面的。

保存到数据库

我们爬取的信息并不复杂,完全可以保存到csv文件中。不过为了练习,也为了后续更改成分布式爬虫方便,我选择把爬取的信息保存到MongoDB中。为此我们需要引入pymongo。与数据库的交互并不是很复杂,我们只需要把做完数据清洗的数据做insert操作插入到数据库里就可以了,在这里就不赘述了。部分代码如下:

    def open_spider(self, spider):self.client = pymongo.MongoClient(self.mongo_uri)self.db = self.client[self.mongo_db]def process_item(self, item, spider):name = item.__class__.__name__self.db[name].insert(dict(item))return itemdef close_spider(self, spider):self.client.close()

总结

经过以上操作,执行scrapy crawl xxx就可以爬取数据了,源码稍后会上传到GitHub。目前只实现了单机爬取,在下一篇文章我会简单介绍如何改写成分布式爬虫,及我在改写分布式爬虫时遇到的坑。

Scrapy爬取二手房成交记录并进行数据分析与展示(一)相关推荐

  1. Scrapy爬取二手房信息+可视化数据分析

    本篇介绍一个scrapy的实战爬虫项目,并对爬取信息进行简单的数据分析.目标是北京二手房信息,下面开始分析. 网页结构分析 采用安居客网页信息作为二手房的信息来源,直接点击进入二手房信息的页面. 每页 ...

  2. Scrapy爬取重庆安居客二手房并存入mysql数据库(下)

    上篇中我们获取了重庆的一二级区(Scrapy爬取重庆安居客二手房并存入mysql数据库(上)),这一篇我们根据二级区获取相应的二手房信息. 初始化数据库 创建二手房信息数据库表,house表存放二手房 ...

  3. Scrapy爬取美女图片续集 (原创)

    上一篇咱们讲解了Scrapy的工作机制和如何使用Scrapy爬取美女图片,而今天接着讲解Scrapy爬取美女图片,不过采取了不同的方式和代码实现,对Scrapy的功能进行更深入的运用. 在学习Scra ...

  4. Python爬虫 - scrapy - 爬取妹子图 Lv1

    0. 前言 这是一个利用python scrapy框架爬取网站图片的实例,本人也是在学习当中,在这做个记录,也希望能帮到需要的人.爬取妹子图的实例打算分成三部分来写,尝试完善实用性. 系统环境 Sys ...

  5. [Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(四) —— 应对反爬技术(选取 User-Agent、添加 IP代理池以及Cookies池 )

    上一篇:[Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(三) -- 数据的持久化--使用MongoDB存储爬取的数据 最近项目有些忙,很多需求紧急上线,所以一直没能完善< 使用 ...

  6. scrapy爬取——阿里招聘信息

    scrapy爬取--阿里招聘信息 爬取网站地址: https://job.alibaba.com/zhaopin/positionList.htm 1.创建项目 进入项目目录 输入cmd进入都是窗口创 ...

  7. 怎样使用Scrapy爬取NVD网站上的数据

    关于Scrapy的使用,我已经写过很多篇博客了: Python爬虫框架Scrapy的基本使用方法(以爬取加密货币GitHub链接为例)_蛐蛐蛐的博客-CSDN博客 使用Python爬虫框架Scrapy ...

  8. [Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(二) —— 编写一个基本的 Spider 爬取微博用户信息

    上一篇:[Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(一) -- 新建爬虫项目 在上一篇我们新建了一个 sina_scrapy 的项目,这一节我们开始正式编写爬虫的代码. 选择目标 ...

  9. [Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(三) —— 数据的持久化——使用MongoDB存储爬取的数据

    上一篇:[Python 爬虫] 使用 Scrapy 爬取新浪微博用户信息(二) -- 编写一个基本的 Spider 爬取微博用户信息 在上一篇博客中,我们已经新建了一个爬虫应用,并简单实现了爬取一位微 ...

最新文章

  1. Leader晋升失败,CTO说,没有商业敏感度,迟早被淘汰
  2. 内网渗透测试:隐藏通讯隧道技术(上)
  3. Oracle中nolog干什么用的,在oracle中,sqlplus / nolog是做什么用的
  4. 如何优雅的设计和使用缓存?
  5. 如何用python制作九九乘法表_Python一行代码给儿子制作九九乘法表
  6. Linux安装glibc(升级版本)
  7. 俄罗斯游戏软件:C语言应用初步感受
  8. 雪城大学信息安全讲义 二、Unix 安全概览
  9. web开发快餐式入门指南 0. 写在前面
  10. pythonxml读写_python xml读取和写入
  11. Mysql Oracle Tidb对空值的处理
  12. 退休的姐妹们,你们还打工吗?
  13. send的内容ajax,Ajax中send方法的使用
  14. c++ map 析构函数_面向偷懒的编程 - C/C++项目中使用Go的分布式系统库
  15. Lottie动画测试工具
  16. 计算机学win7画图,Windows7系统画图工具怎么打开?
  17. Scrum板与Kanban如何抉择?ivhbyfphe板与按照drpxcj
  18. Python编写微信打飞机小游戏(二)
  19. 微信小程序反编译wxss文件缺失_微信小程序反编译 wxss 丢失问题
  20. Android使用VAD检测是否说话

热门文章

  1. PDMS插件_三维文字工具_Text3D
  2. [小知识] 移动端设备号常见类型
  3. 单片机引脚控制继电器最简单的电路方式
  4. 【转载】我的编程之路——知识管理与知识体系
  5. mysql新建数据库
  6. ASCII码 和 Base64编码
  7. 从六一宝宝节“共情消费”看苏宁易购“专注好服务”理念
  8. 作为一个新手程序员该如何成长?http://www.codeceo.com/article/how-new-programmer-grow.html#0-tsina-1-19469-397232819
  9. 用计算机修图属于,手机APP和电脑修图有什么区别?能否用手机替代电脑修图? | 摄影早自习第1082天...
  10. SNS游戏主题餐厅即将上线了!