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,一些功能如进程等用的并非很好,将就着看吧,若有错误,请沟通指出,必定虚心接受
相关文章
相关标签/搜索