知识图谱 | 基于电商网站中的商品分类目录构建知识图谱

news2024/12/23 22:14:57

Hi,大家好,我是半亩花海。本项目旨在构建一个基于电商网站商品分类目录的知识图谱,通过Python程序爬取分类信息,形成商品的目录树,并提取底层商品的概念信息。项目将重点展示如何利用知识图谱呈现概念层级知识,以及如何将数据存储至Neo4j数据库以进行可视化和查询。通过该项目,我们将深入了解知识图谱的构建、数据入库及其在电商领域中的实际应用,提升对知识组织和信息管理的理解。

目录

一、实验目的

二、实验要求

三、实验原理

四、环境配置

1. 下载代码

2. 安装依赖环境

五、实验步骤

1. 启动Neo4j服务

2. 爬取数据

3. 知识入库

六、实验结果

七、完整代码

1. collect_info.py

2. build_kg.py


一、实验目的

(1)了解如何利用知识图谱呈现概念层级知识。

(2)了解如何利用电商网站中的商品分类目录建立知识图谱。

(3)了解知识图谱的入库和查看方式。


二、实验要求

(1)掌握如何用Python程序爬取电商网站中的商品分类目录并构建商品的目录树。

(2)掌握如何获取目录树对应的底层商品的概念信息并组织形成商品的知识图谱。

(3)掌握数据入库方式及如何用Neo4jDesktop查看数据。


三、实验原理

下面以京东电商为实验数据来源,采集京东商品目录树,获取其对应的底层商品概念信息,并组织形成商品的知识图谱。

目前,该图谱包括两类关系,即概念之间的上下位关系(用isa表示)及商品品牌与商品之间的销售关系(用sale表示),涉及商品概念数目达1300多个,商品品牌数目达10万多个,属性数目达几千种,关系数目规模达65万。


四、环境配置

1. 下载代码

