上篇的爬蟲回顧其實(shí)已經(jīng)把爬蟲基本上都做好了,但是我覺得一個(gè)個(gè)復(fù)制年度匯編地址也很麻煩,要從03年粘貼到16年,如果我能夠再來一次循環(huán)就好了。并且,我通過瀏覽其他年度的某省份的工作報(bào)告,發(fā)現(xiàn)有些年度和省份的工作報(bào)告有分頁(yè)現(xiàn)象。用上篇的博客做的爬蟲匹配年份久的年度匯編網(wǎng)址的時(shí)候,發(fā)現(xiàn)省份的網(wǎng)站無法爬取,
處理后的值是空的。那么我們就要一步步地解決問題。
年份循環(huán)
按照上份的省份循環(huán),會(huì)發(fā)現(xiàn)非常好解決
思路是一樣的,無非就是把省份換成了年份而已
不同時(shí)期網(wǎng)站排版不同的兼容問題
在用上篇的爬蟲處理年份比較久的年份匯編的時(shí)候發(fā)現(xiàn)了爬取的內(nèi)容居然為空
然后查看網(wǎng)頁(yè)內(nèi)容進(jìn)行對(duì)比發(fā)現(xiàn),網(wǎng)頁(yè)的排版不一樣,然后逐個(gè)省份檢查,發(fā)現(xiàn)有個(gè)不同的排版,如果進(jìn)行兼容以及兼容后的數(shù)據(jù)保存的確有點(diǎn)棘手。


