HJL Posted April 3, 2021 Share Posted April 3, 2021 Is it possible to read an XPath with AutoIt instead of using "Inspect" and ChroPath? I would like to write a script that takes the XPath of a mouse-clicked field or button into a variable, like copy and paste. That would save a lot of time. Link to comment Share on other sites More sharing options...
JackER4565 Posted April 4, 2021 Share Posted April 4, 2021 yes you can. If you want you can read the entire HTML and go through the elements in it. Link to comment Share on other sites More sharing options...
HJL Posted April 4, 2021 Author Share Posted April 4, 2021 (edited) 12 hours ago, JackER4565 said: yes you can. If you want you can read the entire HTML and go through the elements in it. That's not the problem. I want to get that XPath, that is under the mouse. If I read the entire HTML, I don't know where I clicked. It is like "Inspect" and "Copy XPath" what I am searching for - but automatic. Edited April 4, 2021 by HJL Link to comment Share on other sites More sharing options...
Gianni Posted April 5, 2021 Share Posted April 5, 2021 ...maybe not exactly what you are looking for, but you can take a look at the following link as an example to modify for your goals Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
seadoggie01 Posted April 5, 2021 Share Posted April 5, 2021 (edited) I actually did this. You'll need two things, this script and a JavaScript function that will get the XPath of an element passed to it. Spoiler This is my XPathFromMouse.au3 file. Edit it (to set your webdriver location and other properties), run it, and press Ctrl+6 to get another XPath expandcollapse popup#include <wd_core.au3> #include <wd_helper.au3> ;#include <WD_Ex.au3> Not needed, personal use ;#include <CustomDebugging.au3> Not needed, added Debug + ErrMsg Global $sSession, $__g_iXPathIndex = 0, $sConfig = @ScriptDir & "\config.ini" Main() Func Main() Local $sDriverPath = @AppDataDir & "\WebDrivers\msedgedriver.exe" _WD_Option('Driver', $sDriverPath) _WD_Option('DriverClose', True) _WD_Option('DriverDetect', False) _WD_Option('Port', 9515) _WD_Startup() If ErrMsg(_WD_Startup) Then Exit Local $sDesiredCapabilities = '{"capabilities":{"alwaysMatch": {"ms:edgeOptions": {"w3c": true, "prefs": {"plugins.always_open_pdf_externally": true}}}}}' $sSession = _WD_CreateSession($sDesiredCapabilities) If ErrMsg(_WD_CreateSession) Then Exit OnAutoItExitRegister(CloseChrome) _WD_Navigate($sSession, "https://www.google.com") HotKeySet("^6", GetXPath) While True Sleep(200) WEnd EndFunc Func GetXPath() #ToDo: Determine if window is active #ToDo: Determine which tab is active and attach Local $sElement = _WD_GetMouseElement($sSession) If ErrMsg(_WD_GetMouseElement) Then Exit Local $vRet = _WDEx_ElementXPathGet($sSession, $sElement) If ErrMsg(_WDEx_ElementXPathGet) Then Exit Debug("Path: " & $vRet) Local $sFoundElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, $vRet) If ErrMsg(_WD_FindElement) Then Exit If Not ($sElement = $sFoundElement) Then Debug("Mouse Element: " & $sElement) Debug("Found Element: " & $sFoundElement) Return SetError(1, 0, False) Else IniWrite($sConfig, "XPaths", $__g_iXPathIndex, $vRet) $__g_iXPathIndex += 1 EndIf EndFunc Func _WDEx_ElementXPathGet($sSession, $sElementId) Local $WD_Debug_Saved = $_WD_Debug $_WD_Debug = $_WD_DEBUG_None ; Pulled from: https://stackoverflow.com/questions/2661818/javascript-get-xpath-of-a-node Local $sResponse = _WD_ExecuteScript($sSession, FileRead(@UserProfileDir & "\Documents\AutoIt\javascript_test.txt"), '{"' & $_WD_ELEMENT_ID & '":"' & $sElementId & '"}') If ErrMsg(_WD_ExecuteScript) Then $_WD_Debug = $WD_Debug_Saved Return SetError(1, @error, False) EndIf Local $oJson = Json_Decode($sResponse) Local $vRet = Json_Get($oJson, "[value]") $_WD_Debug = $WD_Debug_Saved Return $vRet EndFunc Func CloseChrome() _WD_DeleteSession($sSession) _WD_Shutdown() EndFunc Func Debug($sMsg, $sPrefix = "+") ; Write to the console if we're not compiled If Not @Compiled Then If $sPrefix <> "" Then $sPrefix &= " " ConsoleWrite($sPrefix & $sMsg & @CRLF) EndIf EndFunc Func ErrMsg($sMsg = "", $iError = @error, $iExtended = @extended, $iScriptLineNum = @ScriptLineNumber) ; If we've used a Function as the message (it looks really nice when I do) then print the name of the function If IsFunc($sMsg) Then $sMsg = FuncName($sMsg) ; If there is an error, then write the error message If $iError Then Local $sText = '"' & @ScriptFullPath & '" (' & $iScriptLineNum & ',5) : (See below for message)' & @CRLF If $iExtended <> 0 Then $sMsg = "Extended: " & $iExtended & " - " & $sMsg $sText &= "! Error: " & $iError & " - " & $sMsg Debug($sText, "") EndIf ; Preserve the error Return SetError($iError, $iExtended, $iError) EndFunc #cs ============= Output File Pattern ============= [Step Sequence] <#>=<user defined step name> [<user defined step name>] Function name=<user selected function> <function name>-<property #>=<function specific property value> ============= Example Output File ============= [Step Sequence] 1=Open Google 2=Enter Search 3=Click Search [Open Google] Function name=_WD_Navigate _WD_Navigate-LoadWait=True [Enter Search] Function name=_WD_ElementAction _WD_ElementAction-XPath=id("tsf")/div[2]/div[@class="A8SBwf"]/div[@class="RNNXgb"]/div[@class="SDkEP"]/div[@class="a4bIc"]/input[@class="gLFyf gsfi"] _WD_ElementAction-Command=value _WD_ElementAction-Option=test [Click Search] Function name=_WD_ElementAction _WD_ElementAction-XPath=id("tsf")/div[2]/div[@class="A8SBwf"]/div[@class="FPdoLc tfB0Bf"]/center[1]/input[@class="gNO89b"] _WD_ElementAction-Command=click #ce I suggest trying out a few different functions from StackOverflow. You'll find a few different styles of XPath. Choose the one you like most. Spoiler The (slightly modified) javascript_test.txt, pulled the JavaScript from here: https://stackoverflow.com/questions/2661818/javascript-get-xpath-of-a-node Note: The important modification is adding "return <functionName>(arguments[0])" as this allows you to pass an element into the function and get the function's return value return createXPathFromElement(arguments[0]); function createXPathFromElement(elm) { var allNodes = document.getElementsByTagName('*'); for (var segs = []; elm && elm.nodeType == 1; elm = elm.parentNode) { if (elm.hasAttribute('id')) { var uniqueIdCount = 0; for (var n=0;n < allNodes.length;n++) { if (allNodes[n].hasAttribute('id') && allNodes[n].id == elm.id) uniqueIdCount++; if (uniqueIdCount > 1) break; }; if ( uniqueIdCount == 1) { segs.unshift('id("' + elm.getAttribute('id') + '")'); return segs.join('/'); } else { segs.unshift(elm.localName.toLowerCase() + '[@id="' + elm.getAttribute('id') + '"]'); } } else if (elm.hasAttribute('class')) { segs.unshift(elm.localName.toLowerCase() + '[@class="' + elm.getAttribute('class') + '"]'); } else { for (i = 1, sib = elm.previousSibling; sib; sib = sib.previousSibling) { if (sib.localName == elm.localName) i++; }; segs.unshift(elm.localName.toLowerCase() + '[' + i + ']'); }; }; return segs.length ? '/' + segs.join('/') : null; }; function lookupElementByXPath(path) { var evaluator = new XPathEvaluator(); var result = evaluator.evaluate(path, document.documentElement, null,XPathResult.FIRST_ORDERED_NODE_TYPE, null); return result.singleNodeValue; } Edited April 5, 2021 by seadoggie01 All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now