github上找到的项目,感觉比较适合知识图谱入门
源码地址:https://github.com/lixiang0/WEB_KG
ubuntu环境(如果在windows下跑改下文件路径,我改了一下还是有点问题就没继续在windows环境下跑了):
- python 3.6
- requests:网络请求
- re:url正则匹配
- bs4:网页解析
- pickle:进度保存
- threading:多线程
- neo4j:知识图谱图数据库
- pip install neo4j-driver:neo4j python驱动
代码目录
- spider/ 抓取原始网页
- ie/ 从网页中解析正文,从正文中抽取结构化信息
- kg/ 抽取三元組,存入neo4j数据库
代码执行顺序:
- 1.spider目录下执行:python spider_main.py
爬取百度百科中文页面,以html格式保存在webpages文件夹下(这一步也许会因为某些原因(我猜是网络原因)提前结束,可以多执行几次这个命令)
- 2.ie目录下执行:python extract-para.py
github上拉取下的ie目录下没有info-para文件夹和info-table文件夹,创建txt文件时报错找不到文件,建议自己新建下这两个文件夹
用Xpath提取出<div class="para"></div>中的所有内容;re.sub是个正则表达式方面的函数,用来实现通过正则表达式,实现比普通字符串的replace更加强大的替换功能;extract()将提取到的内容返回一个list。
line=Selector(text=open(page,'r').read()).xpath('//div[contains(@class, "main-content")]')
title=line.xpath('//h1//text()').extract()
para=re.sub('\[[0-9]+\]', '', ''.join(word for word in line.xpath('//div[contains(@class, "para")]//text()').extract() if len(word)>1))
用Xpath语法提取html页面中的信息,以txt格式保存在info-para文件夹中。Xpath语法见下:
选取节点:
Xpath使用路径表达式在xml文档中选取节点。节点是通过沿着路径或者step来选取的
谓语:
谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语嵌在方括号中。
选取未知节点:
Xpath通配符可用来选取未知的xml元素。
选取若干路径:
通过在路径表达式中使用“|”运算符,可以选取若干个路径。
- 3.ie目录下执行:python extract-table.py
用Xpath提取<dt class = "basincInfo-item name"> <dd class = "basincInfo-item value">标签下的内容
selector=Selector(text=contents)
title=''.join(selector.xpath('//h1/text()').extract()).replace('/','')
names=selector.xpath('//dt[contains(@class,"basicInfo-item name")]').extract()
values=selector.xpath('//dd[contains(@class,"basicInfo-item value")]').extract()
print(len(names),len(values))
lines=''
for i,name in enumerate(names):
#name
temp=Selector(text=name).xpath('//dt/text()|//dt/a/text()').extract()
name=''.join(temp).replace('\n','')
#value
temp=Selector(text=values[i]).xpath('//dd/text()|//dd/a/text()').extract()
value=''.join(temp).replace('\n','')
以这样的格式保存在info-table下
- 4.kg目录下执行:python build-triple-from-table.py
将info-table中的信息,按name$$attr$$value存入triples.txt
open函数中各model区分:
- 5.kg目录下执行:python insert_to_neo4j.py 将三元组信息导入neo4j,三元组最后一共120W+,这一步要启动neo4j
这里改成自己设置的地址和密码。
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "123"))
不同的实体通过共同的属性连接
def add_node(tx, name1, relation,name2):
tx.run("MERGE (a:Node {name: $name1}) "
"MERGE (b:Node {name: $name2}) "
"MERGE (a)-[:"+relation+"]-> (b)",
name1=name1,name2=name2)
最后打开neo4j,输入框中输入:MATCH (n:Node) RETURN n LIMIT 1000,即可看见知识图谱
大概下图这个样子(这还不是120W+的,所以很散,120W+的还没导完,导完替换)