python3爬取古诗词

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

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,一些功能如进程等用的并不是很好,将就着看吧,如有错误,请沟通指出,一定虚心接受

转载于:https://my.oschina.net/u/3163032/blog/1802000

你可能感兴趣的:(python3爬取古诗词)