我们的目标网址:http://data.stats.gov.cn/easyquery.htm?cn=C01
里面可以查询国家统计局发布的各种数据,这里我们针对人口进行爬取,其它项方法都是一样。
提示:看之前需要了解 HTTP 协议和 XMLHttpRequest 方法。
推荐用谷歌浏览器
首先进入下面这个页面:
import time
ntime = int(round(time.time() * 1000))
来段代码结合来说:
# 我采用requests库
import requests
import time
# 用来获取 时间戳
def gettime():
return int(round(time.time() * 1000))
if name == ‘main’:
# 用来自定义头部的
headers = {}
# 用来传递参数的
keyvalue = {}
# 目标网址(问号前面的东西)
url = ‘http://data.stats.gov.cn/easyquery.htm’
# 头部的填充
headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) ' \
'AppleWebKit/605.1.15 (KHTML, like Gecko) ' \
'Version/12.0 Safari/605.1.15'
# 下面是参数的填充,参考图10
keyvalue['m'] = 'QueryData'
keyvalue['dbcode'] = 'hgnd'
keyvalue['rowcode'] = 'zb'
keyvalue['colcode'] = 'sj'
keyvalue['wds'] = '[]'
keyvalue['dfwds'] = '[]'
keyvalue['k1'] = str(gettime())
# 发出请求,使用get方法,这里使用我们自定义的头部和参数
r = requests.get(url, headers=headers, params=keyvalue)
# 打印返回过来的状态码
print r.status_code
# 打印我们构造的url
print r.url
# 打印返回的数据
print r.text
好像没有什么问题,但是如果你仔细看看返回过来的数据就会发现有问题,根本不是我们想要的数据,虽然也是 json 结构,但是里面的数据完全是错的。所以如何获取到我们想要的呢,返回到谷歌浏览器,进行如下操作。
先在如上的页面刷新一次,然后下面会有三条记录,然后依次点击人口 -> 总人口,然后又会多出两条记录。
滑到最下面,可以看到 dfwds 字段有东西了,之前的都没有的 (参考图 10),原来还要传参数。修改代码:
# 我采用requests库
import requests
import time
# 用来获取 时间戳
def gettime():
return int(round(time.time() * 1000))
if __name__ == '__main__':
# 用来自定义头部的
headers = {}
# 用来传递参数的
keyvalue = {}
# 目标网址(问号前面的东西)
url = 'http://data.stats.gov.cn/easyquery.htm'
# 头部的填充
headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) ' \
'AppleWebKit/605.1.15 (KHTML, like Gecko) ' \
'Version/12.0 Safari/605.1.15'
# 下面是参数的填充,参考图10
keyvalue['m'] = 'QueryData'
keyvalue['dbcode'] = 'hgnd'
keyvalue['rowcode'] = 'zb'
keyvalue['colcode'] = 'sj'
keyvalue['wds'] = '[]'
# keyvalue['dfwds'] = '[]'
# 上面那个修改成下面这个
keyvalue['dfwds'] = '[{"wdcode":"zb","valuecode":"A0301"}]'
keyvalue['k1'] = str(gettime())
# 发出请求,使用get方法,这里使用我们自定义的头部和参数
r = requests.get(url, headers=headers, params=keyvalue)
# 打印返回过来的状态码
print r.status_code
# 打印我们构造的url
print r.url
# 打印返回的数据
print r.text
再来看看结果
如果耐心点可以看出,我们获取了从 2008 到 2017 的所有数据,然后我们就可以从里面进行解析数据进行存储来。但是如果要找 2000 年的呢,看下面。
从上图可以看见这个页面还提供搜索功能,于是我们也可以进行搜索。比如 2000 年。
经过我几个小时到摸索,我终于搞出来了,针对于目前的情况,我们是每一次都进行一次请求,得到数据后就断了,如果要进行搜索,我们必须要建立一个对话 (Session),然后在这个对话中把 dfwds 改成上图中的内容就可以成功获取。
代码修改:
# 我采用requests库
import requests
import time
# 用来获取 时间戳
def gettime():
return int(round(time.time() * 1000))
if __name__ == '__main__':
# 用来自定义头部的
headers = {}
# 用来传递参数的
keyvalue = {}
# 目标网址(问号前面的东西)
url = 'http://data.stats.gov.cn/easyquery.htm'
# 头部的填充
headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) ' \
'AppleWebKit/605.1.15 (KHTML, like Gecko) ' \
'Version/12.0 Safari/605.1.15'
# 下面是参数的填充,参考图10
keyvalue['m'] = 'QueryData'
keyvalue['dbcode'] = 'hgnd'
keyvalue['rowcode'] = 'zb'
keyvalue['colcode'] = 'sj'
keyvalue['wds'] = '[]'
keyvalue['dfwds'] = '[{"wdcode":"zb","valuecode":"A0301"}]'
keyvalue['k1'] = str(gettime())
# 发出请求,使用get方法,这里使用我们自定义的头部和参数
# r = requests.get(url, headers=headers, params=keyvalue)
# 建立一个Session
s = requests.session()
# 在Session基础上进行一次请求
r = s.get(url, params=keyvalue, headers=headers)
# 打印返回过来的状态码
print r.status_code
# 修改dfwds字段内容
keyvalue['dfwds'] = '[{"wdcode":"sj","valuecode":"2000"}]'
# 再次进行请求
r = s.get(url, params=keyvalue, headers=headers)
# 此时我们就能获取到我们搜索到的数据了
print r.text
至此一次完整获取数据的过程就结束了,上面代码进行修改就可以获取很多东西的数据,当然如果弄清各个字段的意思就更好了。如有错误请及时告知。
转自:https://www.jianshu.com/p/9827a052da91