下载代码(https://github.com/Airobin329/ProductKnowledgeGraph.git),并解压。

--|ProductKnowledgeGraph   #项目文件夹

--|--|data                                 #存放爬取数据的文件夹

--|--|--brands.txt                      #品牌数据文件

--|--|--goods.txt                       #商品数据文件

--|--|--goods_info.json            #商品信息文件

--|--|image                              #图片

--|--|build_kg.py                     #数据入库程序

--|--|collect_info.py                #爬虫程序

--|--|README.md                  #仓库说明

2. 安装依赖环境

(1)安装Python3(Download Python | Python.org),下载对应操作系统的安装包。

(2)安装依赖库。

win+R→cmd→输入以下命令行:

pipinstalllxmlpymongopy2neochardet-ihttps://pypi.tuna.tsinghua.edu.cn/simple

  • lxml:用于解析html文件
  • pymongo:用于连接mongodb
  • py2neo:用于连接neo4j
  • chardet:用于识别html文件编码

(3)安装MongoDB并启动服务(Windows 平台安装 MongoDB | 菜鸟教程,也可不安装)。

(4)安装Neo4j并启动服务(../课程学习/知识表示与处理/实验/21142604陶锐-第五章-语义网络写入图形数据库-实验报告.docx,内含Neo4j的安装过程)。

五、实验步骤

1. 启动Neo4j服务

首先以管理员身份运行cmd,再在命令行处输入neo4j.batconsole,然后在浏览器中输入网址http://localhost:7474/,即会出现相关界面。

2. 爬取数据

运行如下的爬虫程序:pythoncollect_info.py

这段代码用于构建一个商品知识图谱,主要目的是将商品数据以图谱的形式存储到数据库中,以便后续进行商品相关的查询和分析。

(1)主要功能

  • 读取数据:从指定的数据文件中读取商品信息,包括商品的分类、属性和品牌等信息。
  • 构建图谱:根据读取的数据,构建商品知识图谱。图谱中的节点表示商品、品牌等实体,边表示实体之间的关系,例如商品之间的属于关系,品牌与商品之间的销售关系等。
  • 连接到Neo4j数据库:使用py2neo库连接到Neo4j图数据库,将构建的知识图谱存储到数据库中。

(2)代码的执行流程

  • 初始化GoodsKg类和设置参数:在初始化GoodsKg类时,首先需要设置数据文件的路径和连接到Neo4j数据库所需的参数,如主机地址、用户名和密码等。这些参数会在构建图谱时用到。
  • 读取数据文件并解析商品信息:使用read_data方法读取数据文件,并解析其中的商品信息。此方法会返回商品的类别、属性和品牌等信息,以便后续构建图谱。
  • 构建图谱中的节点和边:根据解析得到的商品信息,构建图谱中的节点和边。节点的类型包括商品(Product)和品牌(Brand),节点的属性是商品或品牌的名称。边的类型包括商品之间的属于关系和品牌与商品之间的销售关系,边的属性包括关系名称。
  • 执行create_graph方法存储图谱到数据库中:最后,执行create_graph方法将构建的图谱存储到Neo4j数据库中。

(3)代码的运行结果

3. 知识入库

运行如下的入库程序:pythonbuild_kg.py

  • 初始化连接和关闭:
    • 在__init__方法中,初始化了与Neo4j数据库的连接,包括数据库地址和认证信息。
    • close方法用于关闭与数据库的连接,确保资源被正确释放。
  • 获取网页内容:
    • get_html方法用于发送HTTP请求获取京东网站首页的HTML内容。
    • 使用了requests库发送GET请求,并返回响应内容。
  • 解析网页结构:
    • 在home_list方法中,使用XPath解析HTML内容,提取商品分类信息。
    • 使用lxml.etree库解析HTML,定位到指定的HTML元素。
  • 遍历分类信息:
    • 遍历提取的分类信息,包括一级、二级和三级分类以及对应的链接。
    • 通过循环遍历,依次访问各个分类的链接,获取其下的三级分类信息和链接。
  • 创建节点和关系:
    • create_node方法用于在Neo4j数据库中创建节点和关系,表示商品的分类信息。
    • 使用Cypher查询语言,执行MERGE操作创建节点,并通过关系连接不同级别的分类节点。
  • 执行主程序:
    • 在__main__部分,创建GoodSchema对象,调用其home_list方法获取商品分类信息。
    • 最后关闭与数据库的连接,释放资源。

六、实验结果

使用Neo4jDesktop查看数据。

由于数据量巨大,在此只截取部分结果,如下图所示。

(1)当爬取数据之后,打开Neo4j界面的结果为:

(2)当知识入库之后,打开Neo4j界面的结果为:

七、完整代码

1. collect_info.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@Project : ProductKnowledgeGraph
@File    : collect_info.py
@IDE     : PyCharm
@Author  : 半亩花海
@Date    : 2024/06/03 11:07
"""
import json
import os
from py2neo import Graph, Node, Relationship


class GoodsKg:
    def __init__(self):
        cur = '/'.join(os.path.abspath(__file__).split('/')[:-1])
        self.data_path = os.path.join(cur, 'data/goods_info.json')
        self.g = Graph(
            host="127.0.0.1",  # neo4j 搭载服务器的 ip 地址,ifconfig 可获取到
            user="neo4j",  # 数据库 user name,如果没有更改过,应该是 neo4j
            password="0123456789")
        self.g.delete_all()  # 删除数据库中的所有节点和关系
        return

    '''读取数据'''

    def read_data(self):
        rels_goods = []
        rels_brand = []
        goods_attrdict = {}
        concept_goods = set()
        concept_brand = set()
        count = 0
        for line in open(self.data_path, encoding='utf-8'):
            count += 1
            print(count)
            line = line.strip()
            data = json.loads(line)
            first_class = data['fisrt_class'].replace("'", '')
            second_class = data['second_class'].replace("'", '')
            third_class = data['third_class'].replace("'", '')
            attr = data['attrs']
            concept_goods.add(first_class)
            concept_goods.add(second_class)
            concept_goods.add(third_class)
            rels_goods.append('@'.join([second_class, 'is_a', '属于', first_class]))
            rels_goods.append('@'.join([third_class, 'is_a', '属于', second_class]))

            if attr and '品牌' in attr:
                brands = attr['品牌'].split(';')
                for brand in brands:
                    brand = brand.replace("'", '')
                    concept_brand.add(brand)
                    rels_brand.append('@'.join([brand, 'sales', '销售', third_class]))

            goods_attrdict[third_class] = {name: value for name, value in attr.items() if name != '品牌'}

        return concept_brand, concept_goods, rels_goods, rels_brand

    '''构建图谱'''

    def create_graph(self):
        concept_brand, concept_goods, rels_goods, rels_brand = self.read_data()
        print('creating nodes....')
        self.create_node('Product', concept_goods)
        self.create_node('Brand', concept_brand)
        print('creating edges....')
        self.create_edges(rels_goods, 'Product', 'Product')
        self.create_edges(rels_brand, 'Brand', 'Product')
        return

    '''批量建立节点'''

    def create_node(self, label, nodes):
        pairs = []
        bulk_size = 1000
        batch = 0
        bulk = 0
        batch_all = len(nodes) // bulk_size
        print(batch_all)
        for node_name in nodes:
            sql = """CREATE(:%s {name:'%s'})""" % (label, node_name)
            pairs.append(sql)
            bulk += 1
            if bulk % bulk_size == 0 or bulk == batch_all + 1:
                sqls = '\n'.join(pairs)
                self.g.run(sqls)
                batch += 1
                print(batch * bulk_size, '/', len(nodes), 'finished')
                pairs = []
        return

    '''构造图谱关系边'''

    def create_edges(self, rels, start_type, end_type):
        batch = 0
        count = 0
        for rel in set(rels):
            count += 1
            rel = rel.split('@')
            start_name = rel[0]
            end_name = rel[3]
            rel_type = rel[1]
            rel_name = rel[2]
            sql = 'match (m:%s), (n:%s) where m.name = "%s" and n.name = "%s" create (m)-[:%s{name:"%s"}]->(n)' % (
            start_type, end_type, start_name, end_name, rel_type, rel_name)
            try:
                self.g.run(sql)
            except Exception as e:
                print(e)
            if count % 10 == 0:
                print(count)

        return


if __name__ == '__main__':
    handler = GoodsKg()
    handler.create_graph()

2. build_kg.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@Project : ProductKnowledgeGraph
@File    : build_kg.py
@IDE     : PyCharm
@Author  : 半亩花海
@Date    : 2024/06/04 20:13
"""
import requests
from lxml import etree
import json
from neo4j import GraphDatabase


class GoodSchema:
    def __init__(self):
        self.driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "0123456789"))

    def close(self):
        self.driver.close()

    def get_html(self, url):
        headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/600.5.17 (KHTML, like Gecko) Version/8.0.5 Safari/600.5.17"
        }
        try:
            response = requests.get(url, headers=headers)
            response.raise_for_status()
            return response.text
        except Exception as e:
            print(f"Failed to fetch HTML from {url}: {e}")
            return None

    def home_list(self):
        url = 'https://www.jd.com/allSort.aspx'
        html = self.get_html(url)
        if html:
            selector = etree.HTML(html)
            divs = selector.xpath('//div[@class= "category-item m"]')
            for indx, div in enumerate(divs):
                first_name = div.xpath('./div[@class="mt"]/h2/span/text()')[0]
                second_classes = div.xpath('./div[@class="mc"]/div[@class="items"]/dl')
                for dl in second_classes:
                    second_name = dl.xpath('./dt/a/text()')[0]
                    third_classes = ['https:' + i for i in dl.xpath('./dd/a/@href')]
                    third_names = dl.xpath('./dd/a/text()')
                    for third_name, url in zip(third_names, third_classes):
                        try:
                            self.create_node(first_name, second_name, third_name, url)
                            print(indx, len(divs), first_name, second_name, third_name)
                        except Exception as e:
                            print(e)
        else:
            print("Failed to fetch HTML from JD homepage")

    def create_node(self, first_name, second_name, third_name, url):
        with self.driver.session() as session:
            session.run(
                "MERGE (f:FirstClass {name: $first_name})"
                "MERGE (s:SecondClass {name: $second_name})"
                "MERGE (t:ThirdClass {name: $third_name, url: $url})"
                "MERGE (f)-[:HAS_SECOND]->(s)"
                "MERGE (s)-[:HAS_THIRD]->(t)",
                first_name=first_name, second_name=second_name, third_name=third_name, url=url
            )


