二维A*算法

MATLAB2016b可以正常运行 

function bidirectional_ASTAR
clc;
clear;
%% 初始化界面
n = 11;   % field size n x n tiles  20*20的界面
%wallpercent = 0.3;  % this percent of field is walls   15%的界面作为阻碍物(墙)
cmap = [1 1 1; ...%  1 - white - 空地0 0 0; ...% 2 - black - 障碍 1 0 0; ...% 3 - red - 已搜索过的地方0 0 1; ...% 4 - blue - 下次搜索备选中心 0 1 0; ...% 5 - green - 起始点1 1 0;...% 6 - yellow -  到目 标点的路径 1 0 1];% 7 - -  目标点 
colormap(cmap); 
field = ones(n);
startposind =10;   %sub2ind用来将行列坐标转换为线性坐标,这里是必要的,因为如果把startposind设置成[x,y]的形式,访问field([x,y])的时候
goalposind =12;    %它并不是访问x行y列元素,而是访问线性坐标为x和y的两个元素
% field(ceil(n^2.*rand(floor(n*n*wallpercent),1) )) = Inf;
field(1:5, 7) = 2;
field(8,1:3) = 2; 
field(2:5,3:5)=2;field(8,10)=2;
% startposind = sub2ind([n,n],ceil(n.*rand),ceil(n.*rand));   %sub2ind用来将行列坐标转换为线性坐标,这里是必要的,因为如果把startposind设置成[x,y]的形式,访问field([x,y])的时候
%goalposind = sub2ind([n,n],ceil(n.*rand),ceil(n.*rand));    %它并不是访问x行y列元素,而是访问线性坐标为x和y的两个元素
field(startposind )=5;
field(goalposind )=7;
costchart = NaN*ones(n);      %costchart用来存储各个点的实际代价,NaN代表不是数据(不明确的操作)
costchart(startposind) = 0;     %起点的实际代价
fieldpointers = zeros(n);
fieldpointers1 = zeros(n);global setOpenCosts;global setOpenCosts1;global setOpen;global setOpen1;global setOpenHeuristics;global setOpenHeuristics1;
setOpen = (startposind); setOpenCosts = (0); setOpenHeuristics = (Inf);
setClosed = []; setClosedCosts = [];%初始化起点的open表和close表
setOpen1 = (goalposind); setOpenCosts1 = (0); setOpenHeuristics1 = (Inf);
setClosed1 = []; setClosedCosts1 = [];%初始化目标点的open表和close表[goalpos(1) ,goalpos(2)] = ind2sub([n n],goalposind);       %获得目标点的行列坐标
[startpos(1) ,startpos(2)] = ind2sub([n n],startposind);
uicontrol('Style','pushbutton','String','RE-DO', 'FontSize',12, ...'Position', [10 10 60 40], 'Callback','bidirectional_ASTAR');
tic
while true %ismember(A,B)返回与A同大小的矩阵,其中元素1表示A中相应位置的元素在B中也出现,0则是没有出现field(startposind )=5;field(goalposind )=7;image(1.5,1.5,field); grid on; axis image; set(gca,'gridline','-','gridcolor','r','linewidth',2);set(gca,'xtick',1:1:12,'ytick',1:1:12);drawnow;if(max(ismember(setOpen,setOpen1)))break;end;  [~, ii] = min(setOpenCosts + setOpenHeuristics);   %从OPEN表中选择花费最低的点temp,ii是其下标(也就是标号索引)[~, ii1] = min(setOpenCosts1 + setOpenHeuristics1);field(setOpen(ii))=3;field(setOpen1(ii1))=6;[currentpos(1), currentpos(2)] = ind2sub([n n],setOpen(ii));[currentpos1(1), currentpos1(2)] = ind2sub([n n],setOpen1(ii1));%获得以起点扩展的当前点的行列坐标,注意currentpos(1)是行坐标,currentpos(2)是列坐标%% 获得当前点的邻居[posinds,posinds1,cost,cost1,heuristic,heuristic1]=get_neighbors(n,ii,ii1,currentpos(1),currentpos(2),currentpos1(1),currentpos1(2),goalpos(1),goalpos(2),startpos(1),startpos(2));setClosed = [setClosed; setOpen(ii)];     %将temp插入CLOSE表中setClosedCosts = [setClosedCosts; setOpenCosts(ii)];  %将temp的花费计入ClosedCostssetClosed1 = [setClosed1; setOpen1(ii1)];     %将temp插入CLOSE表中setClosedCosts1 = [setClosedCosts1; setOpenCosts1(ii1)];  %将temp的花费计入ClosedCosts%% 新增节点的判断for jj=1:length(posinds)      %对于扩展的四个方向的坐标if(field(posinds(jj))~=3 && field(posinds(jj))~=2 && field(posinds(jj))~=5 &&posinds(jj)~=1)field(posinds(jj))=4;if ~max([setClosed; setOpen] == posinds(jj)) %如果此点不在OPEN表和CLOSE表中fieldpointers(posinds(jj)) = setOpen(ii); %将此点的方向存在对应的fieldpointers中costchart(posinds(jj)) = cost(jj); %将实际代价值存入对应的costchart中setOpen = [setOpen; posinds(jj)]; %将此点加入OPEN表中setOpenCosts = [setOpenCosts; cost(jj)];   %更新OPEN表实际代价setOpenHeuristics = [setOpenHeuristics; heuristic(jj)];    %更新OPEN表启发代价elseif max(setOpen == posinds(jj)) %如果此点在OPEN表中I = find(setOpen == posinds(jj));   %找到此点在OPEN表中的位置if setOpenCosts(I) > cost(jj)  %如果在OPEN表中的此点实际代价比现在所得的大costchart(setOpen(I)) = cost(jj);    %将当前的代价存入costchart中,注意此点在costchart中的坐标与其自身坐标是一致的(setOpen(I)其实就是posinds(jj)),下同fieldpointerssetOpenCosts(I) = cost(jj);      %更新OPEN表中的此点代价,注意此点在setOpenCosts中的坐标与在setOpen中是一致的,下同setOpenHeuristicssetOpenHeuristics(I) = heuristic(jj);    %更新OPEN表中的此点启发代价(窃以为这个是没有变的)fieldpointers(setOpen(I)) = setOpen(ii);   %更新此点的方向   endendendendfor jj=1:length(posinds1)      %对于扩展的四个方向的坐标if(field(posinds1(jj))~=6 && field(posinds1(jj))~=2 && field(posinds1(jj))~=7 && posinds1(jj)~=1)field(posinds1(jj))=4; if ~max([setClosed1; setOpen1] == posinds1(jj))%如果此点不在OPEN表和CLOSE表中fieldpointers1(posinds1(jj)) = setOpen1(ii1); %将此点的方向存在对应的fieldpointers中costchart(posinds1(jj)) = cost1(jj); %将实际代价值存入对应的costchart中setOpen1 = [setOpen1; posinds1(jj)]; %将此点加入OPEN表中setOpenCosts1 = [setOpenCosts1; cost1(jj)];   %更新OPEN表实际代价setOpenHeuristics1 = [setOpenHeuristics1; heuristic1(jj)];    %更新OPEN表启发代价elseif max(setOpen1 == posinds1(jj)) %如果此点在OPEN表中I = find(setOpen1 == posinds1(jj));   %找到此点在OPEN表中的位置if setOpenCosts1(I) > cost1(jj)  %如果在OPEN表中的此点实际代价比现在所得的大costchart(setOpen1(I)) = cost1(jj);    %将当前的代价存入costchart中,注意此点在costchart中的坐标与其自身坐标是一致的(setOpen(I)其实就是posinds(jj)),下同fieldpointerssetOpenCosts1(I) = cost1(jj);      %更新OPEN表中的此点代价,注意此点在setOpenCosts中的坐标与在setOpen中是一致的,下同setOpenHeuristicssetOpenHeuristics1(I) = heuristic1(jj);    %更新OPEN表中的此点启发代价(窃以为这个是没有变的)fieldpointers1(setOpen1(I)) = setOpen1(ii1);   %更新此点的方向   endendendend %% 更新open表update_open(ii,ii1)if (isempty(setOpen) && isempty(setOpen1))break; end    %当OPEN表为空,代表可以经过的所有点已经查询完毕
end
toc%% 查找并显示路径
if(max(ismember(setOpen,setOpen1)))disp('已找到路径!');  %disp: Display array, disp(X)直接将矩阵显示出来,不显示其名字,如果X为string,就直接输出文字Xb=intersect(setOpen,setOpen1);%取setClosed和setClosed1的交集path=b;%查找从起点开始搜索的路径while (fieldpointers(path(1)) ~= 0) path = [fieldpointers(path(1)), path];     end path2=b;%查找从终点搜索的路径while (fieldpointers1(path2(1)) ~= 0) path2 = [fieldpointers1(path2(1)), path2];     end p1=[path,flip(path2)]; %flip 颠倒矩阵for k = 2:length(p1) - 1 field(p1(k)) = 7;image(1.5, 1.5, field);grid on;set(gca,'gridline','-','gridcolor','r','linewidth',2);set(gca,'xtick',1:1:12,'ytick',1:1:12);axis image;drawnow;end
elsedisp('路径不存在!'); endtitle('基于{ \color{red}A*} 算法的路径规划 ','fontsize',16)
end%% 更新open表
function update_open(ii,ii1)global   setOpenCostsglobal   setOpenCosts1global   setOpenglobal   setOpen1global setOpenHeuristics;global setOpenHeuristics1;
%  更新OPEN表 分为三种情况%从起点开始的open表if (ii > 1 && ii < length(setOpen))   %temp在OPEN表的中间,删除tempsetOpen = [setOpen(1:ii-1); setOpen(ii+1:end)];setOpenCosts = [setOpenCosts(1:ii-1); setOpenCosts(ii+1:end)];setOpenHeuristics = [setOpenHeuristics(1:ii-1); setOpenHeuristics(ii+1:end)];elseif (ii == 1)setOpen = setOpen(2:end);   %temp是OPEN表的第一个元素,删除tempsetOpenCosts = setOpenCosts(2:end);setOpenHeuristics = setOpenHeuristics(2:end);else     %temp是OPEN表的最后一个元素,删除tempsetOpen = setOpen(1:end-1);setOpenCosts = setOpenCosts(1:end-1);setOpenHeuristics = setOpenHeuristics(1:end-1);end% 从终点开始的open表if (ii1 > 1 && ii1 < length(setOpen1))   %temp在OPEN表的中间,删除tempsetOpen1 = [setOpen1(1:ii1-1); setOpen1(ii1+1:end)];setOpenCosts1 = [setOpenCosts1(1:ii1-1); setOpenCosts1(ii1+1:end)];setOpenHeuristics1 = [setOpenHeuristics1(1:ii1-1); setOpenHeuristics1(ii1+1:end)];elseif (ii1 == 1)setOpen1 = setOpen1(2:end);   %temp是OPEN表的第一个元素,删除tempsetOpenCosts1 = setOpenCosts1(2:end);setOpenHeuristics1 = setOpenHeuristics1(2:end);else     %temp是OPEN表的最后一个元素,删除tempsetOpen1 = setOpen1(1:end-1);setOpenCosts1 = setOpenCosts1(1:end-1);setOpenHeuristics1 = setOpenHeuristics1(1:end-1);endend%% 获得当前的点的邻居
function [posinds,posinds1,cost,cost1,heuristic,heuristic1]=get_neighbors(n,ii,ii1,currentpos_x,currentpos_y,currentpos1_x,currentpos1_y,goalpos_x,goalpos_y,startpos_x,startpos_y)global   setOpenCostsglobal   setOpenCosts1
cost = Inf*ones(4,1); heuristic = Inf*ones(4,1); pos = ones(4,2);  cost1 = Inf*ones(4,1); heuristic1 = Inf*ones(4,1); pos1 = ones(4,2); %  左侧查询newx = currentpos_x ; newy = currentpos_y-1; if newy > 0  %如果没有到边界pos(1,:) = [newx newy];   %获得新的坐标heuristic(1) = abs(goalpos_x-newx) + abs(goalpos_y-newy);    %heuristic(1)为启发函数计算的距离代价% heuristic(1) = sqrt((goalpos(1)-newx)^2 + (goalpos(2)-newy)^2);    %heuristic(1)为启发函数计算的距离代价cost(1) = setOpenCosts(ii) +  1;   %costsofar为之前花费的代价,field(newy,newx)为环境威胁代价,cost(1)为经过此方向点的真实代价endnewx1 = currentpos1_x ; newy1= currentpos1_y-1; if newy1 > 0  %如果没有到边界pos1(1,:) = [newx1 newy1];   %获得新的坐标heuristic1(1) = abs(startpos_x-newx1) + abs(startpos_y-newy1);    %heuristic(1)为启发函数计算的距离代价% heuristic(1) = sqrt((goalpos(1)-newx)^2 + (goalpos(2)-newy)^2);    %heuristic(1)为启发函数计算的距离代价cost1(1) = setOpenCosts1(ii1) +  1;   %costsofar为之前花费的代价,field(newy,newx)为环境威胁代价,cost(1)为经过此方向点的真实代价end%  向右查询newx = currentpos_x; newy = currentpos_y+1;if newy <= npos(2,:) = [newx newy];heuristic(2) = abs(goalpos_x-newx) + abs(goalpos_y-newy);  %heuristic(1)为启发函数计算的距离代价% heuristic(2) = sqrt((goalpos(1)-newx)^2 + (goalpos(2)-newy)^2); cost(2) =setOpenCosts(ii) +  1;endnewx1 = currentpos1_x; newy1 = currentpos1_y+1;if newy1 <= npos1(2,:) = [newx1 newy1];heuristic1(2) = abs(startpos_x-newx1) + abs(startpos_y-newy1);  %heuristic(1)为启发函数计算的距离代价% heuristic(2) = sqrt((goalpos(1)-newx)^2 + (goalpos(2)-newy)^2); cost1(2) =setOpenCosts1(ii1) +  1;end%  向上查询newx = currentpos_x+1; newy = currentpos_y;if newx <= npos(3,:) = [newx newy];heuristic(3) = abs(goalpos_x-newx) + abs(goalpos_y-newy);    %heuristic(1)为启发函数计算的距离代价%  heuristic(3) = sqrt((goalpos(1)-newx)^2 + (goalpos(2)-newy)^2); cost(3) =setOpenCosts(ii) + 1;endnewx1 = currentpos1_x+1; newy1 = currentpos1_y;if newx1 <= npos1(3,:) = [newx1 newy1];heuristic1(3) = abs(startpos_x-newx1) + abs(startpos_y-newy1);    %heuristic(1)为启发函数计算的距离代价%  heuristic(3) = sqrt((goalpos(1)-newx)^2 + (goalpos(2)-newy)^2); cost1(3) =setOpenCosts1(ii1) + 1;end%   向下查询newx = currentpos_x-1; newy = currentpos_y;if newx > 0pos(4,:) = [newx newy];heuristic(4) = abs(goalpos_x-newx) + abs(goalpos_y-newy);    %heuristic(1)为启发函数计算的距离代价%heuristic(4) = sqrt((goalpos(1)-newx)^2 + (goalpos(2)-newy)^2); cost(4) = setOpenCosts(ii) + 1;endnewx1 = currentpos1_x-1; newy1 = currentpos1_y;if newx1 > 0pos1(4,:) = [newx1 newy1];heuristic1(4) = abs(startpos_x-newx1) + abs(startpos_y-newy1);    %heuristic(1)为启发函数计算的距离代价%heuristic(4) = sqrt((goalpos(1)-newx)^2 + (goalpos(2)-newy)^2); cost1(4) = setOpenCosts1(ii1) + 1;end
%     %   左上查询
%          newx = currentpos(1)-1; newy = currentpos(2)-1;
%         if (newy >0 && newx>0)
%            pos1(1,:) = [newx newy];
%            heuristic1(1)=abs(goalpos(1)-newx) + abs(goalpos(2)-newy);    %heuristic(1)为启发函数计算的距离代价
%            cost1(1) = setOpenCosts(ii)  + sqrt(2)*field(newx,newy);
%        end
%   %    右上查询
%      newx = currentpos(1)-1; newy = currentpos(2)+1;
%      if (newy <= n && newx>0)
%         pos1(2,:) = [newx newy];
%         heuristic1(2) = abs(goalpos(1)-newx) + abs(goalpos(2)-newy);    %heuristic(1)为启发函数计算的距离代价
%         cost1(2) = setOpenCosts(ii)  +sqrt(2)*field(newx,newy);
%      end
%  %  左下查询
%      newx = currentpos(1)+1; newy = currentpos(2)-1;
%      if (newy > 0 && newx<=n)
%         pos1(3,:) = [newx newy];
%         heuristic1(3) = abs(goalpos(1)-newx) + abs(goalpos(2)-newy);    %heuristic(1)为启发函数计算的距离代价
%         cost1(3) = setOpenCosts(ii)  + sqrt(2)*field(newx,newy);
%      end
%     %  右下查询
%      newx = currentpos(1)+1; newy = currentpos(2)+1;
%      if (newx <= n && newy<=n)
%         pos1(4,:) = [newx newy];    
%         heuristic1(4) = abs(goalpos(1)-newx) + abs(goalpos(2)-newy);    %heuristic(1)为启发函数计算的距离代价
%         cost1(4) = setOpenCosts(ii)  + sqrt(2)*field(newx,newy);
%      endposinds = sub2ind([n,n],pos(:,1),pos(:,2));posinds1 = sub2ind([n,n],pos1(:,1),pos1(:,2));
end%% 注释:当获取当前点的邻居向8个方向时,估计函数h(n)要采用切比雪夫距离

 

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

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

