全部代码以及分析见GitHub:https://github.com/dta0502/NBSPRC-spider
详细分析见我的个人博客:国家统计局的统计用区划代码和城乡划分代码爬虫-(二)总体实现
页面分析
这里我分析一下页面,为后面的页面解析做准备。我就拿2016年的页面做下分析:2016年统计用区划代码和城乡划分代码(截止2016年07月31日)。
省级页面分析
省级信息提取
我们进入到2016年统计用区划代码和城乡划分代码(截止2016年07月31日)这个页面,然后用chrome的“检查”工具看下我们要找的信息在哪。
这里我们需要爬取省级名称、省内市级信息的子链接这两个参数。
我们从图中可以发现,左边页面每一行对应的XPath路径为:
//tr[@class="provincetr"]
然后一行中每个省的信息在下一级的td标签内:
td/a/text()
td/a/@href
下级链接获取
省级页面的URL:
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/index.html
下级页面的URL(我这里以浙江省
为例):
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/33.html
页面中提取到的信息(我这里以浙江省
为例):
33.html
所以我们可以通过如下方式获取真实的URL保存到一个列表中:
url = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/index.html"
# provinceLink = "33.html"
provinceURL = url[:-10] + provinceLink
市级页面分析
市级信息提取
我们进入到浙江省中。具体的分析跟上面的省级页面分析类似,不再赘述。下面是市级页面分析图:
下级链接获取
市级页面的URL:
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/33.html
下级页面的URL(我这里以杭州市
为例):
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/33/3301.html
页面中提取到的信息(我这里以杭州市
为例):
33/3301.html
区级页面分析
区级信息提取
我们进入到杭州市中。具体的分析跟上面的省级页面分析类似,不再赘述。下面是区级页面分析图:
下级链接获取
区级页面的URL:
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/33/3301.html
下级页面的URL(我这里以上城区
为例):
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/33/01/330102.html
页面中提取到的信息(我这里以上城区
为例):
01/330102.html
街道页面分析
街道信息提取
我们进入到上城区中。具体的分析跟上面的省级页面分析类似,不再赘述。下面是街道页面分析图:
下级链接获取
街道页面的URL:
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/33/01/330102.html
街道页面的URL(我这里以湖滨街道
为例):
http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/33/01/02/330102003.html
页面中提取到的信息(我这里以湖滨街道
为例):
02/330102003.html
居委会页面分析
居委会信息提取
我们进入到湖滨街道中。具体的分析跟上面的省级页面分析类似,不再赘述。下面是居委会页面分析图:
这里已经到了最底层,没有下级链接了。
国家统计局的统计用区划代码和城乡划分代码爬取—第一版
下面我们开始一步步爬取过程。
导入库
import requests
from lxml import etree
import csv
主页面爬取过程
url = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/index.html"
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'}
这里需要注意一下,国家统计局的统计用区划代码和城乡划分代码网页的编码为gb2312
。一般我都采用下面的代码来获取页面:
data = requests.get(url,headers = headers).text
但是在碰到这个编码方式时会出现乱码,所以做出如下改变:
response = requests.get(url,headers = headers)
response.apparent_encoding
'GB2312'
response.encoding = response.apparent_encoding
data = response.text
页面解析过程
省级名称、URL获取
selector = etree.HTML(data)
provinceList = selector.xpath('//*[@class="provincetr"]')
provinceList
[<Element tr at 0x54a4c88>,
<Element tr at 0x54b4148>,
<Element tr at 0x54b4188>,
<Element tr at 0x54b41c8>]
for i in provinceList:
provinceName = i.xpath('td/a/text()')
provinceLink = i.xpath('td/a/@href')
下面是根据获取到的每个省的链接进行补全,得到真实的URL。
provinceURL = provinceLink
for i in range(len(provinceLink)):
for j in range(len(provinceLink[i])):
provinceURL[i][j][0] = url[:-10] + provinceLink[i][j][0]
provinceURL[0:2]
['http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/11.html',
'http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/12.html']
市级代码、URL获取
cityCode = [] #第二维的数组
cityLink = []
cityName = []
for provURL in provinceURL:
response = requests.get(provURL,headers = headers)
response.encoding = response.apparent_encoding
data = response.text
selector = etree.HTML(data)
cityList = selector.xpath('//tr[@class="citytr"]')
#下面是抓取每一个城市的代码、URL
Code = [] #第一维的数组:里面存储了一个省下辖的市的信息
Link = []
Name = []
for i in cityList:
Code.append(i.xpath('td[1]/a/text()'))
Link.append(i.xpath('td[1]/a/@href'))
Name.append(i.xpath('td[2]/a/text()'))
cityCode.append(Code)
cityLink.append(Link)
cityName.append(Name)
cityCode[3][0:2]
[['140100000000'], ['140200000000']]
cityLink[3][0:2]
[['14/1401.html'], ['14/1402.html']]
cityName[3][0:2]
[['太原市'], ['大同市']]
下面是根据获取到的每个市的链接进行补全,得到真实的URL。
cityLink[0][0][0]
'11/1101.html'
cityURL = cityLink
for i in range(len(cityLink)):
for j in range(len(cityLink[i])