然后看著我的正則表達(dá)式我想到了一個(gè)傻辦法
cities = '(北京|天津|河北|山西|內(nèi)蒙古|遼寧|吉林|黑龍江|上海|江蘇|浙江|安徽|福建|江西|' \
'山東|河南|湖北|湖南|廣東|廣西|海南|重慶|四川|貴州|云南|西藏|陜西|甘肅|青海|寧夏|新疆)'
cities = cities.decode('utf8').strip()
re.findall('"(http://www.gov.*?)".*?' + cities + '<', page, re.S)
兩個(gè)不同的排版無非是后綴添加了省或者自治區(qū),那么我不要這些省份以及自治區(qū)不就好了么
于是我的正則表達(dá)式變成了
def plar_serach_all_spider(self):
"""爬取當(dāng)前工作年份中的地方政府工作報(bào)告的各省份報(bào)告超鏈接
爬取網(wǎng)頁(yè)中的源代碼 并進(jìn)行省份與相應(yīng)網(wǎng)址的匹配
將匹配的結(jié)果以省份為鍵,URL位置保存在元祖 plar_web_tuple 中
:return:None
"""
# 用來匹配省份
# 因?yàn)榫W(wǎng)站歷經(jīng)很多次的改版 各個(gè)時(shí)段對(duì)各個(gè)省份的叫法不一 所以給匹配帶來了困難
# 例如 北京市 和 北京 都有出現(xiàn)過 所以需要一下方法解決
cities = '(北京市|北京|天津市|天津|河北省|河北|山西省|山西|內(nèi)古|內(nèi)蒙古自治區(qū)|內(nèi)蒙古|遼寧省|遼寧|吉林省|吉林|' \
'黑江|黑龍江省|黑龍江|上海市|上海|江蘇省|江蘇|浙江省|浙江|安徽省|安徽|福建省|福建|江西省|江西|' \
'山東省|山東|河南省|河南|湖北省|湖北|湖南省|湖南|廣東省|廣東|廣西壯族自治區(qū)|廣西|海南省|海南|' \
'重慶市|重慶|四川省|四川|貴州省|貴州|云南省|云南|西藏自治區(qū)|西藏|陜西省|陜西|甘肅省|甘肅|' \
'青海省|青海|寧夏回族自治區(qū)|寧夏|新疆維吾爾自治區(qū)|新疆)'
cities = cities.decode('utf8').strip()
# 保存當(dāng)前網(wǎng)頁(yè)源碼 并將干擾匹配的信息去除
page = urllib2.urlopen(self.year_dict[self.year]).read().replace(
'http://www.gov.cn/govweb/xhtml/favicon.ico', '').replace(' ', '').replace(
' ', '').decode('utf8').split(' ')
page_data = ''.join(page)
# 進(jìn)行匹配
web_plar_tuple = re.findall('"(http://www.gov.*?)".*?' + cities + '<', page_data, re.S)
數(shù)據(jù)保存的時(shí)候 稍微處理一下就行
plar_web_tuple = {}
# 將匹配后的結(jié)果保存到元組中
for plar_line in web_plar_tuple:
templar = plar_line[1][0:2]
if templar == '內(nèi)蒙'.decode('utf8'):
templar = '內(nèi)蒙古'.decode('utf8')
if templar == '黑龍'.decode('utf8'):
templar = '黑龍江'.decode('utf8')
plar_web_tuple[templar] = plar_line[0]
# 進(jìn)入省份循環(huán)
self.plar_loop(plar_web_tuple)
處理分頁(yè)
一開始發(fā)現(xiàn)爬取的數(shù)據(jù)的文本比其他年度的文件大小小了很多,然后瀏覽到這個(gè)年度的省份報(bào)告網(wǎng)頁(yè)發(fā)現(xiàn)網(wǎng)頁(yè)的文字不是一頁(yè)的分頁(yè)處理的,這個(gè)時(shí)候就要看看有沒有什么辦法能夠處理這個(gè)問題。通過平常瀏覽網(wǎng)頁(yè)的心得,一般網(wǎng)站對(duì)分頁(yè)對(duì)網(wǎng)站會(huì)有特殊的處理,果不其然,以2009年北京政府工作報(bào)告為例,從第一頁(yè)http://www.gov.cn/test/2009-02/13/content_1230040.htm 跳轉(zhuǎn) 下一頁(yè)變成了 http://www.gov.cn/test/2009-02/13/content_1230040_2.htm 第三頁(yè)則是 http://www.gov.cn/test/2009-02/13/content_1230040_3.htm
那么我可以添加一個(gè)判斷,如果下一頁(yè)如果存在,并且能夠正常訪問那么就是有分頁(yè)的,把分頁(yè)的數(shù)據(jù)加上再返回即可。
def page_processing(url_cut, myitems):
""" 處理分頁(yè)
:param url_cut:
:param myitems:
:return:
"""
# 擁有下一頁(yè)則設(shè)置為True 反之為False
next_page = True
# 爬取源碼 保存
page = urllib2.urlopen(url_cut+'_2.htm').read().decode("utf8").replace(' ', '').replace(
'<strong>', '').replace('</strong>', '').replace('</br>', '')
myitems.extend(re.findall('<p.*?>(.*?[\u4e00-\u9fa5]*?.*?)</p>', page))
page_num = 3
# 直到?jīng)]有下一頁(yè) 否則一直循環(huán)
while next_page:
try:
page = urllib2.urlopen(url_cut + '_' + str(page_num)+'.htm').read().decode("utf8").replace(
' ', '').replace('<strong>', '').replace('</strong>', '').replace('</br>', '')
myitems.extend(re.findall('<p.*?>(.*?[\u4e00-\u9fa5]*?.*?)</p>', page))
page_num += 1
except urllib2.URLError:
next_page = False
return myitems
文件歸類(分文件夾保存)
由于要處理數(shù)據(jù),肯定是把文件分年度和分省份保存更加方便一下呀,但是我又覺得這樣太麻煩了。說白了也是懶,然后我就各種查資料。
思路是通過爬取的時(shí)候我的文件命名方式是 年份省份政府工作報(bào)告 這樣的,我分類的時(shí)候是把文件名進(jìn)行切割,匹配所需要的字符串。
# 需要重新寫
# 不涉及對(duì)類屬性的操作
@staticmethod
def report_classification():
"""將文本文件歸類
按年份以及月份歸類 會(huì)自動(dòng)創(chuàng)建文件夾進(jìn)行分類
:return:
"""
# 調(diào)用包來使用文本復(fù)制功能
from shutil import copy as cp
# work_text 是需要粘貼的工作目錄
# all_text 是需要復(fù)制的目錄
# root_text是根目錄
root_text = os.getcwd()
work_text = root_text + os.sep + 'report_down'
all_text = work_text + os.sep + 'all'
def cp_file(text):
"""復(fù)制文件
:param text: 需要?dú)w類的名稱
:return:
"""
# 針對(duì)省份和年份做標(biāo)記
if text == '省':
flag = 1
elif text == '年':
flag = 0
# 設(shè)置處理的工作目錄
path = work + os.sep + '按'.decode('utf8') + text.decode('utf') + '份'.decode('utf')
# 尋找需要?dú)w類的文件
file_list = os.walk(all_text)
for file_line in file_list:
for filename in file_line[2]:
# 判斷系統(tǒng) Windows系統(tǒng)需要格外的轉(zhuǎn)換
if platform.system() == 'Linux':
filename = filename.decode('utf8')
save_dir = filename.split('_')[flag]
elif platform.system() == 'Windows':
filename = filename.decode('gbk').encode('utf8')
save_dir = filename.split('_')[flag].decode('utf8')
filename = filename.decode('utf8')
else:
filename = filename.decode('utf8')
save_dir = filename.split('_')[flag]
# 若不在則新建文件夾
try:
if not os.path.exists(path + os.sep + save_dir):
os.makedirs(path + os.sep + save_dir)
except IOError:
print 'make dirs error'
# 開始復(fù)制
cp(all_text.decode('gbk') + os.sep + filename, path + os.sep + save_dir)
# Windows下需要將字符串轉(zhuǎn)碼
work = work_text.decode('gbk')
# 分別分類省和年的數(shù)據(jù)
cp_file('省')
cp_file('年')
print '打包完成'
結(jié)束
就這樣擁有爬取以及文件歸類的爬蟲已經(jīng)做好了