相关文章

linux特殊权限_suid_chattr_umask

3.3 特殊权限 如果一个文件很重要&#xff0c;需要依赖特殊权限避免其被删除。 由于特殊权限会拥有一些“特权”&#xff0c;因而用户若无特殊需要&#xff0c;不应该去打开这些权限&#xff0c;避免安全方面出现严重漏洞&#xff0c;甚至摧毁系统。3个权限是对了执行文件或目…

FPGA串口接收解帧、并逐帧发送有效数据-2

FPGA串口接收解帧、并逐帧发送有效数据 工程实现的功能&#xff1a;FPGA串口接收到串口调试助手发来的数据&#xff0c;将其数据解帧。判断到正确的帧头和帧尾之后&#xff0c;将有效数据存入rx_data中&#xff1b;另一方面发送端将有效数据逐帧发送出去。 参考&#xff1a;正…

【电路笔记】-串联和并联电阻

串联和并联电阻 文章目录 串联和并联电阻1、概述2、串联和并联电阻示例13、串联和并联电阻示例2 电阻器可以无限数量的串联和并联组合连接在一起&#xff0c;形成复杂的电阻电路。 1、概述 在之前的教程中&#xff0c;我们学习了如何将各个电阻器连接在一起以形成串联电阻器网…

linux设置权限_setfacl_getfacl

