当前位置: 首页 > news >正文

Python爬取机车网车型数据并存入Mysql数据库

结果展示(文末附完整代码):

一、引言

        在当今数字化时代,数据对于各个领域的重要性不言而喻。对于机车行业而言,获取丰富的机车品牌、车型及详细信息数据,能够为市场分析、消费者研究等提供有力支持。本文将详细介绍一个使用 Python 编写的机车数据爬虫项目,该爬虫能够从特定机车网站抓取机车品牌、车型及其详细信息,并将数据存储到 MySQL 数据库中(同时也提供了 MongoDB 存储的部分代码示例)。

二、项目概述

        本项目旨在实现一个自动化的机车数据采集工具,通过对具体机车网站的爬取,获取机车品牌列表,进一步深入到每个品牌的车型页面,最终抓取车型的详细信息页面数据。整个过程涵盖了页面请求、数据解析以及数据存储等关键环节,下面将逐步展开介绍。

三、代码实现细节

(一)类的初始化(__init__方法)

        在JiChe类的初始化方法中,首先设定了要爬取的基础 URL,即http://www.jiche.com/pinpai/,这是整个爬虫的起始点。同时,定义了请求头信息,模拟浏览器发送请求,避免被网站识别为爬虫而拒绝访问。在本次代码中,使用的是常见的 Chrome 浏览器的 User-Agent 信息。

        对于数据库连接部分,代码中连接到了本地的 MySQL 数据库。设置了主机地址为127.0.0.1,端口号3306,用户名root,密码921108,数据库名称为fjj,并创建了数据库游标,以便后续执行 SQL 语句操作数据库。虽然代码中也包含了连接 MongoDB 的部分注释代码,但本文主要聚焦于 MySQL 数据库的操作与讲解。

class JiChe(object):def __init__(self):"""初始化 JiChe 类的实例。在这里设置了要爬取的基础 URL、请求头信息,以及连接到 MySQL 数据库所需的参数,并创建了数据库游标。"""self.url = 'http://www.jiche.com/pinpai/'self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ""Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.37 "}# # 连接 MongoDB# self.mongo_client = MongoClient('localhost', 27017)# self.mongo_db = self.mongo_client['your_database_name']# self.mongo_collection = self.mongo_db['your_collection_name']self.db = pymysql.Connect(host='127.0.0.1',port=3306,user='root',password='921108',db='fjj')self.cursor = self.db.cursor()

(二)获取页面内容(get_page_content方法)

   get_page_content方法负责发送 HTTP GET 请求获取指定 URL 的页面内容。它接收一个url参数,即要请求的页面地址。在方法内部,使用requests库发送请求,并根据请求头信息进行伪装。同时,为了确保正确解析页面中的中文等字符,将响应的编码设置为utf8。如果请求过程中出现异常,如网络连接问题或页面不存在等,将捕获requests.RequestException异常,并打印错误信息,同时返回None表示获取页面内容失败。

def get_page_content(self, url):"""发送 HTTP GET 请求获取指定 URL 的页面内容,并设置正确的编码。:param url: 要请求的 URL 地址:return: 返回获取到的页面文本内容,如果请求失败则返回 None"""try:response = requests.get(url, headers=self.headers)response.encoding = 'utf8'return response.textexcept requests.RequestException as e:print(f"请求页面时出错: {e}")return None

(三)解析品牌页面(parse_brand_page方法)

   parse_brand_page方法用于解析品牌页面。它接收品牌页面的文本内容作为参数resp。在方法内部,首先使用lxml库的etree模块将页面内容解析为 HTML 元素树。然后,通过特定的 XPath 表达式/html/body/div[2]/div[3]/div/div/div[1]/div/div[2]/ul/li找到页面中品牌列表所在的ul标签下的所有li标签。这里的 XPath 表达式是根据目标网站的页面结构确定的,如果网站页面结构发生变化,可能需要相应调整。

        对于每个品牌的li标签,进一步提取品牌标题和链接。品牌标题通过title = data.xpath("./p/a/@title")[0]获取,链接通过href = data.xpath("./p/a/@href")[0]获取。获取到品牌标题和链接后,调用parse_model_page方法对每个品牌的车型页面进行进一步解析。如果在提取数据过程中出现索引错误,例如 XPath 表达式找不到对应的元素,将打印错误信息提示页面结构可能发生变化。

