文档章节

scrapy爬虫练习-链家楼盘数据及可视化分析

zoulala
 zoulala
发布于 2018/09/18 17:50
字数 1108
阅读 283
收藏 3

项目githup地址

项目的目的

  • 爬取链家楼盘数据
  • 数据可视化分析

工具

  • python3
  • scrapy

创建项目

scrapy安装及使用可以参考教程scrapy,在pycharm软件的Terminal上操作:scrapy startproject scrapys 生成的目录如下:

项目创建好了,下一步分析网页数据

爬取数据

  • 打开主网页

打开链家官网,设定城市,以广州新楼盘为例‘https://gz.fang.lianjia.com/loupan/’ 网站类似如下:

当然可以爬取更多城市的数据,url中gz改为城市代码即可,可以设置城市列表自动来爬取各个城市数据。

  • 需求字段

网页中我们能看到楼盘列表,并且含有很多页,每页大概10个楼盘,每个楼盘包含的信息有(名称、房屋类型、地点、面积、均价、总价、标签等),我们选定爬取的字段有: 楼盘名称、房屋类型、面积、均价、总价、标签,6个字段数据。

在项目items.py文件中添加字段类:

class LianjiaItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field()
    type = scrapy.Field()
    area_range = scrapy.Field()
    start_price = scrapy.Field()
    mean_price = scrapy.Field()
    tags = scrapy.Field()
  • 网页分析

按F12进入页面代码分析,点击元素选择图标->在选择左边需要的字段信息,在代码区就能看到所在的位置,如下图:

也可以ctrl+f在输入框中搜索,或用xpath获取需要的信息,框中用输入//div[@class="resblock-name"]也能看到有10条信息。

各个字段的位置信息如下:

总路径:'//ul[@class="resblock-list-wrapper"]/li'
name :'div/div[@class="resblock-name"]/a[@class="name"]/text()'
type :'div/div[@class="resblock-name"]/span[@class="resblock-type"]/text()'
area_range :'div/div[@class="resblock-area"]/span/text()'
mean_price :'div/div[@class="resblock-price"]/div[@class="main-price"]/span[@class="number"]/text()'
mean_unit :'div/div[@class="resblock-price"]/div[@class="main-price"]/span[@class="desc"]/text()'
start_price :'div/div[@class="resblock-price"]/div[@class="second"]/text()'
tags :'div/div[@class="resblock-tag"]/span/text()'

  • 数据爬取程序

分析好了数据获取路径,我们开始构建爬虫程序。 我们在spiders文件夹下新建一个爬虫脚本lianjia_spider.py:

import re
import scrapy
from scrapy.http import Request
from scrapys.items import LianjiaItem

# scrapy用yield异步处理网页,想顺序处理网页,可以参考https://stackoverflow.com/questions/6566322/scrapy-crawl-urls-in-order

class LJ_houseSpider(scrapy.Spider):
    name = "lianjia"
    allowed_domains = ["gz.fang.lianjia.com"]  # 允许爬取的域名,非此域名的网页不会爬取
    start_urls = [
        "http://gz.fang.lianjia.com/loupan/"
    ]

    def start_requests(self):
        """
        这是一个重载函数,它的作用是发出第一个Request请求
        :return:
        """
        # 请求self.start_urls[0],返回的response会被送到回调函数parse中
        yield Request(self.start_urls[0])

    def parse(self, response):

        max_page_text = response.xpath('//div[@class="page-box"]/@data-total-count').extract()
        nums = re.findall(r'(\d+)',max_page_text[0])
        max_num = int(nums[0])
        max_num //= 10
        print('max page>>>>>>>>>>>',max_num)
        for i in range(max_num):
            print(i)
            url = self.start_urls[0]+'pg'+str(i+1)
            yield Request(url, callback=self.extract_content, priority=max_num-i)  #该方法及其他的Request回调函数必须返回一个包含 Request 及(或) Item 的可迭代的对象

        

    def extract_content(self, response):
        paths = response.xpath('//ul[@class="resblock-list-wrapper"]/li')
        items = []
        for sel in paths:
            item = LianjiaItem()
            name = sel.xpath('div/div[@class="resblock-name"]/a[@class="name"]/text()').extract()
            type = sel.xpath('div/div[@class="resblock-name"]/span[@class="resblock-type"]/text()').extract()
            area_range = sel.xpath('div/div[@class="resblock-area"]/span/text()').extract()
            mean_price = sel.xpath('div/div[@class="resblock-price"]/div[@class="main-price"]/span[@class="number"]/text()').extract()
            mean_unit = sel.xpath('div/div[@class="resblock-price"]/div[@class="main-price"]/span[@class="desc"]/text()').extract()
            start_price = sel.xpath('div/div[@class="resblock-price"]/div[@class="second"]/text()').extract()
            tags = sel.xpath('div/div[@class="resblock-tag"]/span/text()').extract()

            item['name'] = name[0] if name else 'NAN'
            item['type'] = type[0] if type else 'NAN'
            item['area_range'] = re.findall(r'\d+',area_range[0])+re.findall(r'-[\d+](.)+',area_range[0]) if area_range else []
            item['mean_price'] = mean_price[0] +' '+ ' '.join(re.findall(r'\w[/]\w',mean_unit[0])) if mean_price and mean_unit else 'NAN'
            item['start_price'] = re.findall(r'\d+',start_price[0])+re.findall(r'[\d+](.)+[/]',start_price[0]) if start_price else []
            item['tags'] = tags
            items.append(item)
        return items
  • 数据存储到excel

