python3爬取古詩詞

python3爬取古詩詞

  • 最近在學習python3基本的編程語法,python用起來代碼很簡潔(比java要清爽的多),看完官方文檔,本身就像動手實踐一下,作一個小小的檢測
  • 背景
    本人酷愛古詩詞,因此目標選擇了 古詩詞網
  • 思路
    • 經過觀察網站的佈局,在首頁雖然有翻頁的功能,但到100頁就沒了,不知道能不能爬下全部的古詩詞。點擊頁面上方的 詩文,發現頁面的右側有不少分類,每一個分類對應不一樣的url頁面(ps:其實首頁也有,但一開始就選擇了詩文那個頁面的右側分類列表準備下手),目測能爬下全部的數據,因此從右面列表開始下手
    • 查看頁面佈局(F12)
      經過觀察,右面列表的 類型包含完整的url,而 做者朝代形式這些的url並不全,同時這兩種url打開的頁面解析html也會不一樣。一個是直接列出全部的詩詞名,再點擊進入詳情頁;另外一個是直接展現詩詞,但分頁
    • 解析html選擇最新的requests-html
    • 將解析後的數據保存到mysql
    • 多進程爬取數據
  • 準備工做
    • 安裝mysql-python鏈接驅動模塊
    • 安裝requests-html模塊
  • 代碼以下
    • 導入須要使用的模塊
    import mysql.connector
    from requests_html import HTMLSession
    from multiprocessing import Pool
    • 建立session
    session = HTMLSession()
    • 解析由 類型跳轉的頁面
    def run_proc(url):
      print('參數:%s' % url)
    
      a = get(url).html.find('.main3', first=True).find('.left', first=True).find('.sons', first=True).find('a')
      result = []
      for j in range(len(a)):
          url_info = 'https://so.gushiwen.org' + a[j].attrs['href']
          print(url_info)
    
          val = parse_html(url_info, False, 'h1', True)
          if len(result) == 200:
              save_db(result)
              result = []
          result.append(val[0])
      if len(result) > 0:
          save_db(result)
    • 解析由做者朝代形式跳轉的頁面
    def run_proc_v2(url):
      print('參數:%s' % url)
      val = parse_html(url, True, 'b', False)
      result = val['result']
      total = int(val['total'])
      page_no = (total + 9) // 10
      url_split = url.split('.aspx')[0]
      prefix = url_split[:len(url_split) - 1]
      for i in range(1, page_no):
          page_url = prefix + str(i) + '.aspx'
          if len(result) == 200:
              save_db(result)
              result = []
          r = parse_html(page_url, False, 'b', False)
          if len(r) > 0:
              for j in range(len(r)):
                  result.append(r[j])
      if len(result) > 0:
          save_db(result)
    • 獲取鏈接
    def get(url):
      re = session.get(url)
      re.encoding = 'utf-8'
      return re
    • 解析html
    # 解析html
    # url:要解析的url
    # is_total 是否解析總數
    # title_node 詩詞名html元素節點
    # flag 是否只解析一條
    def parse_html(url, is_total, title_node, flag):
        div = get(url).html.find('.main3', first=True).find('.left', first=True)
        sons = div.find('.sons')
        result = []
        if sons is not None and len(sons) > 0:
            for i in range(len(sons)):
                values = []
    
                son = sons[i]
                # title
                values.insert(0, son.find(title_node, first=True).text)
    
                # author
                source = son.find('.source', first=True).find('a')
                values.insert(1, source[1].text)
    
                # content
                values.insert(2, son.find('.contson', first=True).text)
                # dynasty
                values.insert(3, source[0].text)
                result.append(values)
                if flag:
                    break
        # 解析總數
        if is_total:
            total_str = div.find('.pages', first=True).find('span')[1].text
            total = total_str[1:len(total_str) - 1]
            val = {'result': result, 'total': total}
            return val
        else:
            return result
    • 入庫
    def save_db(result):
      if result is not None and len(result) > 0:
          print('開始插入數據...')
          conn = mysql.connector.connect(user='root', password='wujinlei', host='127.0.0.1', port='3307',
                                         database='crawler')
          cursor = conn.cursor()
          for i in range(len(result)):
              values = result[i]
              cursor.execute('insert into poetry (title,author,content,dynasty) values (%s,%s,%s,%s)',
                             values)
          conn.commit()
          print('已經插入%s條數據' % len(result))
          cursor.close()
          conn.close()
    • 主函數
    if __name__ == "__main__":
      p = Pool(8)
    
      cate = get("https://www.gushiwen.org/shiwen/").html.find('.main3 .right', first=True).find('a')
      print(len(cate))
      if cate is not None and len(cate) > 0:
          for i in range(len(cate)):
              c = cate[i]
              url = c.attrs['href']
              if url[0] == '/':
                  url = 'https://www.gushiwen.org' + url
                  p.apply_async(run_proc_v2, args=(url,))
              else:
                  p.apply_async(run_proc, args=(url,))
    
      p.close()
      p.join()
  • 以上便是所有的代碼,初步瞭解python,一些功能如進程等用的並非很好,將就着看吧,若有錯誤,請溝通指出,必定虛心接受
相關文章
相關標籤/搜索