if __name__ == '__main__':
    handler = GoodSchema()
    handler.home_list()
    handler.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1942487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

等保测评练习卷17

等级保护初级测评师试题17 姓名: 成绩: 判断题(10110分) 1. 关于安全区域边界的安全审计,三级系统的要求包括应对审计进程进行保护&#x…

Java实现分卷压缩功能,不引入第三方依赖的实现方式

分卷压缩 分卷压缩是一种将一个大文件分割成多个较小文件的压缩方法。这种方法通常用于便于存储、传输或备份大文件。分卷压缩的主要特点和步骤包括: 分割大文件:将一个大文件分割成多个较小的文件,每个小文件称为一个“分卷”。压缩分卷:对每个分卷进行压缩,以减少每个分…

【复习】软件工程

软件危机是指在计算机软件的开发和维护过程中所遇到的一系列严重问题。 典型表现: 开发成本和进度的估计常常很不准确 用户对已完成的软件系统不满意,闭门造车 软件质量(quality)不可靠 软件常常是不可维护的 软件产品供不应…

java的DOS命令

目录 1.DOS命令了解 DOS介绍 常用的dos命令1 DOS的基本原理 相对路径与绝对路径 常用的dos命令2 2.本章作业 1.编写hello,world程序 2.输出个人基本信息 3.jdk,jre,jvm关系 4.环境变量path配置及作用 5.java编写步骤 6.java编写7…

