百木园-与人分享,
就是让自己快乐。

国家统计局数据采集

概述

国家统计局的公开数据真实性强,宏观且与我们的生活息息相关。

因此,采集此数据作为数据分析实验的数据再好不过。

采集过程

采集各种公开数据的第一步就是分析网页。

数据展示界面

上面的图是国家统计局年度数据的界面。 左边是数据分类的树形菜单,右边是每个菜单点击之后显示的数据,可以设置年份来过滤数据。

采集数据分类树

根据页面的情况,首先,我们需要采集树形菜单中的数据,然后再根据菜单的分类来依次采集右边的数据。 这样可以避免采集的遗漏。

爬虫采集数据一般有 2 种情况:

  • 采集 html 页面,然后分析其中的结构,提取出数据
  • 查看是否存在获取数据的 API,直接从 API 中提取数据

通过分析网页的加载过程,发现国际统计局的数据是有 API 的,这就节省了很多时间。 API 信息如下:

host: \"https://data.stats.gov.cn/easyquery.htm\"
method: POST
params: id=zb&dbcode=hgnd&wdcode=zb&m=getTree

通过 python 的 requests 库模拟 POST 请求就可以获取到树形菜单中的数据了。

def init_tree(tree_data_path):
data = get_tree_data()
with open(tree_data_path, \"wb\") as f:
pickle.dump(data, f)

def get_tree_data(id=\"zb\"):
r = requests.post(f\"{host}?id={id}&dbcode=hgnd&wdcode=zb&m=getTree\", verify=False)
logging.debug(\"access url: %s\", r.url)
data = r.json()

for node in data:
if node[\"isParent\"]:
node[\"children\"] = get_tree_data(node[\"id\"])
else:
node[\"children\"] = []

return data

直接调用上面的 init_tree 函数即可,树形菜单会以 json 格式序列化到 tree_data_path 中。
序列化的目的是为了后面采集数据时可以反复使用,不用每次都去采集这个树形菜单。(毕竟菜单是基本不变的)

根据分类采集数据

有了分类的菜单,下一步就是采集具体的数据。 同样,通过分析网页,数据也是有 API 的,不用采集 html 页面再提取数据。

host: \"https://data.stats.gov.cn/easyquery.htm\"
method: GET
params: 参数有变量,具体参见代码

采集数据稍微复杂一些,不像采集树形菜单那样访问一次 API 即可,而是遍历树形菜单,根据菜单的信息访问 API。

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

import logging
import os
import pickle
import time

import pandas as pd
import requests

host = \"https://data.stats.gov.cn/easyquery.htm\"
tree_data_path = \"./tree.data\"
data_dir = \"./data\"

def data(sj=\"1978-\"):
tree_data = []
with open(tree_data_path, \"rb\") as f:
tree_data = pickle.load(f)

traverse_tree_data(tree_data, sj)

def traverse_tree_data(nodes, sj):
for node in nodes:
# 叶子节点上获取数据
if node[\"isParent\"]:
traverse_tree_data(node[\"children\"], sj)
else:
write_csv(node[\"id\"], sj)

def write_csv(nodeId, sj):
fp = os.path.join(data_dir, nodeId + \".csv\")
# 文件是否存在, 如果存在, 不爬取
if os.path.exists(fp):
logging.info(\"文件已存在: %s\", fp)
return

statData = get_stat_data(sj, nodeId)
if statData is None:
logging.error(\"NOT FOUND data for %s\", nodeId)
return

# csv 数据
csvData = {\"zb\": [], \"value\": [], \"sj\": [], \"zbCN\": [], \"sjCN\": []}
for node in statData[\"datanodes\"]:
csvData[\"value\"].append(node[\"data\"][\"data\"])
for wd in node[\"wds\"]:
csvData[wd[\"wdcode\"]].append(wd[\"valuecode\"])

# 指标编码含义
zbDict = {}
sjDict = {}
for node in statData[\"wdnodes\"]:
if node[\"wdcode\"] == \"zb\":
for zbNode in node[\"nodes\"]:
zbDict[zbNode[\"code\"]] = {
\"name\": zbNode[\"name\"],
\"cname\": zbNode[\"cname\"],
\"unit\": zbNode[\"unit\"],
}

if node[\"wdcode\"] == \"sj\":
for sjNode in node[\"nodes\"]:
sjDict[sjNode[\"code\"]] = {
\"name\": sjNode[\"name\"],
\"cname\": sjNode[\"cname\"],
\"unit\": sjNode[\"unit\"],
}

# csv 数据中加入 zbCN 和 sjCN
for zb in csvData[\"zb\"]:
zbCN = (
zbDict[zb][\"cname\"]
if zbDict[zb][\"unit\"] == \"\"
else zbDict[zb][\"cname\"] + \"(\" + zbDict[zb][\"unit\"] + \")\"
)
csvData[\"zbCN\"].append(zbCN)

for sj in csvData[\"sj\"]:
csvData[\"sjCN\"].append(sjDict[sj][\"cname\"])

# write csv file
df = pd.DataFrame(
csvData,
columns=[\"sj\", \"sjCN\", \"zb\", \"zbCN\", \"value\"],
)
df.to_csv(fp, index=False)

def get_stat_data(sj, zb):
payload = {
\"dbcode\": \"hgnd\",
\"rowcode\": \"zb\",
\"m\": \"QueryData\",
\"colcode\": \"sj\",
\"wds\": \"[]\",
\"dfwds\": \'[{\"wdcode\":\"zb\",\"valuecode\":\"\'
+ zb
+ \'\"},{\"wdcode\":\"sj\",\"valuecode\":\"\'
+ sj
+ \'\"}]\',
}

r = requests.get(host, params=payload, verify=False)
logging.debug(\"access url: %s\", r.url)
time.sleep(2)

logging.debug(r.text)
resp = r.json()
if resp[\"returncode\"] == 200:
return resp[\"returndata\"]
else:
logging.error(\"error: %s\", resp)
return None

代码说明:

  • tree_data_path = \"./tree.data\" : 这个是第一步序列化出的树形菜单数据
  • 采集的数据按照树形菜单中的每个菜单的编号生成相应的 csv
  • 树形菜单的每个叶子节点才有数据,非叶子节点不用采集
  • 调用 data 函数来采集数据,默认是从 1978 年的数据开始采集的
  • 采集结果

    本次采集的结果有 1917 个不同种类的数据。
    下载地址: https://databook.top/data/de9d8cc6-2bab-4ef1-b09f-8dcf83c32648/detail

    来源:https://www.cnblogs.com/wang_yb/p/14636575.html
    图文来源于网络,如有侵权请联系删除。

    未经允许不得转载:百木园 » 国家统计局数据采集

    相关推荐

    • 暂无文章