一、准备阶段

1. 网站结构观察

目标网站: http://www.stats.gov.cn/tjsj/ndsj/2020/indexch.htm

观察结果:具体数据以图片的形式展现,在html中留有一个网址,需要一次请求获取图片

*2.搭建Scrapy环境

scrapy startproject statistical_yearbook
scrapy genspider main http://www.stats.gov.cn/tjsj/ndsj/2020/indexch.htm

*3. 代码逻辑

1.利用Scrapy请求网站获得采集目标的图片网址以及图片标题,保存在StatisticalYearbookItem中
2.在pipelines.py中建立MyImagePipeline类继承于ImagesPipeline父类,配合采集到的网址和标题下载图片并命名,保存在images文件夹中

二、代码实现

main.py

import scrapy
from ..items import StatisticalYearbookItemclass MainSpider(scrapy.Spider):name = 'main'# allowed_domains = ['baidu']start_urls = ['http://www.stats.gov.cn/tjsj/ndsj/2020/indexch.htm']def parse(self, response):url = response.xpath('/html/frameset/frameset/frame[1]/@src').extract()[0]yield scrapy.Request(response.urljoin(url),callback= self.parse_one)def parse_one(self,response):#教育部分sel = response.xpath('//*[@id="foldinglist"][21]')item = StatisticalYearbookItem()item['name'] = []item['url'] = []for i in list(zip(sel.css('li a::text').extract()[1:-1],sel.css('li a::attr(href)').extract()[1:-1])):item['name'].append(i[0])item['url'].append(response.urljoin(i[1]))yield item

items.py

import scrapyclass StatisticalYearbookItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()name = scrapy.Field()url = scrapy.Field()

pipelines.py

from itemadapter import ItemAdapter
from scrapy.pipelines.images import ImagesPipeline
import scrapyclass MyImagePipeline(ImagesPipeline):def get_media_requests(self, item, info):# return [Request(x) for x in item.get(self.images_urls_field, [])]for i in zip(item['url'],item['name']):yield scrapy.Request(url=i[0],meta = {'name':i[1]})def file_path(self, request, response=None,info=None,item = None):img_name = request.meta['name'] + '.jpg'return img_name  # 返回文件名def item_completed(self, results, item, info):return item  # 返回给下一个即将被执行的管道类

结果:


三、对结果的进一步处理

从上诉中,我们采集到的结果是一张张jpg格式的图片,无法作为数据分析的数据源,因此需要对采集结果进行格式转换。

1.观察采集结果

发现:第一,图片不是完整的表格结构,只在标题上有表格结构,这增加了提取数据的难度。第二,图片中的数据以表格的形式排列。

2.代码逻辑

1.利用OpenCv对图片进行解析,为图片画上表格线。

① 对图片进行水平投影,根据得到的投影数据可以为表格画上横线
②找到每张图片的通用特征,利用找图得到只有标题表格竖线没有其余任何文字干扰的那一列像素排列,利用OpenCV画上竖线
③为每张图片画上边缘(因为会用到百度ocr识别表格,边缘没有画线会导致识别不准确)
④将处理好的数据上传至百度ocr服务器,获得识别结果,数据提取完毕。

四、图片转Excel代码实现

为图片画出表格

