python实战之深圳公租房户籍区排位

小编在深圳申请了公租房,虽然可以通过深圳市住房和建设局网站查询到排位信息,却无法直观看出同样资格人群里自己的排名。 于是决定用python爬取轮候库数据,解决这个问题。

爬取说明

爬取网址:http://www.szjs.gov.cn/bsfw/zdyw_1/zfbz/gxfgs/

2018年9月30日爬取结果data.txt

3955877,1,BHJ005840,1,南山区
3955878,2,BHJ005866,1,南山区
3955879,3,BHJ021327,2,南山区
3955880,4,BHJ005848,1,南山区
3955881,5,BHJ006961,4,南山区
3955882,6,BHJ016656,1,南山区
3955883,7,BHJ002199,1,南山区
3955884,8,BHJ029628,3,罗湖区
3955885,9,BHJ016179,3,盐田区
3955886,10,BHJ022242,1,罗湖区

数据分为5列,依次为:用户唯一标识(可以忽略)、排位、备案号、申请人数、户籍所在区。

此次先简单手工将数据文件导入mysql数据库,再用sql检索结果。

后续学习计划:
使用python将文本数据导入mysql;
使用ELK,将数据导入elasticsearch,通过kibana展示分析;
做成在线功能放在的公众号(id:jintianbufaban),让非IT人员使用;

scrapy爬取公租房数据

安装scrapy不再赘述,开始爬取功能开发。
第一步:创建爬虫项目,命名为sz_security_housing

scrapy startproject sz_security_housing

下面是运行后的scrapy工程结构:


第二步:配置items文件items.py

# -*- coding: utf-8 -*-

import scrapy

class SzSecurityHousingItem(scrapy.Item):
    #用户唯一id
    userid = scrapy.Field()
    #轮候排位
    seqno = scrapy.Field()

    #备案回执好
    applyNo = scrapy.Field()

    #申请人数
    num = scrapy.Field()

    #户籍所在地
    place = scrapy.Field()

第三步:在spiders文件夹中新建sz_security_housing.py

# -*- coding: utf-8 -*-
import scrapy
from sz_security_housing.items import SzSecurityHousingItem
from scrapy.http import FormRequest
import json
import time

class SzSecurityHousingSpider(scrapy.Spider):
    #爬虫名,启动爬虫使用
    name = 'szsh'

     #爬虫域
    allowed_domains = ['szjs.gov.cn']

    def start_requests(self):
        url = 'http://bzflh.szjs.gov.cn/TylhW/lhmcAction.do?method=queryYgbLhmcList'

        headers = {
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Encoding': 'gzip, deflate',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Connection': 'keep-alive',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Host': 'bzflh.szjs.gov.cn',
            'Origin': 'http://bzflh.szjs.gov.cn',
            'Referer': 'http://bzflh.szjs.gov.cn/TylhW/lhmcAction.do?method=queryYgbLhmcInfo&waittype=2',
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
        }

        yield scrapy.FormRequest(
            url = url,
            headers = headers,
            formdata = {"pageNumber" : "1", "pageSize" : "10","waittype":"2","num":"0","shoulbahzh":"","xingm":"","idcard":""},
            meta={'pageNum':1,'pageSize':10,"headers":headers},
            callback = self.parse
        )


    def parse(self,response):
        item=SzSecurityHousingItem()
        data  = json.loads(response.body_as_unicode())
        # print(data)
        total = data["total"]
        # print(total)
        list = data["rows"]
        for value in list:
            item['userid']=value['LHMC_ID']
            item['seqno']=value['PAIX']
            item['applyNo']=value['SHOULHZH']
            yield item

        url = 'http://bzflh.szjs.gov.cn/TylhW/lhmcAction.do?method=queryYgbLhmcList'
        meta=response.meta
        prepageNumber=meta["pageNum"]
        pageSize=meta["pageSize"]
        headers=meta["headers"]
        print('finsh scrapy pageNumber:%s'%prepageNumber)
        print(len(list))
        time.sleep( 2 )
        pageNumber=prepageNumber+1
        if len(list) == pageSize:
            requestdata={"pageNumber" : "1", "pageSize" : "1000","waittype":"2","num":"0","shoulbahzh":"","xingm":"","idcard":""}
            requestdata['pageNumber']=str(pageNumber)
            requestdata['pageSize']=str(pageSize)
            meta['pageNum']=pageNumber
            # print(requestdata)
            yield scrapy.FormRequest(
                url = url,
                headers = headers,
                formdata =requestdata,
                meta=meta,
                callback = self.parse
            )

第四步:配置管道文件pipelines.py

# -*- coding: utf-8 -*-

from urllib import request
from lxml import etree
import re

