抓取历届政府工作报告#

import requests
from bs4 import BeautifulSoup

www.hprc.org.cn/wxzl/wxysl/lczf/

另外一个镜像

http://hprc.cssn.cn/wxzl/wxysl/lczf/

Inspect#

· 2016年政府工作报告
<td width="274" class="bl">·&nbsp;<a href="./d12qgrdzfbg/201603/t20160318_369509.html" target="_blank" title="2016年政府工作报告">2016年政府工作报告</a></td>
# get the link for each year
url = "http://www.hprc.org.cn/wxzl/wxysl/lczf/" 
content = requests.get(url)
content.encoding
'ISO-8859-1'

Encoding#

  • ASCII

    • 7位字符集

    • 美国标准信息交换代码(American Standard Code for Information Interchange)的缩写, 为美国英语通信所设计。

    • 它由128个字符组成,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(退格、响铃等)组成。

  • iso8859-1 通常叫做Latin-1。

    • 和ascii编码相似。

    • 属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列。比如,字母a的编码为0x61=97。

    • 无法表示中文字符。

    • 单字节编码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用iso8859-1编码来表示。在很多协议上,默认使用该编码。

  • gb2312/gbk/gb18030

    • 是汉字的国标码,专门用来表示汉字,是双字节编码,而英文字母和iso8859-1一致(兼容iso8859-1编码)。

    • 其中gbk编码能够用来同时表示繁体字和简体字,K 为汉语拼音 Kuo Zhan(扩展)中“扩”字的声母

    • gb2312只能表示简体字,gbk是兼容gb2312编码的。

    • gb18030,全称:国家标准 GB 18030-2005《信息技术中文编码字符集》,是中华人民共和国现时最新的内码字集

  • unicode

    • 最统一的编码,用来表示所有语言的字符。

    • 占用更多的空间,定长双字节(也有四字节的)编码,包括英文字母在内。

    • 不兼容iso8859-1等其它编码。相对于iso8859-1编码来说,uniocode编码只是在前面增加了一个0字节,比如字母a为”00 61”。

    • 定长编码便于计算机处理(注意GB2312/GBK不是定长编码),unicode又可以用来表示所有字符,所以在很多软件内部是使用unicode编码来处理的,比如java。

  • UTF

    • unicode不便于传输和存储,产生了utf编码

    • utf编码兼容iso8859-1编码,同时也可以用来表示所有语言的字符

    • utf编码是不定长编码,每一个字符的长度从1-6个字节不等。

    • 其中,utf8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。

      • 由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。

decode#

urllib2.urlopen(url).read().decode(‘gb18030’)

content.encoding = 'gb18030'

content = content.text

Or

content = content.text.encode(content.encoding).decode('gb18030')

html.parser#

BeautifulSoup(content, ‘html.parser’)

# Specify the encoding
content.encoding = 'utf8' # 'gb18030'
content = content.text
soup = BeautifulSoup(content, 'html.parser') 
# links = soup.find_all('td', {'class', 'bl'})  
# print(links[0]('a')[0]['href'])
links = soup.select('.bl a')
print(links[0])
<a href="./dssjqgrmdbdh_1/202203/t20220313_5398415.html" target="_blank" title="2022年政府工作报告">2022年政府工作报告</a>
len(links)
53
url
'http://www.hprc.org.cn/wxzl/wxysl/lczf/'
links[-1]['href']
'./dishiyijie_10/200908/t20090818_3955459.html'
links[0]['href'].split('./')[1]
'dssjqgrmdbdh_1/202203/t20220313_5398415.html'
print(url + links[0]['href'].split('./')[1])
http://www.hprc.org.cn/wxzl/wxysl/lczf/dssjqgrmdbdh_1/202203/t20220313_5398415.html
hyperlinks = [url + i['href'].split('./')[1] for i in links]
hyperlinks[:5] 
['http://www.hprc.org.cn/wxzl/wxysl/lczf/dssjqgrmdbdh_1/202203/t20220313_5398415.html',
 'http://www.hprc.org.cn/wxzl/wxysl/lczf/dssjqgrmdbdh_1/202103/t20210316_5318622.html',
 'http://www.hprc.org.cn/wxzl/wxysl/lczf/dssjqgrmdbdh_1/202006/t20200604_5138985.html',
 'http://www.hprc.org.cn/wxzl/wxysl/lczf/dssjqgrmdbdh_1/201903/t20190318_4849567.html',
 'http://www.hprc.org.cn/wxzl/wxysl/lczf/dssjqgrmdbdh_1/201803/t20180323_4240852.html']