import cv2
import numpy as np
import osdef match_img(img_big,img_small,value = 0.91):h,w,l = cv2.imread(img_small).shapeim = cv2.imread(img_big)img_gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)template = cv2.imread(img_small,0)res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)loc = np.where(res >= value)top_left = (loc[1][0],loc[0][0])return top_left,(top_left[0] + w, top_left[1] + h)
#21-12 22
address_all = "./statistical_yearbook/images"for iii in os.listdir(address_all):address = address_all +'/' + iiiprint(address)address3 = './statistical_yearbook/muban3.png'address1 = './statistical_yearbook/muban1.png'address2 = './statistical_yearbook/muban2.png'imgg = cv2.imread(address)h1, w1,z1 = imgg.shapeimg = cv2.imread(address,0)ret,img1=cv2.threshold(img,100,255,cv2.THRESH_BINARY)h,w=img1.shapea , b = match_img(address,address1)c , d = match_img(address,address3)e , f = match_img(address,address2)x = int((d[0] - c[0])/2) + c[0]y = int((d[1] - c[1])/2) + c[1]x1 = int((b[0] - a[0])/2) + a[0]y1 = int((b[1] - a[1])/2) + a[1]y_s = img1[e[1] ]# y_s = img1[c[1]]s_res = []for i, ii in enumerate(y_s):if ii == 0:s_res.append(i)#划横线(得到值)h,w=img1.shapea=[0 for z in range(0,h)]for i in range(0,h):          #遍历每一行for j in range(0,w):      #遍历每一列if img1[i,j]==0:      #判断该点是否为黑点,0代表黑点a[i]+=1           #该行的计数器加一img1[i,j]=255     #将其改为白点,即等于255a  = [i if i > 3 else 0 for i in a ]b = []for i in range(len(a)):if  a[i] != 0 and a[i - 1] != 0 and a[i + 1] == 0:b.append(i)c = []for i in b:if y <i and i < y1:c.append(i)c = [i + 5 for i in c]'''划横线'''for i in c:cv2.line(imgg,(0,i),(w,i),(0,0,0),1)'''划竖线'''# for i in aaa:#     cv2.line(imgg,(i + x,y),(i + x,y1),(0,0,0),1)for i in s_res:cv2.line(imgg, (i, y - 5), (i, y1), (0, 0, 0), 1)'''划四周'''cv2.rectangle(imgg, (0, 0), (w1, h1), (0, 0, 0), 2)address4 = f'./statistical_yearbook/images_excel/{iii}'cv2.imwrite(address4,imgg)print(iii + '保存完毕')print('-' * 20)

结果:

百度OCR部分:

import os
import sys
import requests
import time
import tkinter as tk
from tkinter import filedialog
from aip import AipOcr# 定义常量
APP_ID = 'nide id'
API_KEY = 'nide key'
SECRET_KEY = 'nide secretkey'
# 初始化AipFace对象
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)# 读取图片
def get_file_content(filePath):with open(filePath, 'rb') as fp:return fp.read()#文件下载函数
def file_download(url, file_path):r = requests.get(url)with open(file_path, 'wb') as f:f.write(r.content)if __name__ == "__main__":root = tk.Tk()root.withdraw()data_dir = filedialog.askdirectory(title='请选择图片文件夹') + '/'result_dir = filedialog.askdirectory(title='请选择输出文件夹') + '/'num = 0for name in os.listdir(data_dir):print ('{0} : {1} 正在处理:'.format(num+1, name.split('.')[0]))image = get_file_content(os.path.join(data_dir, name))res = client.tableRecognitionAsync(image)# print ("res:", res)if 'error_code' in res.keys():print ('Error! error_code: ', res['error_code'])sys.exit()req_id = res['result'][0]['request_id']    #获取识别ID号for count in range(1, 20):    #OCR识别也需要一定时间,设定10秒内每隔1秒查询一次res = client.getTableRecognitionResult(req_id)    #通过ID获取表格文件XLS地址print(res['result']['ret_msg'])if res['result']['ret_msg'] == '已完成':break    #云端处理完毕,成功获取表格文件下载地址,跳出循环else:time.sleep(1)url = res['result']['result_data']xls_name = name.split('.')[0] + '.xls'file_download(url, os.path.join(result_dir, xls_name))num += 1print ('{0} : {1} 下载完成。'.format(num, xls_name))time.sleep(1)

结果:

5.结束

这次爬取总共花了两天时间,其中三分之二的时间都在思考为图片画上表格,对OpenCv的感悟深了一步,对数据采集的手段又多了一份理解!