def parse_brand_page(self, resp):"""解析品牌页面,提取品牌列表中的每个品牌的标题和链接,然后对每个品牌进一步解析。:param resp: 品牌页面的文本内容"""html = etree.HTML(resp)try:# 通过 XPath 找到 ul 标签下的所有 li 标签,这里的 XPath 表达式可能需要根据实际页面结构调整data_list = html.xpath('/html/body/div[2]/div[3]/div/div/div[1]/div/div[2]/ul/li')for data in data_list:title = data.xpath("./p/a/@title")[0]  # 获取品牌标题href = data.xpath("./p/a/@href")[0]  # 获取品牌链接self.parse_model_page(title, href)except IndexError:print("在解析品牌页面时,提取数据出现索引错误,可能页面结构发生变化。")

(四)解析车型页面(parse_model_page方法)

   parse_model_page方法用于解析车型页面。它接收品牌标题title和品牌链接href作为参数。在方法内部,首先构建车型页面的 URL,即品牌链接加上chexing.html。然后,调用get_page_content方法获取车型页面的文本内容。如果获取成功,同样使用etree将页面解析为 HTML 元素树。

        通过 XPath 表达式//*[@id="j-model-list"]/li找到车型列表所在的li标签。对于每个车型的li标签,提取车型标题、链接和型号。车型标题通过title = data.xpath("./a/@title")[0]获取,链接通过href = data.xpath("./a/@href")[0]获取,型号通过type_ = data.xpath("./a/text()")[0]获取。获取到车型信息后,调用parse_detail_page方法对车型的详细信息页面进行解析。如果在提取数据过程中出现索引错误,将打印错误信息提示页面结构可能发生变化。

def parse_model_page(self, title, href):"""解析车型页面,提取车型列表中的每个车型的标题、链接和型号,然后对每个车型进一步解析。:param title: 品牌标题:param href: 品牌链接"""url = href + 'chexing.html'response_text = self.get_page_content(url)if response_text:html = etree.HTML(response_text)try:# 通过 XPath 找到特定 id 的 ul 标签下的所有 li 标签,这里的 XPath 表达式可能需要根据实际页面结构调整data_list = html.xpath('//*[@id="j-model-list"]/li')for data in data_list:title = data.xpath("./a/@title")[0]  # 获取车型标题href = data.xpath("./a/@href")[0]  # 获取车型链接type_ = data.xpath("./a/text()")[0]  # 获取车型型号self.parse_detail_page(title, type_, href)except IndexError:print("在解析车型页面时,提取数据出现索引错误,可能页面结构发生变化。")

(五)解析车型详细页面(parse_detail_page方法)

   parse_detail_page方法用于解析车型详细页面。它接收车型标题title、车型型号type_和车型链接href作为参数。在方法内部,首先调用get_page_content方法获取车型详细页面的文本内容。如果获取成功,使用BeautifulSoup库将页面解析为 BeautifulSoup 对象,以便更方便地提取页面中的表格数据。

        通过find_all('table')方法找到页面中的所有表格标签。对于每个表格,首先提取表格的id属性的后四位并加上字作为一个标识信息kuan,然后遍历表格中的每个td标签。对于每个td标签,提取其中的文本信息。如果td标签中没有img标签,将td标签中的普通文本、span标签中的文本和b标签中的文本进行组合,去除首尾空白字符后添加到td_texts列表中。最后,将kuantd_texts列表作为一个子列表添加到detail列表中,形成车型详细信息的列表结构。

        提取完数据后,将数据插入到 MySQL 数据库中。构建 SQL 插入语句sql = "INSERT INTO 机车 (title, type_, href, detail) VALUES (%s, %s, %s, %s)",并设置插入参数params = (title, type_, href, str(detail)),然后使用数据库游标执行插入操作,并提交事务。如果在提取数据过程中出现异常,将打印错误信息提示页面结构可能发生变化。

def parse_detail_page(self, title, type_, href):"""解析车型详细页面,提取页面中的表格数据,整理成详细信息列表。:param title: 车型标题:param type_: 车型型号:param href: 车型链接"""response_text = self.get_page_content(href)if response_text:soup = BeautifulSoup(response_text, 'html.parser')table_tags = soup.find_all('table')detail = []try:for table in table_tags:kuan = table['id'][-4:] + '款'td_texts = []td_texts.append(kuan)for td in table.find_all('td'):if td.find('img') is None:other_text = td.find(string=True, recursive=False).strip() if td.find(string=True,recursive=False) else ""span_text = td.find('span').get_text(strip=True) if td.find('span') else ""if span_text == '价格':span_text = span_text + ':'b_text = td.find('b').get_text(strip=True) if td.find('b') else ""td_texts.append(span_text + other_text + b_text)detail.append(td_texts)print(title, type_, href, detail)# 将数据插入到 MySQL 数据库sql = "INSERT INTO 机车 (title, type_, href, detail) VALUES (%s, %s, %s, %s)"params = (title, type_, href, str(detail))self.cursor.execute(sql, params)self.db.commit()# # 将数据存入 MongoDB# data_to_insert = {#     "title": title,#     "type": type_,#     "href": href,#     "detail": detail# }# self.mongo_collection.insert_one(data_to_insert)except Exception:print("在解析车型详细页面时,提取数据出现索引错误,可能页面结构发生变化。")