hyperlinks[-5:]
['http://www.hprc.org.cn/wxzl/wxysl/lczf/dishiyijie_9/200908/t20090818_3955464.html',
 'http://www.hprc.org.cn/wxzl/wxysl/lczf/dishiyijie_10/200908/t20090818_3955462.html',
 'http://www.hprc.org.cn/wxzl/wxysl/lczf/dishiyijie_10/200908/t20090818_3955461.html',
 'http://www.hprc.org.cn/wxzl/wxysl/lczf/dishiyijie_10/200908/t20090818_3955460.html',
 'http://www.hprc.org.cn/wxzl/wxysl/lczf/dishiyijie_10/200908/t20090818_3955459.html']
print(hyperlinks[15]) # 2007年有分页
http://www.hprc.org.cn/wxzl/wxysl/lczf/dishiyijie_1/200908/t20090818_3955570.html

Inspect 下一页#

下一页

<a href="t20090818_27775_1.html"><span style="color:#0033FF;font-weight:bold">下一页</span></a>
  • a

    • script

      • td

url_i = 'http://www.hprc.org.cn/wxzl/wxysl/lczf/dishiyijie_1/200908/t20090818_3955570.html'
content = requests.get(url_i)
content.encoding = 'utf8'
content = content.text
#content = content.text.encode(content.encoding).decode('gb18030')
soup = BeautifulSoup(content, 'html.parser') 
#scripts = soup.find_all('script')
#scripts[0]
scripts = soup.select('td script')[0]
scripts
<script>
	var currentPage = 0;//所在页从0开始
	var prevPage = currentPage-1//上一页
	var 下一页Page = currentPage+1//下一页
	var countPage = 4//共多少页
	//document.write("共"+countPage+"页&nbsp;&nbsp;");
	
	//循环
	var num = 17;
	for(var i=0+(currentPage-1-(currentPage-1)%num) ; i<=(num+(currentPage-1-(currentPage-1)%num))&&(i<countPage) ; i++){
		if(countPage >1){
			if(currentPage==i)
				document.write("【<span style=\"color:#FF0000;\" class=\"hui14_30_h\">"+(i+1)+"</span>】&nbsp;");
			else if(i==0)
				document.write("<a href=\"t20090818_3955570.html\" class=\"hui14_30_h\">【"+(i+1)+"】</a>&nbsp;");
			else
				document.write("<a href=\"t20090818_3955570"+"_" + i + "."+"html\" class=\"hui14_30_h\">【"+(i+1)+"】</a>&nbsp;");
		}	
	}
	
	document.write("<br><br>");
	//设置上一页代码
	if(countPage>1&&currentPage!=0&&currentPage!=1)
		document.write("<a href=\"t20090818_3955570"+"_" + prevPage + "."+"html\"><span style=\"color:#0033FF;font-weight:bold\">上一页</span></a>&nbsp;");
	else if(countPage>1&&currentPage!=0&&currentPage==1)
		document.write("<a href=\"t20090818_3955570.html\"><span style=\"color:#0033FF;font-weight:bold\">上一页</span></a>&nbsp;");
	//else
	//	document.write("上一页 &nbsp;");
	
	
	//设置下一页代码 
	if(countPage>1&&currentPage!=(countPage-1))
		document.write("<a href=\"t20090818_3955570"+"_" + 下一页Page + "."+"html\" ><span style=\"color:#0033FF;font-weight:bold\">下一页</span></a> &nbsp;");
	//else
	//	document.write("下一页 &nbsp;");
					 
	</script>