3.2 设置权限ACL&#xff08;access control list&#xff09; 假设&#xff1a;/data所有者与所属组均为root&#xff0c;在不改变所有者的前提下&#xff0c;要求用户tom对该目录有完全访问权限&#xff08;rwx&#xff09;。只能考虑&#xff1a; 方法一&#xff1a;给/dat…

超详细实现【贪吃蛇】(1)

目录 技术要点介绍 &#x1f642;Win32 API &#x1f642;控制台程序 &#x1f387;标题 &#x1f387;大小 在Windows终端上&#xff1a; 在VS上&#xff1a; &#x1f387;坐标 &#x1f642;光标 &#x1f636;‍&#x1f32b;️GetStdHandle &#x1f636;‍&am…

基于STM32 + TIM _定时器的基本机构和工作原理详解

前言 本篇博客主要学习了解定时器的基本结构和工作原理&#xff0c;掌握定时器的驱动程序和设计。本篇博客大部分是自己收集和整理&#xff0c;如有侵权请联系我删除。 本次博客板子使用的是正点原子精英版&#xff0c;芯片是STM32F103ZET6,需要资料可以我拿取。 本博客内容原…

[数据结构]红黑树的定义以及添加原则

红黑树是一种自平衡的二叉查找树&#xff0c;是一种常用的数据结构 1972年出现&#xff0c;在当时被称为平衡二叉B树。后来1978年被修改为如今的“红黑树” 它是一个特殊的二叉查找树&#xff0c;红黑树的每一个节点上都有储存位表示节点的颜色 每一个节点可以是红或者黑&#…

