國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

MushRain 發表於 2022-05-04
統計

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

0、前言

在做一些預測的時候常常會用到國家統計局的資料,之前寫的一些爬蟲也沒能夠複用,今天又遇到了這個問題,反覆檢查之後發現國家統計局的各種資料其實都遵循同一套邏輯,而只需掌握這一個邏輯,我們便可以想要啥就要啥。

1、初見

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

經典https不安全🤪🤪🤪🤪🤪

一進到這個網站我立馬熟練的點開了,各項資料分類,這裡有國家月度資料,國家年度資料,國家季度資料,也有分各個省的資料。

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

我今天對2021的出生率死亡率非常感興趣,於是我立馬快速切換到年度資料。

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

隨後飛速的在左側側邊欄找到人口指標下的人口出生率、死亡率和自然增長率。

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

我也如期拿到了資料

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

但是總感覺過程不夠絲滑,我能不能讓這個過程更高效一點?

2、分析

我開啟了F12神奇,冒充開發者。

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

結果發現原來發現,不論什麼資料基本都是同一個介面:

https://data.stats.gov.cn/easyquery.htm
paramters = {
    "m": "QueryData",
    "dbcode": "fsnd",
    "rowcode": "zb",
    "colcode": "sj",
    "wds": [], 
    "dfwds": [{"wdcode":"zb","valuecode":"A0303"}],
    "k1": 1651675561678
    "h": 1,
}

這請求方法是GET,引數又只有這麼幾個,那麼如果我解析了這幾個引數,我豈不是想爬什麼爬什麼,想爬什麼時間段就爬什麼時間段?

  • m:無需多言,就是請求資料
  • dbcode:我是在想不出這個單詞表示的意義,不過當我看到後面fsnd的時候,我知道這應該是分省年度的縮寫,我想這大抵對應首頁的幾個資料種類。
  • rowcode:直譯為行編碼,一看後面的字,原來是zb招標啊,
  • colcode:直譯為列編碼,後面的sj應該是時間的縮寫
  • wds:不明所以
  • dfwds:不明所以,不過這個欄位和上面wds應該很重要
  • k1:為時間戳
  • h:好像就是一個常量

簡單分析之後我立馬上試了一試

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

OK的完全沒有問題,那麼接下來就是指定需求了:

  1. 所有指標一視同仁
  2. 爬取任意久遠的時間段(官網只提供了幾個有限的選項)

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

  1. 可以自由切換不同的省,不同的資料類(國家年度,分省年度):顯然微調dbcode即可實現

3、問題解決

3.1、所有指標一視同仁

預想一次性處理所有指標,那麼就先得對指標的命名情況有一個瞭解

dfwds: [{"wdcode":"zb","valuecode":"A0302"}]

dfwds中我們發現那個熟悉的詞語拼音縮寫,zb 指標,後面的應該就對應於這個指標的程式碼

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

可以發現A0302完美對應這個指標在指標樹中位置。同時我觀察到10號元素不是A10而是A0A,所以可以得出大部分資料都是滿10進A隨後按照字典序提升。

3.2、對任意時間段爬取

官網只提供了一段時間的爬取,但是我想要任意時間段的資料。嘗試檢視了近20年資料之後,我發現這裡的dfwds變了,現在變成了時間索引,且valuecode也 變了,變成最近20,我自然聯想到直接把20改一改,沒準就能行。

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

果然如期返回了!那我們的推斷沒有錯。

現在我想爬取任意一個指標的任意時間段的資料,經過測試發現原來dfwds真的是一個陣列,可以放多個條件

"dfwds": "[{\"wdcode\":\"zb\",\"valuecode\":\"A0202\"},{\"wdcode\":\"sj\",\"valuecode\":\"LAST50\"}]"

把指標資訊和時間約束都加到這個欄位,從而實現了我們最初的需求。

我立馬寫成程式碼測試

4、測試

python nationStatisticdata.py --zb A0302 --sj LAST50 --dbcode hgnd --output 湖北省人口出生死亡自然增長.csv

國家統計局通用資料爬取思路+程式碼實現 (超級舒暢的一次爬取經歷)

非常順利哈哈哈哈!

5、程式碼

GitHub: https://github.com/HuangXingjie2002/Mush-Spider