scripts.text#.split('countPage = ')[1].split('//')[0]
'\n\tvar currentPage = 0;//所在页从0开始\n\tvar prevPage = currentPage-1//上一页\n\tvar 下一页Page = currentPage+1//下一页\n\tvar countPage = 4//共多少页\n\t//document.write("共"+countPage+"页&nbsp;&nbsp;");\n\t\n\t//循环\n\tvar num = 17;\n\tfor(var i=0+(currentPage-1-(currentPage-1)%num) ; i<=(num+(currentPage-1-(currentPage-1)%num))&&(i<countPage) ; i++){\n\t\tif(countPage >1){\n\t\t\tif(currentPage==i)\n\t\t\t\tdocument.write("【<span style=\\"color:#FF0000;\\" class=\\"hui14_30_h\\">"+(i+1)+"</span>】&nbsp;");\n\t\t\telse if(i==0)\n\t\t\t\tdocument.write("<a href=\\"t20090818_3955570.html\\" class=\\"hui14_30_h\\">【"+(i+1)+"】</a>&nbsp;");\n\t\t\telse\n\t\t\t\tdocument.write("<a href=\\"t20090818_3955570"+"_" + i + "."+"html\\" class=\\"hui14_30_h\\">【"+(i+1)+"】</a>&nbsp;");\n\t\t}\t\n\t}\n\t\n\tdocument.write("<br><br>");\n\t//设置上一页代码\n\tif(countPage>1&&currentPage!=0&&currentPage!=1)\n\t\tdocument.write("<a href=\\"t20090818_3955570"+"_" + prevPage + "."+"html\\"><span style=\\"color:#0033FF;font-weight:bold\\">上一页</span></a>&nbsp;");\n\telse if(countPage>1&&currentPage!=0&&currentPage==1)\n\t\tdocument.write("<a href=\\"t20090818_3955570.html\\"><span style=\\"color:#0033FF;font-weight:bold\\">上一页</span></a>&nbsp;");\n\t//else\n\t//\tdocument.write("上一页 &nbsp;");\n\t\n\t\n\t//设置下一页代码 \n\tif(countPage>1&&currentPage!=(countPage-1))\n\t\tdocument.write("<a href=\\"t20090818_3955570"+"_" + 下一页Page + "."+"html\\" ><span style=\\"color:#0033FF;font-weight:bold\\">下一页</span></a> &nbsp;");\n\t//else\n\t//\tdocument.write("下一页 &nbsp;");\n\t\t\t\t\t \n\t'
# countPage = int(''.join(scripts).split('countPage = ')\
#                 [1].split('//')[0])
# countPage

countPage = int(scripts.text.split('countPage = ')[1].split('//')[0])
countPage
4
import sys
    
def crawler(url_i):
    content = requests.get(url_i)
    content.encoding = 'utf8'  
    content = content.text
    soup = BeautifulSoup(content, 'html.parser') 
    year = soup.find('span', {'class', 'huang16c'}).text[:4]
    year = int(year)
    report = ''.join(s.text for s in soup('p'))
    # 找到分页信息
    scripts = soup.find_all('script')
    countPage = int(''.join(scripts[1]).split('countPage = ')[1].split('//')[0])
    if countPage == 1:
        pass
    else:
        for i in range(1, countPage):
            url_child = url_i.split('.html')[0] +'_'+str(i)+'.html'
            content = requests.get(url_child)
            content.encoding = 'utf8'
            content = content.text
            soup = BeautifulSoup(content, 'html.parser') 
            report_child = ''.join(s.text for s in soup('p'))
            report = report + report_child
    return year, report
hyperlinks[15] # 2007
'http://www.hprc.org.cn/wxzl/wxysl/lczf/dishiyijie_1/200908/t20090818_3955570.html'
year, report = crawler(hyperlinks[15])
year
2007
report[-300:]
'和高素质人才。引导跨国公司把高端制造和研发环节转移到我国,吸引外资加快向中西部、东北地区等老工业基地和符合产业政策的领域扩展。大力承接国际服务外包,提高我国服务业发展水平。加强对外资并购的引导和规范。优化投资环境,规范招商引资行为,纠正一些地方违法违规变相给予优惠政策和层层下达分解指标的做法。\u3000\u3000引导和规范企业对外投资合作。完善财税、信贷、外汇、保险等政策措施,支持有实力、有信誉、有竞争力的各种所有制企业走出去。加强引导和协调,避免企业在境外盲目投资和恶性竞争。发展对外承包工程与劳务合作。办好境外经济贸易合作区。推动多哈回合谈判进程,积极参与多边贸易规则制定,稳步推进双边和区域自由贸易区建设。'
# 抓取53年政府工作报告内容
reports = {}
for link in hyperlinks:
    year, report = crawler(link)
    print(year, end= '\r') # flush and print
    reports[year] = report 
1954
with open('./data/gov_reports1954-2022.txt', 'w', encoding = 'utf8') as f:
    for r in reports:
        line = str(r)+'\t'+reports[r].replace('\n', ' ').replace('\t', ' ') +'\n'
        f.write(line)
import pandas as pd

df = pd.read_table('./data/gov_reports1954-2022.txt', sep = '\t', names = ['year', 'report'])
pd.read_table?
df[:5]
year report
0 2022 各位代表:  现在,我代表国务院,向大会报告政府工作,请予审议,并请全国政协委员提出意见。 ...
1 2021 各位代表:  现在,我代表国务院,向大会报告政府工作,请予审议,并请全国政协委员提出意见。 ...
2 2020 新华社北京5月29日电  政府工作报告  ——2020年5月22日在第十三届全国人民代表...
3 2019 新华社北京3月16日电   政府工作报告  ——2019年3月5日在第十三届全国人民代表...
4 2018 各位代表:  现在,我代表国务院,向大会报告过去五年政府工作,对今年工作提出建议,请予审...