14、如何⽤DDD设计微服务代码模型

在完成领域模型设计后,接下来我们就可以开始微服务的设计和 落地了。在微服务落地前,⾸先要确定微服务的代码结构,也就是我 下⾯要讲的微服务代码模型。 只有建⽴了标准的微服务代码模型和代码规范后,我们才可以将 领域对象映射到…

C#初级——输出语句和转义字符

输出语句 在C#中,C#的输出语句是通过Console类进行输出,该类是一个在控制台下的一个标准输入流、输出流和错误流。使用该类下的Write()函数,即可打印要输出的内容。 Console.Write("Hello World!"); //在控制台应用中打印Hell…

websocket状态机

websocket突破了HTTP协议单向性的缺陷,基于HTTP协议构建了双向通信的通道,使服务端可以主动推送数据到前端,解决了前端不断轮询后台才能获取后端数据的问题,所以在小程序和H5应用中被广泛使用。本文主要集合报文分析对于websocket…

Python 机器学习求解 PDE 学习项目——PINN 求解一维 Poisson 方程

本文使用 TensorFlow 1.15 环境搭建深度神经网络(PINN)求解一维 Poisson 方程: − Δ u f in Ω , u 0 on Γ : ∂ Ω . \begin{align} -\Delta u & f \quad & \text{in } \Omega,\\ u & 0 \quad & \text{on } \Gamma:\partial \Om…

2024.7.22(nfs、samba)

一、web_server作用是发布nginx的web项目 1、停用selinux关闭防火墙 [rootnfs_server ~]# setenforce 0 [rootnfs_server ~]# vim /etc/selinux/config [rootnfs_server ~]# systemctl stop firewalld [rootnfs_server ~]# systemctl disable firewalld 2、安装nginx [rootwe…

四、GD32 MCU 常见外设介绍 (4) EXTI 中断介绍

