利用Python在统计局网站爬取统计年鉴

环境

1、环境搭建

爬取统计局需要用到几个常用的库。除此之外,由于需要下载,所以还需要用到下载模块。这里使用的是我自己编写的一个下载类,存放于modules中。关于它的源代码和使用方法,详解伪造cookie爬取网站通用模块(附CSDN爬取范例)

源代码:

import urllib.parse
import urllib.request
import ssl
import bs4
from modules import *
import re
import pandas


# 开启表单提取
ssl._create_default_https_context = ssl._create_unverified_context
# 定义headers,统计局不需要cookie,所以简单定义一个访问头就可以了
headers = {'Cache-Control': 'no-cache', # 将Cache-Control设置成no-cache比较稳妥
           'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'}

2、设置一些常用选项

设置年份的范围,以指定需要爬取的报告。最好是指定15年之前的,因为这之后统计年鉴从excel格式改成了图片格式,无法直接获取。
设置表格等宽。

# 定义需要查询的年份
choiceYear = []
for i in range(2005, 2015):
    choiceYear.append(f'{i}年')
# 设置等宽
pandas.set_option('display.unicode.east_asian_width', True)

3、统计局有个网页,专门用于跳转到不同年份。可以通过这个网页获取年份对应的网址。

图片

# 建立request
url = r'http://www.stats.gov.cn/tjsj/ndsj/'
req = urllib.request.Request(url=url, headers=headers, method="GET")
respon = urllib.request.urlopen(req)
html = respon.read().decode('utf8')

# 解析存储了年份和网址对应关系的网页部分
soul = bs4.BeautifulSoup(html, features='lxml')
urlList = soul.find_all('td', align="center", valign="middle")

# 将年份和网页的对应关系,存入字典{年:网址},并转为pandas对象
urlDict = {}
for i in urlList:
    if i.a.string in choiceYear:
        urlDict[i.a.string] = i.a["href"]
dfUrl = pandas.DataFrame.from_dict(data=urlDict, orient="index", columns=['网址'])

4、这一步需要基于统计局网站构建规律去获取文件存储的位置。

基本思路如下:

  1. 对于上面获取的每一个年鉴网址,将根目录改成left.htm,就可以获取年鉴大纲;
  2. 解析大纲网址,在所有<a>标签内搜索和定位需要的关键字,比如个体就业人数
  3. 对于搜索和定位到的<a>标签,调用其href属性,便获得了个体就业人数对应的网址
  4. 将网址的根目录类型改成.xls(.htm->.xls),便获取了文件存储网址(xls版本)

源代码:

for index in dfUrl.index:
    # 改造value以获取网页框架内,左边框对应的值
    subValue = urllib.parse.urljoin(dfUrl.loc[index, '网址'], 'left.htm')

    # 对value进行访问并解析内容
    subReq = urllib.request.Request(
        url=subValue, headers=headers, method="GET")
    subRespon = urlopen(subReq)
    subHtml = subRespon.read().decode('gbk')

    # 提取解析内容中存储于li标签的财政支出信息
    subSoul = bs4.BeautifulSoup(subHtml, features='lxml')
    pattern = re.compile('[^和]个体就业人数( *)\(')
    subString = subSoul.find_all(name='a', string=pattern)[0].string

    # 提取网址
    subHref = subSoul.find_all(name='a', string=pattern)[0]["href"]

    # 将网址资源的后缀从.htm改成.xls
    subHref = subHref.replace('.htm', '.xls')

    dfUrl.loc[index, '标签'] = subString
    dfUrl.loc[index, '文件位置'] = urllib.parse.urljoin(
        dfUrl.loc[index, '网址'], subHref)

5、下载

如果上一步顺利下来,那么就获取了每个年鉴报告的下载地址,存储于pandas.DataFrame对象的文件位置里。这样就可以对报告进行下载。
源代码:

# 定义存储文件的位置
path = './out/'
for index in dfUrl.index:
    Downunit(url=dfUrl.loc[index, '文件位置'],
             path=path + index + '.xls', threadnum=3).Download()
  • 5
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大尾巴鱼_root

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值