代码生成器——MyBatisX插件

MyBatisX插件 MyBatis-Plus为我们提供了强大的mapper和service模板&#xff0c;能够大大的提高开发效率。 但是在真正开发过程中&#xff0c;MyBatis-Plus并不能为我们解决所有问题&#xff0c;例如一些复杂的SQL&#xff0c;多表联查&#xff0c;我们就需要自己去编写代码和SQ…

密码学实验三

第一题&#xff1a; 寻找满足特定条件的 e&#xff1b; 第一步&#xff1a; 第二步&#xff1a; 由式1.7知&#xff0c;给定e,p,q&#xff0c;就可计算出相应的RSA不动点的数目。因此设计算法步骤如下&#xff1a; 枚举找出所有与φ(n)互素的e。枚举所有满足条件的e&#xff…

为XiunoBBS4.0开启redis缓存且支持密码验证

修改模块文件1 xiunoPHP/cache_redis.class.php: <?phpclass cache_redis {public $conf array();public $link NULL;public $cachepre ;public $errno 0;public $errstr ;public function __construct($conf array()) {if(!extension_loaded(Redis)) {return $thi…

HTTP 基本概念(计算机网络)

一、HTTP 是什么&#xff1f; HTTP(HyperText Transfer Protocol) &#xff1a;超文本传输协议。 HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。 「HTTP 是用于从互联网服务器传输超文本到本地浏览器的协议…

Linux部分基础指令讲解

目录 1.echo指令 2.more指令 3.less指令&#xff08;重要&#xff09; 4.head指令 5.tail指令 6.管道| 7.时间相关的指令 8.cal指令 9.find指令 10.grep指令 1.echo指令 我们先看效果 如图所示我们可以看到显示器显示出了hellow world和hellow这两句话&#xff0c;我们的echo的…

51单片机对SHT30的驱动,读取温湿度

一、SHT30简介 SHT30温湿度传感器是一种数字式温湿度传感器&#xff0c;由Sensirion公司开发和生产。它具有高精度、快速响应和稳定性强的特点&#xff0c;被广泛用于气象观测、室内环境监测、智能家居和工业自动化等领域。 以下是SHT30温湿度传感器的主要特点&#xff1a; 高精…

简单句子成分、阅读技巧

四、段落的主旨题&#xff1a;问这一段讲了什么&#xff08;一般都在段落的第一句话或最后一句话&#xff09; 词汇题的答案一般都在生词的上一句或者下一句 做题步骤&#xff1a; 1、先标段落 2、看题&#xff0c;划出关键词 3、去原文定位&#xff0c;标注中文意思 4、第一遍…

Dart编程基础 - 一种新的编程语言

Dart编程基础 – 一种新的编程语言 Dart Programming Essentials - A New Type of Programming Language By JacksonML Dart is a client-optimized language for fast apps on any platform From dart.dev 在1999年之前&#xff0c;和我一样对计算机技术感兴趣的伙伴们&…

1094. 拼车(差分堆排序)

Problem: 1094. 拼车 文章目录 题目思路Review 差分数组定义区间加法减法更新差分数组&#xff1a;为啥这样更新 思路1 Code思路2 Code 题目 车上最初有 capacity 个空座位。车 只能 向一个方向行驶&#xff08;也就是说&#xff0c;不允许掉头或改变方向&#xff09; 给定整…

高级前端面试中的三个 “送命题” !!!

原型与原型链 说到原型&#xff0c;就不得不提一下构造函数&#xff0c;首先我们看下面一个简单的例子&#xff1a; function Dog(name,age){this.name name;this.age age; }let dog1 new Dog("哈士奇",3); let dog2 new Dog("泰迪",2);首先创造空的…

机械臂运动规划、抓取末端执行器、抓取开源项目

运动规划 1.1已有抓取点 假设抓取点已检测到。这些方法设计了从机器人手到目标物体抓取点的路径。这里运动表示是关键问题。虽然存在从机器人手到目标抓握点的无限数量的轨迹&#xff0c;但是由于机器人臂的限制&#xff0c;许多区域无法到达。因此&#xff0c;需要对轨迹进行…

python etree.HTML 以及xpath 解析网页的工具

文章目录 导入模块相关语法实战 导入模块 from lxml import etree相关语法 XPath&#xff08;XML Path Language&#xff09;是一种用于在XML文档中定位和选择元素的语言。XPath的主要应用领域是在XML文档中进行导航和查询&#xff0c;通常用于在XML中选择节点或节点集合。以…

UiPath学习笔记

文章目录 前言RPA介绍UiPath下载安装组件内容 前言 最近有一个项目的采集调研涉及到了客户端的采集&#xff0c;就取了解了一下RPA和UIPATH&#xff0c;记录一下 RPA介绍 RPA&#xff08;Robotic Process Automation&#xff1a;机器人处理自动化&#xff09;&#xff0c;是…