基于Python的一网通办网公开数据爬取与实现
2019-10-12丁晓阳王兰成
丁晓阳 王兰成
摘 要:目的:上海一网通办网作为典型的政府线上办公与数据公开网站,其设计具有广泛的代表性,本文通过研究与实际测试,实现了全站数据的抓取,为其他网站的数据爬取提供参考,为公共网络的大数据分析奠定基础。方法:通过谷歌浏览器查看对应网站的消息请求头和网页源码;将网站所有网页中的数据分为A类(网页数据直接获取类)和B类(网页数据异步获取类)。利用Python调用re、request和lxml等内置库与第三方库,模拟浏览器向服务器发送请求,对服务器返回的html和Json等格式的数据进行解析,对于异步传输的数据需要在浏览器中找到对应的json文件,再次查看消息頭并发送请求获取异步数据,过滤出目标数据,最后写入到CSV格式的文本中。结果:经过研究与测试,爬虫成功爬取上海一网通办网上所有数据,爬取效率较高,爬取数据具有非常高的准确性;其中数据爬取的难点在于定位异步请求数据的文件和模拟浏览器请求异步数据。
关键词:公开情报;情报获取Python;爬虫;数据爬取
引言
美国中央情报局前局长希伦科特曾指出:“ 大多数公开情报来源于诸如外国书刊、科技调查报告、图片、商业分析报告、报纸和新闻广播,以及精通国际关系的人提供的综合性看法之类的普遍渠道”。【[1]樊合成,陈树宁,王守宏.试论公开情报研究[J]. 现代情报,2004,01:52-54.】 如今,大多的情报存在于网络中,对网络上大量的公开数据进行爬取与分析会产生巨大的价值,这同样对于获取信息优势至关重要。而作为计算机与互联网融合孕育而生的大数据已不再只停留于IT行业,而是被广泛应用于各个领域,美国率先将大数据上升为国家战略并将其定义为“未来的新石油”。【[2]许阳,王程程.大数据推进政府治理能力现代化:研究热点与发展趋势[J]. 电子政务,2018,11:101-112.】我国在网络大数据应用方面的起步较晚,网络公开数据的爬取、分析与利用不够充分。本文利用典型的政府线上办公网:上海一网通办,实现对网站数据全部精准抓取,为其他公共网络的数据爬取提供支持与参考。本文所提供的爬取方法具有较高通用性,可以支持其他一般性网页的数据爬取。
1 工具介绍
为了简单、轻便的编写脚本,本文所涉及的爬虫未利用其他集成开发环境,而是选择的Python的官方开发工具IDLE。在爬虫编写过程中共涉及8个内置和第三方库分别为:os、 sys、time、re、json、requests、chardet和lxml。其中requests库用于模拟浏览器向服务器发送请求;chardet用于检测数据编码格式,以便用对数据进行解析;lxml库用于高效解析HTML和XML文件,支持XPath解析方式。数据存储选择的是通用的CSV格式,主要是方便以后导入各类数据库或者直接进行Excel编辑。
2 爬虫实现
编写网络爬虫是从互联网上获取数据的重要方式,通常一个网页的数据需要浏览器发送多次请求以获取不同类型的数据,例如,上海一网通办主页于2019年7月8日请求网页内容共发送88个请求。如果需要爬取的数据属于网页中的A类数据,那么此类数据在网页中直接获取,这类数据是网页中数据存在的普遍形式,爬取时的操作也相对比较简单。如果需要爬取的数据属于网页中的B类数据,此类数据通常需要执行网页中的JavaScript代码才能获取,也就是需要再次发送数据请求,此类数据获取相对比较难。本文分别就A类和B类两类数据,从一网通办网站上分别选取:市委领导信箱和户籍办理两个典型的模块进行分析和说明。
2.1 市委领导信箱爬虫设计与实现
市委领导信箱公开数据爬取设计流程大致为:第一,获取邮件列表目录所在的网页数据,利用chatdet库分析网页编码格式并解析数据,从中爬取每个邮件的网络地址并发送请求。第二,从目录首页获取爬取的总页码。第三,分析每一个邮件目录页的网址规则,自动翻页,遍历每页邮件目录页,并向每一个邮件网络地址发送请求并爬取邮件内容。第四,清洗邮件内容并写入CSV文件。
以下是该模块爬虫实现的源代码:
(已隐去导入库代码)
#step1:获取邮件列表目录所在的网页数据
r = requests.get('http://wsxf.sh.gov.cn/xf_swldxx/feedback_list.aspx?PageName=hfxd')#获取信箱目录列表网页数据
page_number = 0 #新建预存信箱列表页数的全局变量
dirpath = '一网通办'+ time.strftime("%Y-%m-%d", time.localtime())#预存数据文件保存路径
if not os.path.exists(dirpath): #确认文件保存路径是否存在,如果不存在就新建相应路径
os.mkdir(dirpath)
def grabble_mail(r):#定义爬取每一个目录页的爬虫函数
global dirpath
try:
r.raise_for_status() #确认请求是否相应正常
print('爬取正常')
except:
print('错误状态码:'+ str(r.status_code))
#利用chatdet库分析网页编码格式,并解析数据
charinfo = chardet.detect(r.content) #分析网页的编码格式
print('目标网页 编码信息:')
print(charinfo)
r_text = r.content.decode(charinfo['encoding'],errors='ignore') #用分析得到的编码格式解析数据
cl_text = r_text.replace('\n','') #数据清理去掉数据中的回车符号
r_tree = etree.HTML(r_text) #利用lxml中的etree库解析html文件
#step2:确定邮件目录页总页数
if not re.findall('\d+',r.url):#通过首页数据中的“共几页”确定总爬取页数
global page_number
page_number = int(re.findall('第\d+页 共(\d+)页 共\d+条',r_tree.xpath('//*[@id="main"]/tbody/tr/td[2]/div//text()')[5])[0])
print('共有'+ str(page_number)+ '个目录页')
#step3:爬取每一页中的每一个邮件网络地址并再次访问每一个网络地址爬取邮件内容
a_taglist = r_tree.xpath('//*[@id="FBList"]/tbody//a')#爬取邮件目录列表中每个邮件的网络地址
try:
for a in range(len(a_taglist)):
try:
sub_r = requests.get('http://wsxf.sh.gov.cn/xf_swldxx/' + a_taglist[a].attrib["href"])
sub_charinfo = chardet.detect(sub_r.content)
print('爬取:'+ a_taglist[a].attrib["href"])
sub_r_text = sub_r.content.decode(sub_charinfo['encoding'], errors='ignore')
sub_cl_text = sub_r_text.replace('\r', '')
sub_r_tree = etree.HTML(sub_cl_text)
sub_title = sub_r_tree.xpath('//*[@id="MainContent_LaTitle"]//text()')[0]
sub_date = sub_r_tree.xpath('//*[@id="MainContent_LaDate"]//text()')[0]
sub_content = sub_r_tree.xpath('//*[@id="MainContent_LaContent"]//text()')[0]
sub_pbdate = sub_r_tree.xpath('//*[@id="MainContent_LaHFDate"]//text()')[0]
sub_departm = sub_r_tree.xpath('//*[@id="MainContent_LaDeptment"]//text()')[0]
sub_disposition = sub_r_tree.xpath('//*[@id="MainContent_LaDisposition"]//text()')[0]
#step4:把邮件内容清除掉回车和逗号之后写入csv文件,因为回车和逗号会影响CSV结构
with open(dirpath + '/' + '市委领导信箱' + '-' + time.strftime("%Y-%m-%d", time.localtime()) + '.csv', 'a+') as f:
f.write(sub_title.replace('\n', '').replace(',','').strip())
f.write(',')
f.write(sub_date.replace('\n', '').replace(',','').strip() )
f.write(',')
f.write(sub_content.replace('\n', '').replace(',','').strip() )
f.write(',')
f.write(sub_pbdate.replace('\n', '').replace(',','').strip() )
f.write(',')
f.write(sub_departm.replace('\n', '').replace(',','').strip() )
f.write(',')
f.write(sub_disposition.replace('\n', '').replace(',','').strip() )
f.write('\n')
except:
print('錯误子链接')
continue
except:
print('错误链接')
grabble_mail(r) #真实执行爬取首页中每一个邮件的内容
#step3:分析每一个邮件目录页的网址规则,自动翻页,爬取所有页面中邮件内容
jr = requests.get(page_url,headers = headers)
charinfo = chardet.detect(jr.content)
jr_text = jr.content.decode(charinfo['encoding'], errors='ignore')
#step3:利用json库解析数据保存为Python字典格式
pyjs = json.loads(jr_text)
3 测试与评价
对本文实现的爬虫进行爬取效率和准确率测试,爬虫运行的环境参数为:Windows10 专业版操作系统,Intel(R) Core(TM) i3 CPU M 350 @2.27GHz处理器,4.00GB RAM,网络为第四代移动通信技术。爬取市委领导信箱27页共524封信件用时519.89秒,数据准确率为100%,因为网站的信件结构规范,无噪音数据。户籍信息的数据量少爬取用时5.25秒,数据准确率为100%。
从实际测试结果看,爬虫的效率较高,每封信件的爬取用时保持在1秒以内,数据爬取的准确率极高,该爬虫的实用性高。
4 结束语
本文所设计与实现的爬虫具有通用性,对于一般性网站公开数据的爬取具有很好的借鉴意义。其主要有以下几个特点:
(1)爬虫的代码简洁、轻巧,设计思路清晰直观
(2)爬虫的爬取策略适用性强,对于一般网站的公开数据爬取有较强借鉴意义
(3)自动化程度高,自动翻页遍历访问所有二级链接爬取数据
(4)爬取效率与准确率较高,为下一步数据分析奠定良好基础
参考文献:
[1]樊合成,陈树宁,王守宏.试论公开情报研究[J]. 现代情报,2004,01:52-54.
[2]许阳,王程程.大数据推进政府治理能力现代化:研究热点与发展趋勢[J].电子政务,2018,11:101-112.
[3]李培.基于Python的网络爬虫与反爬虫技术研究[J].计算机与数字工程,2019(06):1415-1496.
[4]曾泓竣,曾千容.探析数据爬取中的相关知识产权问题[J].法制博览,2019(17):225.
[5]S. R. Mani Sekhar,G. M. Siddesh,Sunilkumar S. Manvi,K. G. Srinivasa.Optimized Focused Web Crawler with Natural Language Processing Based Relevance Measure in Bioinformatics Web Sources[J].Cybernetics and Information Technologies,2019,19(2).
[6]Anonymous.Tiger sheds cables with battery-operated rack crawler[J].Concrete Products,2019,122(6).
[7]胡俊潇,陈国伟.网络爬虫反爬策略研究[J].科技创新与应用,2019(15):137-138+140.
作者简介:
丁晓阳(1990-),男,国防大学政治学院研究生,主要研究方向:网络舆情。
王兰成(1962-),男,国防大学知名教授,博士生导师,主要研究方向:网络舆情,图书情报与档案管理。