(六)启动爬虫(run方法)

   run方法是整个爬虫的启动入口。在该方法中,首先调用get_page_content方法获取品牌页面的内容。如果获取成功,即品牌页面内容不为None,则调用parse_brand_page方法开始解析品牌页面,从而启动整个爬虫的流程,后续将依次解析车型页面和车型详细页面,直到完成所有数据的抓取和存储。

def run(self):"""启动整个爬虫流程,先获取品牌页面内容,然后依次进行解析。"""brand_page_content = self.get_page_content(self.url)if brand_page_content:self.parse_brand_page(brand_page_content)

四、项目总结

全部代码:

# -*- coding:utf-8 -*-
import pymysql
import requests
from bs4 import BeautifulSoup
from lxml import etreeclass JiChe(object):def __init__(self):"""初始化JiChe类的实例。在这里设置了要爬取的基础URL、请求头信息,以及连接到MySQL数据库所需的参数,并创建了数据库游标。"""self.url = 'http://www.jiche.com/pinpai/'self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ""Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.37 "}# # 连接MongoDB# self.mongo_client = MongoClient('localhost', 27017)# self.mongo_db = self.mongo_client['your_database_name']# self.mongo_collection = self.mongo_db['your_collection_name']self.db = pymysql.Connect(host='127.0.0.1',port=3306,user='root',password='921108',db='fjj')self.cursor = self.db.cursor()def get_page_content(self, url):"""发送HTTP GET请求获取指定URL的页面内容,并设置正确的编码。:param url: 要请求的URL地址:return: 返回获取到的页面文本内容,如果请求失败则返回None"""try:response = requests.get(url, headers=self.headers)response.encoding = 'utf8'return response.textexcept requests.RequestException as e:print(f"请求页面时出错: {e}")return Nonedef parse_brand_page(self, resp):"""解析品牌页面,提取品牌列表中的每个品牌的标题和链接,然后对每个品牌进一步解析。:param resp: 品牌页面的文本内容"""html = etree.HTML(resp)try:# 通过XPath找到ul标签下的所有li标签,这里的XPath表达式可能需要根据实际页面结构调整data_list = html.xpath('/html/body/div[2]/div[3]/div/div/div[1]/div/div[2]/ul/li')for data in data_list:title = data.xpath("./p/a/@title")[0]  # 获取品牌标题href = data.xpath("./p/a/@href")[0]  # 获取品牌链接self.parse_model_page(title, href)except IndexError:print("在解析品牌页面时,提取数据出现索引错误,可能页面结构发生变化。")def parse_model_page(self, title, href):"""解析车型页面,提取车型列表中的每个车型的标题、链接和型号,然后对每个车型进一步解析。:param title: 品牌标题:param href: 品牌链接"""url = href + 'chexing.html'response_text = self.get_page_content(url)if response_text:html = etree.HTML(response_text)try:# 通过XPath找到特定id的ul标签下的所有li标签,这里的XPath表达式可能需要根据实际页面结构调整data_list = html.xpath('//*[@id="j-model-list"]/li')for data in data_list:title = data.xpath("./a/@title")[0]  # 获取车型标题href = data.xpath("./a/@href")[0]  # 获取车型链接type_ = data.xpath("./a/text()")[0]  # 获取车型型号self.parse_detail_page(title, type_, href)except IndexError:print("在解析车型页面时,提取数据出现索引错误,可能页面结构发生变化。")def parse_detail_page(self, title, type_, href):"""解析车型详细页面,提取页面中的表格数据,整理成详细信息列表。:param title: 车型标题:param type_: 车型型号:param href: 车型链接"""response_text = self.get_page_content(href)if response_text:soup = BeautifulSoup(response_text, 'html.parser')table_tags = soup.find_all('table')detail = []try:for table in table_tags:kuan = table['id'][-4:] + '款'td_texts = []td_texts.append(kuan)for td in table.find_all('td'):if td.find('img') is None:other_text = td.find(string=True, recursive=False).strip() if td.find(string=True,recursive=False) else ""span_text = td.find('span').get_text(strip=True) if td.find('span') else ""if span_text == '价格':span_text = span_text + ':'b_text = td.find('b').get_text(strip=True) if td.find('b') else ""td_texts.append(span_text + other_text + b_text)detail.append(td_texts)print(title, type_, href, detail)# 将数据插入到MySQL数据库sql = "INSERT INTO 机车 (title, type_, href, detail) VALUES (%s, %s, %s, %s)"params = (title, type_, href, str(detail))self.cursor.execute(sql, params)self.db.commit()# # 将数据存入MongoDB# data_to_insert = {#     "title": title,#     "type": type_,#     "href": href,#     "detail": detail# }# self.mongo_collection.insert_one(data_to_insert)except Exception:print("在解析车型详细页面时,提取数据出现索引错误,可能页面结构发生变化。")def run(self):"""启动整个爬虫流程,先获取品牌页面内容,然后依次进行解析。"""brand_page_content = self.get_page_content(self.url)if brand_page_content:self.parse_brand_page(brand_page_content)if __name__ == '__main__':spider = JiChe()spider.run()

        通过以上代码实现,我们成功构建了一个机车数据爬虫。它能够从指定的机车网站抓取品牌、车型及详细信息,并存储到 MySQL 数据库中,为后续的数据分析和应用提供了数据基础。然而,在实际应用中,还需要考虑一些问题。例如,网站的页面结构可能会发生变化,这就需要定期检查和调整 XPath 表达式等解析代码,以确保爬虫的稳定性和准确性。同时,为了避免对目标网站造成过大的访问压力,还可以考虑设置合理的爬取间隔时间,遵循网站的 robots.txt 规则等。

        此外,在数据存储方面,虽然本文主要介绍了 MySQL 数据库的使用,但 MongoDB 等非关系型数据库也有其优势,如更好的扩展性和对复杂数据结构的支持。可以根据实际需求进一步优化数据存储方案,或者考虑结合使用多种数据库技术。总之,机车数据爬虫项目具有很大的应用潜力和拓展空间,通过不断地优化和完善,可以为机车行业相关研究和业务提供更强大的数据支持工具。

        希望本文能够帮助读者理解机车数据爬虫的基本原理和实现方法,读者可以根据自己的需求进一步修改和扩展代码,以适应不同的应用场景。

        请注意,在实际使用中,如果涉及到对网站数据的获取,需要确保遵守相关网站的使用条款和法律法规,避免未经授权的访问和数据滥用等问题,本文仅供交流学习,请勿滥用。

相关文章:

Python爬取机车网车型数据并存入Mysql数据库

结果展示(文末附完整代码): 一、引言 在当今数字化时代,数据对于各个领域的重要性不言而喻。对于机车行业而言,获取丰富的机车品牌、车型及详细信息数据,能够为市场分析、消费者研究等提供有力支持。本文将…...

fpga 时序分析基础

目录 触发器的动态参数 同步时序电路分析 1. 时钟脉冲的特性 2. 同步时序电路分析 Timing Analyzer的应用 异步时序与亚稳态问题 时序分析就是对时序电路进行时序检查,通过分析电路中所有寄存器之间的路径延迟以检查电路的传输延迟是否会导致触发器的建立时间…...

python学习——二维列表的列表生成式

二维列表的列表生成式允许你生成一个列表,其中每个元素本身也是一个列表。这在处理矩阵或表格数据时非常有用。 以下是如何使用列表生成式来创建二维列表的示例: 文章目录 基本语法示例1. 创建一个 3x3 的单位矩阵2. 创建一个 4x4 的乘法表3. 创建一个 …...

【错误❌】——槽函数定义好但未初始化

public slots:void onClose(); 初始化即可成功:...

OpenCV相机标定与3D重建(6)将3D物体点投影到2D图像平面上函数projectPoints()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::fisheye::projectPoints 是 OpenCV 库中用于鱼眼镜头模型的函数,它将3D物体点投影到2D图像平面上。这个函数对于模拟或者理解鱼眼…...

【Linux】剧幕中的灵魂更迭:探索Shell下的程序替换

🎬 个人主页:谁在夜里看海. 📖 个人专栏:《C系列》《Linux系列》《算法系列》 ⛰️ 一念既出,万山无阻 目录 📖一、进程程序替换 1.替换的演示 ❓替换与执行流 ❓程序替换≠进程替换 2.替换的原理 …...

38 基于单片机的宠物喂食(ESP8266、红外、电机)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STC89C52单片机,采用L298N驱动连接P2.3和P2.4口进行电机驱动, 然后串口连接P3.0和P3.1模拟ESP8266, 红外传感器连接ADC0832数模转换器连接单片机的P1.0~P1.…...

Unity中的数学应用 之 角色移动中单位化向量的妙用 (小学难度)

最近准备从简单到困难跟几个教程用以加强自己的业务能力,相信很多小伙伴都做过胡闹厨房这一个案例,其实这个案例比较初级,但是也包含了很多平常可能注意不到小细节,所以我就以它为举例,拓展其中的数学知识 CodeMonkey教…...

设置ip和代理DNS的WindowsBat脚本怎么写?

今天分享一个我们在工作时,常见的在Windows中通过批处理脚本(.bat 文件)来设置IP地址、代理以及DNS 相关配置的示例,大家可以根据实际需求进行修改调整。 一、设置静态IP地址脚本示例 以下脚本用于设置本地连接(你可…...

字符串分割转换(Java Python JS C++ C )

题目描述 给定一个非空字符串S,其被N个‘-’分隔成N+1的子串,给定正整数K,要求除第一个子串外,其余的子串每K个字符组成新的子串,并用‘-’分隔。 对于新组成的每一个子串,如果它含有的小写字母比大写字母多,则将这个子串的所有大写字母转换为小写字母; 反之,如果它…...

【Maven】项目创建

3. Maven的应用 本章主要内容: 使用 Maven 创建 JavaSE 项目使用 Maven 创建 JavaWeb 项目,在本地部署 Tomcat 测试导入 Maven 项目 3.1 基于Maven开发JavaSE的项目 3.1.1 流程 1、File—>new—>Project—>Empty Project Location&#xff1…...

number的++和--运算 C#

number10 请计算num number --number - number number就是先对number运算,然后再给number赋值--number 先给number赋值,再拿来运算 using System;class Program {static void Main(string[] args){int number 10;int a, b, c, number1, number2;…...

浅谈网络 | 应用层之HTTPS协议

目录 对称加密非对称加密数字证书HTTPS 的工作模式重放与篡改 使用 HTTP 协议浏览新闻虽然问题不大,但在更敏感的场景中,例如支付或其他涉及隐私的数据传输,就会面临巨大的安全风险。如果仍然使用普通的 HTTP 协议,数据在网络传输…...

2、Three.js初步认识场景Scene、相机Camera、渲染器Renderer三要素

三要素之间关系: 有了虚拟场景Scene,相机录像Camera,在相机小屏幕上看到的Renderer Scene当前空间 Mesh人在场景 Camera相机录像 Renderer显示器上 首先先描述下Scene: 这个场景为三要素之一,一切需要展示的东西都需…...

Deepwave 声波正演和弹性波正演

Deepwave Deepwave 调用 scalar 方法实现声波和弹性波正演。 ######## 声波正演 ###################### import torch import numpy as np import deepwave from deepwave import scalardevice torch.device(cuda if torch.cuda.is_available()else cpu)## Set observation…...

【WRF-Urban】多层建筑能源参数化模型概述:原理

【WRF-Urban】多层建筑能源参数化模型概述:原理 1 概述1.1 原理1.2 使用步骤 2参考 多层建筑能源参数化(Multi-layer Building Energy Parameterization, BEP)模型是一种用于模拟城市环境中多层建筑群的能量交换和微气候影响的参数化模型。该…...

基于Qt实现的自定义树结构容器:设计与应用

在Qt框架中,尽管其提供了许多强大的容器类(如 QList, QMap, QTreeWidget 等),但缺少一个通用的、灵活的树结构容器,直接支持多层级数据管理。为了满足这些需求,本文设计并实现了一个可复用的自定义树结构容…...

网络命令Linux

目录 一,Linux 二,CMD 一,Linux ping www.baidu.com 测试联网 -c 2 次数,ping几次 , -i 间隔 -W timeout 超时时间,等待响应的超时时间 ss -lntup |grep -w 22 netstat -lntup |grep -w 22 lsof -i:22 ls…...

简单的Activiti Modoler 流程在线编辑器

简单的Activiti Modoler 流程在线编辑器 1.需求 我们公司使用的流程是activiti5.22.0,版本有些老了,然后使用的编辑器都是eclipse的流程编辑器插件,每次编辑流程需要打开eclipse进行编辑,然后再导入到项目里面,不是特…...

【NodeJS】Express写接口的整体流程

前提条件 开发 Node.js,首先就必须要安装 Node.js。推荐使用 nvm,它可以随意切换 node 版本。下载 nvm,具体可以看本人另一篇文章:nvm的作用、下载、使用、以及Mac使用时遇到commond not found:nvm如何解决。 nvm官方&#xff1…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...