python爬蟲回顧<四>處理分頁(yè),不同時(shí)期網(wǎng)站排版不同的兼容問題,以及文件歸類(分文件夾保存)

上篇的爬蟲回顧其實(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)棘手。

1487729144226.jpg
1487729173666.jpg

然后看著我的正則表達(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)做好了

1487730270591.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容