将数据存储于excel文件中,在主目录下新建一个存数据的文件夹results;修改pipelines.py如下

import xlwt

class ScrapysPipeline(object):
    def process_item(self, item, spider):
        return item

class LianJiaPipeline(object):
    def __init__(self):
        self.filename = 'results/tianjing_houses.xls'
        self.outputbook = xlwt.Workbook()
        self.table = self.outputbook.add_sheet('sheet1', cell_overwrite_ok=True)
        self.nrow = 0

    def process_item(self, item, spider):
        self.table.write(self.nrow, 0, item['name'])
        self.table.write(self.nrow, 1, item['type'])
        self.table.write(self.nrow, 2, ' '.join(item['area_range']))
        self.table.write(self.nrow, 3, item['mean_price'])
        self.table.write(self.nrow, 4, ' '.join(item['start_price']))
        self.table.write(self.nrow, 5, ' '.join(item['tags']))

        self.nrow += 1

    def close_spider(self, spider):
        self.outputbook.save(self.filename)
  • 运行爬虫

在命令行输入scrapy crawl lianjia 或者通过pycharm来运行,在主目录建文件main.py:

#coding=utf8
from scrapy import cmdline
cmdline.execute("scrapy crawl lianjia".split())

点击运行,结果如下:

数据可视化

(待续...)

© 著作权归作者所有

zoulala
粉丝 5
博文 38
码字总数 32619
作品 0
私信 提问
屌丝想买房,爬取南京20000多套二手房|上篇

这是菜鸟学Python的第111篇原创文章 阅读本文大概需要3分钟 去年楼市暴涨,今年楼市一天一个价格,也不知道什么时候会跌. 北上广一线城市高的离谱. 南京,成都,合肥算是二线城市,但是房价也...

菜鸟学python
2017/10/20
0
0
一个月入门Python爬虫,快速获取大规模数据

数据是创造和决策的原材料,高质量的数据都价值不菲。而利用爬虫,我们可以获取大量的价值数据,经分析可以发挥巨大的价值,比如: 豆瓣、知乎:爬取优质答案,筛选出各话题下热门内容,探索...

Python开发者
2018/04/25
0
0
从爬虫到机器学习预测,我是如何一步一步做到的?

作者:xiaoyu 微信公众号:Python数据科学 知乎:python数据分析师 前情回顾 前一段时间与大家分享了北京二手房房价分析的实战项目,分为分析和建模两篇。文章发出后,得到了大家的肯定和支持...

路远
2018/08/28
0
0
Python 爬虫进公司必会项目

WechatSogou [1]– 微信公众号爬虫。 基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫,返回结果是列表,每一项均是公众号具体信息字典。 github地址: https://github...

徐代龙
2017/12/20
0
0
7个Python爬虫实战项目教程

有很多小伙伴在开始学习Python的时候,都特别期待能用Python写一个爬虫脚本,实验楼上有不少python爬虫的课程,这里总结几个实战项目,如果你想学习Python爬虫的话,可以挑选感兴趣的学习哦;...

实验楼
2017/12/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JS其他类型值转化为Boolean类型规则

本文转载于:专业的前端网站➤JS其他类型值转化为Boolean类型规则 由于最近在笔试的时候,发现好多关于其他类型转化为Boolean类型的题目,因此总结一下! 一、String类型转化为Boolean 1.转化...

前端老手
25分钟前
4
0
EurekaClient自动装配及启动流程解析

在上篇文章中,我们简单介绍了EurekaServer自动装配及启动流程解析,本篇文章则继续研究EurekaClient的相关代码 老规矩,先看spring.factories文件,其中引入了一个配置类EurekaDiscoveryClie...

Java学习录
31分钟前
5
0
析构函数是否必须为虚函数?为何?

在C++中,基类指针可以指向一个派生类的对象。如果基类的析构函数不是虚函数,当需要delete这个指向派生类的基类指针时,就只会调用基类的析构函数,而派生类的析构函数无法被调用。容易造成...

天王盖地虎626
32分钟前
4
0
【TencentOS tiny】深度源码分析(7)——事件

引言 大家在裸机编程中很可能经常用到flag这种变量,用来标志一下某个事件的发生,然后在循环中判断这些标志是否发生,如果是等待多个事件的话,还可能会if((xxx_flag)&&(xxx_flag))这样子做...

杰杰1号
35分钟前
6
0
聊聊nacos client的ServerHttpAgent

序 本文主要研究一下nacos client的ServerHttpAgent HttpAgent nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/http/HttpAgent.java public interface HttpAgent { ......

go4it
42分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部