class SzSecurityHousingPipeline(object):
    def process_item(self, item, spider):
        print(item)
        url='http://bzflh.szjs.gov.cn/TylhW/lhmcAction.do?method=queryDetailLhc&lhmcId=%s&waittype=2'%(item['userid'])
        print(url)
        try:
            response = request.urlopen(url,timeout=5)
            page = response.read()
            page = page.decode('utf-8')
            selector = etree.HTML(page)
            content=selector.xpath('//div[@class="leader_intro1"]')[1].xpath('string(.)')
            place = re.search('户籍所在区.*区',content).group().replace('户籍所在区:','')
            item['place']=place
            num=len(selector.xpath('//div[@class="leader_intro1"]'))-1
            item['num']=num
        except Exception:
            print ("Error:%s"%(item['seqno']))
        else:   
            print ("Success:%s"%(item['seqno']))
        ret=str(item['userid'])+','+str(item['seqno'])+","+str(item['applyNo'])+","+str(item['num'])+","+str(item['place'])+"\n"
        saveFile = open('data.txt','a')  
        saveFile.write(ret)  
        saveFile.close()  
        # print(item)

第五步:配置settings.py

BOT_NAME = 'sz_security_housing'

SPIDER_MODULES = ['sz_security_housing.spiders']
NEWSPIDER_MODULE = 'sz_security_housing.spiders'


# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'sz_security_housing (+http://www.yourdomain.com)'

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
    'sz_security_housing.pipelines.SzSecurityHousingPipeline': 300,
}

第六步:在项目根目录运行程序,运行结果保存在data.txt

scrapy crawl szsh

爬取结果data.txt

3955877,1,BHJ005840,1,南山区
3955878,2,BHJ005866,1,南山区
3955879,3,BHJ021327,2,南山区
3955880,4,BHJ005848,1,南山区
3955881,5,BHJ006961,4,南山区
3955882,6,BHJ016656,1,南山区
3955883,7,BHJ002199,1,南山区
3955884,8,BHJ029628,3,罗湖区
3955885,9,BHJ016179,3,盐田区
3955886,10,BHJ022242,1,罗湖区

爬虫结果分析

第一步:数据导入mysql
在mysql中建表T_PRH_DATA

CREATE TABLE `T_PRH_DATA` (
  `USER_ID` int(20) unsigned NOT NULL COMMENT '用户ID',
  `SEQ_NO` int(20) NOT NULL COMMENT '轮候排位',
  `APPLY_NO` varchar(20) NOT NULL DEFAULT '' COMMENT '备案号',
  `NUM` tinyint(4) NOT NULL DEFAULT 0 COMMENT '申请人数',
  `PLACE` varchar(20) NOT NULL DEFAULT '' COMMENT '户籍所在区',
  PRIMARY KEY (`USER_ID`),
  KEY `INDEX_APPLY_NO` (`APPLY_NO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='轮候信息'

导入mysql,这里我以Navicat为例:


剩余的直接下一步,至此数据导入到mysql。

第二步:查询户籍区排名

SELECT T.PLACE,T.NUM,COUNT(1) FROM T_PRH_DATA T 
WHERE T.SEQ_NO <=(SELECT D.SEQ_NO FROM  T_PRH_DATA D WHERE  D.APPLY_NO='备案号')
AND T.PLACE='户籍所在区' 
GROUP BY T.PLACE,T.NUM 

这里排序第10个为例,他(她)属于罗湖区、备案号:BHJ022242


以上这是这次的所有内容,源码地址:https://github.com/tianduo4/sz_security_housing

这是学习python的第一个练手项目,做的不好的请多多包涵。 使用过程中遇到问题,或者有更好建议欢迎留言。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • 《 利用 Python36,基于 Scrapy 框架的爬虫思路 》 (一)引言利用爬虫抓取网页数据已经是常见技能,...
    yannis_lau阅读 1,481评论 0 3
  • 背景 部门(东方IC、图虫)业务驱动,需要搜集大量图片资源,做数据分析,以及正版图片维权。前期主要用node做爬虫...
    字节跳动技术团队阅读 7,639评论 1 67
  • 人生有千百种滋味,品尝到最后,都只留下了一种滋味,就是无奈。生命中的一切花朵都会凋谢,一切凋谢都不可挽回,对此我们...
    鱼耗子阅读 319评论 0 0
  • Swift中的”宏” 写Objective-C的时候常常会用到各种宏定义,但是Swift中貌似没有宏的这种定义,更...
    Originalee阅读 592评论 0 9
  • 有这样一个案例:老师对小明说:小明,这次期中考试你考得不好,下一个阶段你得努力,争取在期末考试取得好成绩。(案...
    孙玉生阅读 274评论 0 1