关于2020年中国统计年鉴(教育部分)的数据采集相关推荐

  1. 【报告分享】2020年中国在线教育创新企业榜单.pdf(附下载链接)

    大家好,我是文文(微信:sscbg2020),今天给大家分享爱分析于2020年8月份发布的报告<2020年中国在线教育创新企业榜单:挖掘在线教育领域创业者.pdf>. 2020年,疫情肆虐 ...

  2. 【报告分享】2020年中国老年教育市场研究报告-IT桔子(附下载)

    今天给大家分享的是  2020年中国老年教育市场研究报告-IT桔子 近十年来,中国老龄人口保持每年3%~5%的年增长率,到2018年50周岁以上人口达到4.53亿人.政府.学界.商界早就注意到了这种现 ...

  3. 最新最全2011年-2020年中国统计年鉴面板数据excel

    最新最全!2011-2020年中国统计年鉴面板数据! 1.数据来源:中国统计年鉴 2.时间跨度:2011-2020年 3.区域范围:全国 4.指标说明: 中国统计年鉴不必多说了吧. 此次整理更新了最全 ...

  4. 【报告分享】 2020年中国在线教育行业研究报告-艾瑞咨询(附下载)

    摘要:风口上的在线教育因其"一半是海水,一半是火焰"的现状,追捧与争议并存 来源:艾瑞咨询 如需查看完整报告和报告下载或了解更多,微信公众号:行业报告智库

  5. 2020年中国职业教育行业白皮书

    更多报告内容,可加微信:chanpin628 领取.

  6. 2021年中国在线教育行业发展规模分析:用户逐渐增多,市场规模不断增长[图]

    随着信息化技术在教育领域中的作用日益提升,财政部对教育领域信息技术的建设投入也不断提升.2021年中国教育信息化的教育财政投入超4000亿元.在国家政策支持.互联网繁荣发展,国民受教育意愿提升以及20 ...

  7. 企业千人千面管理模式_一汽解放青岛汽车有限公司荣获“2020(第十六届)中国企业教育先进单位百强”...

        近日,第十六届中国企业教育百强年度盛典暨2020中国企业培训发展论坛在山东济南召开.中国企业教育百强是由全国22个省市自治区企业培训主管部门联合发起的全国性企业培训评价活动. 一汽解放青岛汽车 ...

  8. 将《2020中国统计年鉴》中的GDP数据换算成不变GDP数据

    文章目录 前言 一.数据来源 二.计算步骤 1.理解一下公式和不同的指数 国内生产总值指数(上一年=100) 国内生产总值指数(1978年=100) 现价GDP: 即当年价GDP,也叫名义GDP,包含 ...

  9. 利尔达荣获“2020年度中国LED行业教育照明25强”

    2021年8月5日,在第八届中国LED首创大会上,深圳市照明与显示工程行业协会发布了2020年度中国LED行业教育照明25强榜单. 利尔达凭借在教育照明行业深耕多年的经验及强大的物联技术研发实力,评选 ...

  10. 兔课网到底怎么样?兔课网荣获2020中国在线教育“金牌教育”三大奖项

    2020年7月18日,兔课网以"突破价值·教育升华"为主题的第五届"互联网在线教育协会节"暨中国教育"金牌教育"颁奖盛典.兔课网凭借在教学. ...

最新文章

  1. 1、初识Server API for JavaScript
  2. 如何让自己的开源库支持cocoapods?
  3. python读音有道词典-centos7安装有道词典(不能发音和取词)
  4. java多线程提高性能写法
  5. C++ new/delete、malloc/free
  6. python顺时针旋转_Python之二维数组N*N顺时针旋转90度
  7. 考究Hadoop中split的计算方法
  8. YBTOJ:前缀匹配(AC自动机)
  9. php流程控制作业题,php流程控制
  10. Scala的partition函数
  11. Perl调用shell命令方法小结
  12. 中国游戏发展史V-02
  13. 【观察】从实践到赋能再到引领,华为释放数据中心无限潜
  14. 【过程挖掘算法3】Heuristic Miner(启发式挖掘算法)
  15. 20 个 Laravel Eloquent 必备的实用技巧 1
  16. 计算机应用基础 第一次形成作业(计算机知识综合测试,在线答题)
  17. “云”上就诊,泽塔云超融合助力医院数字化转型
  18. outlook日历同步_如何将您的Google日历与Outlook同步
  19. 我为什么加入了 TDengine
  20. 奇葩的传参 lt;p gt; 哈哈哈哈 lt;/p gt;

热门文章

  1. matlab实现图像的拼接,MATLAB实现图像拼接算法(求助)
  2. Protel99se中PCB放置焊盘和设置焊盘大小
  3. pytorch学习6:norm函数--范数的理解和计算
  4. 软件项目管理课程设计-数字化校园学工信息系统
  5. java计算机毕业设计工会会员管理系统MyBatis+系统+LW文档+源码+调试部署
  6. web flash 视频播放器代码开源
  7. 机器学习丨如何理解正定矩阵和半正定矩阵
  8. 评委对计算机知识竞赛的提问,评委评分知识竞赛答题软件
  9. 芒果 mysql插件,NoSQL代表:MongoDB(芒果数据库)
  10. CentOS install btsync