4.EXTI 中断介绍 EXTI(中断/事件控制器)包含多个相互独立的边沿检测电路并且能够向处理器内核产生中断请求或唤醒事件。 EXTI 有三种触发类型:上升沿触发、下降沿触发和任意沿触发。 EXTI中的每一个边沿检测电路都可以独立配置和屏蔽。 4.1.GD32 EXTI 外设原理简介…

Nginx Rewrite(企业网站架构部署与优化)

Nginx Rewrite介绍 本章结构 实验步骤; 先在服务器1上写三个location;且等级各不相同; 如下;先将之前的location注释掉,避免冲突; 重启服务后生效; 如果用户输入的域名后只加了一个/或/都没有…

深入浅出C语言指针(进阶篇)

深入浅出C语言指针(基础篇) 深入浅出C语言指针(进阶篇) 目录 引言 一、指针和数组 1.数组名的理解 2.指针访问数组 3.一维数组传参的本质 二、二级指针 1.二级指针的概念 2.二级指针的内存表示 3.二级指针的解引用 三、字符指针 1.指针指向单个字符 2.指针指向字…

JavaWeb(4)JavaScript入门2—— JS的对象和JSON

一、JS的对象 1.声明语法1 通过new Object()直接创建对象 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><ti…

Linux——vi和vim编辑器

目录 基本介绍 vi和vim常用的三种模式 vi和vim的常用快捷键 基本介绍 vi和vim常用的三种模式 vi和vim的常用快捷键 网上找的快捷键盘图

docker搭建ES 8.14 集群

参考&#xff1a;【docker搭建es8集群kibana】_docker 安装生产级 es 8.14 集群-CSDN博客 1、之前已搭建一台单机版的dockerES集群 参见 Elasticsearch docker 安装_docker 安装es8.14.3-CSDN博客 2、现在需要重新搭建为docker ES集群 准备新搭建3个点 一、准备工作 提前开…

txt格式单词导入有道词典生词本 (java代码方式)

txt格式单词导入有道词典生词本 (java代码方式) 首先要求txt文档里单词的格式&#xff0c;大概需要像这种&#xff1a; 每行是一个单词&#xff0c;格式为&#xff1a;英文单词空格词性单词意思。 注意 导出单词本的名字就是你 txt 文件的名字 我这里是 公共英语三级 单词本 …

WPF项目实战视频《二》(主要为prism框架)

14.prism框架知识&#xff08;1&#xff09; 使用在多个平台的MVVM框架 新建WPF项目prismDemo 项目中&#xff1a;工具-NuGet包管理&#xff1a;安装Prism.DryIoc框架 在git中能看Prism的结构和源代码&#xff1a;git链接地址 例如&#xff1a;Prism/src/Wpf/Prism.DryIoc.Wpf…

Linux中tomcat下载教程

一.安装tomcat 1.安装 EPEL 仓库&#xff1a; sudo yum install epel-release2.安装 Tomcat&#xff1a; sudo yum install tomcat3.启动 Tomcat 服务&#xff1a; sudo systemctl start tomcat4.启用 Tomcat 服务开机启动&#xff1a; sudo systemctl enable tomcat5.检查…

SpringCloud 环境工程搭建

SpringCloud 环境&工程搭建 文章目录 SpringCloud 环境&工程搭建1. SpringCloud介绍2. 服务拆分原则2.1 单一职责原则2.2 服务自治2.3 单向依赖2.4 服务拆分示例 3. 数据准备4. 工程搭建4.1 创建父工程4.2 创建子工程4.2.1 子项目-订单服务4.2.2 子项目-商品服务 4.3 完…

物联网专业创新人才培养体系的探索与实践

一、引言 随着物联网&#xff08;IoT&#xff09;技术的迅猛发展&#xff0c;物联网领域的人才需求日益增加。物联网技术作为新一轮信息技术革命的核心&#xff0c;已经渗透到社会生活的各个领域&#xff0c;对推动经济转型升级、提升国家竞争力具有重要意义。因此&#xff0c…