古诗词知识图谱(一)

目标:开发一个古诗词智能问答应用,接入微信,可以在微信端利用文字或语音方式实现古诗词接龙。

  1. 设计知识图谱结构;
  2. 爬取古诗词写入Neo4j;

代码如下:

from bs4 import BeautifulSoup
import requests
from urllib.request import urlopen,urlparse,urlsplit,Request
import urllib.request
import re
from base import writefile,gethtml
import csv
import codecs
import random
import py2neo
from py2neo import Graph,Node,Relationship

ua_list = [
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",#Chrome
    "Mozilla/5.0 (Windows NT 6.1; rv:40.0) Gecko/20100101 Firefox/40.0",#firwfox
    "Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko",#IE
    "Opera/9.99 (Windows NT 5.1; U; zh-CN) Presto/9.9.9",#Opera
]
def not_empty(s):
    return s and s.strip()


# 创建list存储节点信息,节点不允许重复创建
list_sub = []
node=set()
main_node = set ( )
unique_title_type = set ( )

def get_everypoetry(sub_url,author,dynasty):
    req1 = urllib.request.Request ( sub_url, headers={'User-agent' : ua} )
    html1 = urlopen ( req1 ).read ( )
    soup1 = BeautifulSoup ( html1, 'lxml' )
    # 开始获取诗词内容
    # 1先获取该诗词连接,跳转到对应诗词界面才能够获取到诗词类型


    page = soup1.find_all ( 'div', {'class' : 'shici_list_main'} )
    for item in page :
        # 获取到诗词链接
        text0 = item.find ( 'a', {'target' : "_blank"} ) ['href']
        # 访问诗词页面
        content_url = 'http://www.shicimingju.com' + text0
        req2 = urllib.request.Request ( content_url, headers={'User-agent' : ua} )
        html2 = urlopen ( req2 ).read ( )
        soup2 = BeautifulSoup ( html2, 'lxml' )
        # 此时可以获取诗词内容和诗词类别
        # title1=soup2.find_all ( 'div', {'id' : 'item_div'} )

        # 诗词标题
        try:
            title = soup2.find ( 'h1' ).text
        except:
            print("获取title报错")
            print(content_url)
        #添加诗词节点
        if title not in node:
            try :
                graph.run (
                    "MERGE (title:Poetry {aname:'" + title + "'})" )
                node.add ( title )
                # 添加诗词跟作者关系
                graph.run (
                    "match (p:Person{name:'" + author + "'}),(t:Poetry{aname:'" + title + "'})" + "CREATE (p)-[:write]->(t)" )
            except :
                print ( "title写入Neo4j报错" )
                print ( content_url )

        # 诗词内容
        try:
            #诗词内容不能在存储时分解,可以放在数据检索时再行分词
            contents = soup2.find ( 'div', {'class' : 'item_content'} ).text.strip ( )

        except:
            print ( "获取诗词内容报错" )
            print ( content_url )
        try:
            graph.run (
                "match (p:Poetry {aname:'" + title + "'}) set p.content ='" + contents + "'" )
        except:
            print ( "获取诗词内容报错" )
            print ( content_url )
        # 诗词赏析
        try:
            appreciation1 = soup2.find ( 'div', {'class' : 'shangxi_content'} )
            appreciation = soup2.find ( 'div', {'class' : 'shangxi_content'} ).text.strip()
            graph.run (
                "match (t:Poetry {aname:'" + title + "'}) set t.zapp='" + appreciation + "'" )
        except:
            print("获取赏析报错")
            appreciation = ""
            graph.run (
                "match (t:Poetry {aname:'" + title + "'}) set t.zapp='" + appreciation + "'" )
            print(content_url)
        # 诗词类型
        try:
            poetry_type = soup2.find ( 'div', {'class' : 'shici-mark'} ).text.strip ( ).split ( '\n' )
        except :
            print ( "type读写报错" )
            poetry_type=['类型','其它']
            print ( content_url )
        type_len = len ( poetry_type )
        poetry_type_list = []
        if type_len > 2 :
            for n in range ( 1, type_len ) :
                poetry_type_list.append ( poetry_type [n].strip ( ) )
        else :
            poetry_type_list.append ( poetry_type [1] )
        while '' in poetry_type_list :
            poetry_type_list.remove ( '' )
        for ty in poetry_type_list :
            ty = ty.strip ( )
            unique_title_type.add ( title + "," + ty )
            if ty not in node :
                graph.run (
                    "MERGE (types:Types {name:'" + ty + "'})" )
                node.add ( ty )


            # 添加诗词跟作者关系
            try:
                if title + ty not in unique_title_type:
                    graph.run (
                        "MATCH (t:Poetry{aname:'" + title + "'}),(p:Types{name:'" + ty + "'})" + "CREATE (t)-[:belong_to]->(p)" )
                    unique_title_type.add ( title + ty )
            except:
                print("创建诗词与类型关系报错")

if __name__ == "__main__":
    #连接图数据库
    graph = Graph (
        "http://localhost:11003/",
        username="admin",
        password="password"
    )
    # 创建list存储节点信息,节点不允许重复
    # list_main = []

    flag=True
    url='http://www.shicimingju.com/chaxun/zuozhe/'
    for i in range(1,652):
        ua = random.choice ( ua_list )
        main_url = url+str(i)+'.html'
        # html, status = gethtml.get_html ( url )
        req = urllib.request.Request ( main_url, headers={'User-agent' : ua} )
        html = urlopen ( req ).read ( )
        soup = BeautifulSoup ( html, 'lxml' )
        try:
            # 主页面要获取诗人、朝代、简介、数量
            # 诗词作者
            author = soup.find ( 'div', {'class' : 'card about_zuozhe'} ).find ( 'h4' ).text  # Node
            # 诗词简介
            brief = soup.find ( 'div', {'class' : 'des'} ).text  # property
            # 诗人朝代
            dynasty = soup.find ( 'div', {'class' : 'aside_val'} ).text  # Node
            # 诗人写诗数量
            total_poetry = soup.find ( 'div', {'class' : 'aside_right'} ).find ( 'div', {
                'class' : 'aside_val'} ).text  # property
            if author not in main_node :
                graph.run (
                    "MERGE (author:Person {name:'" + author + "', brief:'" + brief + "', total_poetry:'" + total_poetry + "'})" )
                main_node.add(author)
            if dynasty not in main_node :
                graph.run (
                    "MERGE (dynasty:Time {name:'" + dynasty + "'})" )
                main_node.add(dynasty)
            if author not in main_node or dynasty not in main_node or flag:
                graph.run (
                    "MATCH (p:Person{name:'" + author + "'}),(t:Time{name:'" + dynasty + "'})" + "CREATE (p)-[:live_in]->(t)" )
                flag=False
            # 进入子页面读取诗词
            # list_main.append ( author )
            # list_main.append ( dynasty )
        except:
            print("获取诗人、数量、年代、简介")
        get_everypoetry ( main_url,author,dynasty )
        # page=soup.find_all('div',{'id':'list_nav_all'})
        # haha=len(page)
        #获取总共有多少页
        try:
            number=soup.find('div',{'id':'list_nav_all'}).find_all('a')
        except:
            print("获取页数报错")
        page_number=len(number)
        # href=number[0]
        for j in range(2,page_number):
            sub_url=url+str(i)+'_'+str(j)+'.html'
            get_everypoetry(sub_url,author,dynasty)
        punc = ':· - ...:-'
        list_item = []

知识图谱效果如下:

 

  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
基于知识图谱古诗词问答系统是一种能够根据用户提出的问题,从诗词知识图谱中动态获取相关信息,并将答案返回给用户的系统。该系统能够结合现代人工智能技术和传统文化知识,为用户提供便捷的查找和学习古诗词的方式。 该系统的开发使用了Java语言,并利用相关的开源项目和框架实现了以下功能: 1. 知识图谱构建:通过爬取各种古诗词数据源,利用自然语言处理和数据清洗技术,将古诗词数据转化为图谱结构,并建立起诗词之间的关联关系。 2. 问题理解:通过自然语言处理和文本分析技术,将用户提出的问题进行语义解析,提取问题的关键信息和意图。例如,用户可能提问“李白的哪首诗提到了月光?”系统需要理解用户关心的是李白的诗和与月光相关的内容。 3. 知识推理:基于知识图谱的结构和关联关系,系统能够进行知识推理,找到与问题相关的答案。例如,在上述问题中,系统可以通过李白节点与月光节点的关联关系,推理出与月光相关的诗词。 4. 答案生成:根据问题的意图和推理结果,系统能够生成符合用户需求的答案。例如,系统可以将相关的古诗词内容以文本形式呈现给用户。 5. 用户交互界面:系统还提供了友好的用户交互界面,使用户能够方便地输入问题、查看结果,以及进行进一步的交互和导航。 基于知识图谱古诗词问答系统的开发充分利用了Java语言的强大生态系统和丰富的机器学习和自然语言处理库,具有良好的可扩展性和性能。它可以成为诗词爱好者、学生和研究者的重要工具,帮助他们更加便捷地了解和学习古诗词的丰富知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SeasonRun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值