tbwalker Posted November 7, 2014 Share Posted November 7, 2014 (edited) I've been working on a test script for a Foscam FI9821w v2 camera to automatically open the web url of the camera, log in with the username and password, and shortcut map the UP,DOWN,LEFT,RIGHT controls. The only thing I'm having issues with are clicking the AUDIO and FULL SCREEN buttons once the main camera page has been reached. The reason I'm building this code is to simplify camera operations for my grandmother, so all she has to do is launch the autoit application and use the arrow keys to move her front door security camera. Here's the code I have so far. I've put in an actual working URL with a working username and password (demo camera provided by Foscam's website), so you can see the code actually work. expandcollapse popup#include <Misc.au3> #include <MsgBoxConstants.au3> #include <IE.au3> Local $CameraAddress = "gc8883.myfoscam.org" Local $CameraPort = "20070" Local $CameraUsername = "user" Local $CameraPassword = "user" Local $hDLL = DllOpen("user32.dll") ;getting ready for the _IsPressed Loop below WaitForIP($CameraAddress) ;This function pauses here until the camera can be pinged $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort);open the camera webpage _IELoadWait($oIE) ;Wait for slow page to load before continuing Local $oUserName = _IEGetObjById($oIE, "username") ;Get field name on login page to fill in Local $oPassword = _IEGetObjById($oIE, "passwd") ;Get field name on login page to fill in Local $oLogin = _IEGetObjById($oIE, "login_ok") ;Get button name to click to login _IEFormElementSetValue($oUserName, $CameraUsername) ;Set the username in the browser _IEFormElementSetValue($oPassword, $CameraPassword) ;Set the password in the browser _IEAction($oLogin, "click") ;Click the login button to continue to camera page While 1 If _IsPressed("26", $hDLL) Then ;Up Arrow Key Press CamUp() ElseIf _IsPressed("28", $hDLL) Then ;Down Arrow Key Press CamDown() ElseIf _IsPressed("25", $hDLL) Then ;Left Arrow Key Press CamLeft() ElseIf _IsPressed("27", $hDLL) Then ;Right Arrow Key Press CamRight() ElseIf _IsPressed("1B", $hDLL) Then ;{ESC} exits this app and closes browser CloseApp() EndIf Sleep(100) WEnd Func WaitForIP($sIP) ;Don't continue with this app until it can ping camera Do Sleep(250) ; Give the CPU a break Until ping($sIP) <> 0 EndFunc Func CloseApp() ProcessClose("iexplore.exe") DllClose($hDLL) exit EndFunc Func CamUp() $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort & "/cgi-bin/CGIProxy.fcgi?cmd=ptzMoveUp&usr=" & $CameraUsername & "&pwd=" & $CameraPassword, 0, 0, 1, 0) _IEQuit($oIE) ;Up Arrow Key is pressed, Sleep While _IsPressed("26", $hDLL) Sleep(250) WEnd $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort & "/cgi-bin/CGIProxy.fcgi?cmd=ptzStopRun&usr=" & $CameraUsername & "&pwd=" & $CameraPassword, 0, 0, 1, 0) _IEQuit($oIE) EndFunc Func CamDown() $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort & "/cgi-bin/CGIProxy.fcgi?cmd=ptzMoveDown&usr=" & $CameraUsername & "&pwd=" & $CameraPassword, 0, 0, 1, 0) _IEQuit($oIE) ;Down Arrow Key is pressed, Sleep While _IsPressed("28", $hDLL) Sleep(250) WEnd $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort & "/cgi-bin/CGIProxy.fcgi?cmd=ptzStopRun&usr=" & $CameraUsername & "&pwd=" & $CameraPassword, 0, 0, 1, 0) _IEQuit($oIE) EndFunc Func CamLeft() $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort & "/cgi-bin/CGIProxy.fcgi?cmd=ptzMoveLeft&usr=" & $CameraUsername & "&pwd=" & $CameraPassword, 0, 0, 1, 0) _IEQuit($oIE) ;Left Arrow Key is pressed, Sleep While _IsPressed("25", $hDLL) Sleep(250) WEnd ;Left Arrow Key is released $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort & "/cgi-bin/CGIProxy.fcgi?cmd=ptzStopRun&usr=" & $CameraUsername & "&pwd=" & $CameraPassword, 0, 0, 1, 0) _IEQuit($oIE) EndFunc Func CamRight() $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort & "/cgi-bin/CGIProxy.fcgi?cmd=ptzMoveRight&usr=" & $CameraUsername & "&pwd=" & $CameraPassword, 0, 0, 1, 0) _IEQuit($oIE) ;Right Arrow Key is pressed, Sleep While _IsPressed("27", $hDLL) Sleep(250) WEnd ;Right Arrow Key is released $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort & "/cgi-bin/CGIProxy.fcgi?cmd=ptzStopRun&usr=" & $CameraUsername & "&pwd=" & $CameraPassword, 0, 0, 1, 0) _IEQuit($oIE) EndFunc Here's a screenshot of the (2) buttons I would like to click: I've tried the following code to click the buttons, but nothing happens: $oDivs = _IETagNameGetCollection ($oIE, "div") For $oDiv in $oDivs If $oDiv.classname == "liveBtnBt9" Then MsgBox(0,"",$oDiv.classname) _IEaction($oDiv,"click") ExitLoop EndIf Next I've messed around with forcing the browser full screen, then mapping mouse clicks to the buttons. This sort of works, but it's not reliable if there's a delay in the page loading (mouse clicks before buttons actually load). Since the above camera address is live, you can actually see the HTML I'm trying to click. Neither of the DIV class buttons have ID's, and the FULL SCREEN div button has only a CLASS. Audio On Button: <div class="liveBtnBt9" name="active"></div> Full Screen Button <div class="liveBtnBT5"></div> If anyone could help point me in a better direction for how to automate clicking these 2 buttons, it would be greatly appreciated. I've searched the forum for every article on clicking DIV's with no ID's or NAME's, but nothing I've found so far actually works. Thanks, TBWalker Edited November 7, 2014 by tbwalker Link to comment Share on other sites More sharing options...
jdelaney Posted November 7, 2014 Share Posted November 7, 2014 (edited) Your code should be fine...try to add a _ieaction(,"focus") prior to the click. How do you know it's not loaded? Is there some attribute that's presnt when it is? You can add an additional loop to wait for the div: $iTimer = TimerInit() $iTimeout = 10000 While TimerDiff($iTimer )<$iTimeout $oDivs = _IETagNameGetCollection ($oIE, "div") For $oDiv in $oDivs If $oDiv.classname == "liveBtnBt9" Then MsgBox(0,"",$oDiv.classname) _IEaction($oDiv,"focus") _IEaction($oDiv,"click") ConsoleWrite("clicked..." & @CRLF) ExitLoop 2 EndIf Next WEnd Edited November 7, 2014 by jdelaney IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
tbwalker Posted November 7, 2014 Author Share Posted November 7, 2014 Thanks for the quick reply, jdelaney. I'll give that _ieaction(,"focus") a test run now. Link to comment Share on other sites More sharing options...
jdelaney Posted November 7, 2014 Share Posted November 7, 2014 (edited) Added a bit more, above. Oh, and that's the basics of my signature...looping until your object is found (within some timeout)...I just use xpaths instead, to drive the looping. Edited November 7, 2014 by jdelaney IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
tbwalker Posted November 7, 2014 Author Share Posted November 7, 2014 Thanks again jdelaney. I gave your suggestion a test drive with the code below. The console shows the "clicked..." at the end, but the video never goes full screen. #include <Misc.au3> #include <MsgBoxConstants.au3> #include <IE.au3> Local $CameraAddress = "gc8883.myfoscam.org" Local $CameraPort = "20070" Local $CameraUsername = "user" Local $CameraPassword = "user" $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort);open the camera webpage _IELoadWait($oIE) ;Wait for slow page to load before continuing Local $oUserName = _IEGetObjById($oIE, "username") ;Get field name on login page to fill in Local $oPassword = _IEGetObjById($oIE, "passwd") ;Get field name on login page to fill in Local $oLogin = _IEGetObjById($oIE, "login_ok") ;Get button name to click to login _IEFormElementSetValue($oUserName, $CameraUsername) ;Set the username in the browser _IEFormElementSetValue($oPassword, $CameraPassword) ;Set the password in the browser _IEAction($oLogin, "click") ;Click the login button to continue to camera page Sleep(15000) $iTimer = TimerInit() $iTimeout = 10000 While TimerDiff($iTimer )<$iTimeout $oDivs = _IETagNameGetCollection ($oIE, "div") For $oDiv in $oDivs If $oDiv.classname == "liveBtnBt5" Then ;FULLSCREEN DIV CLASS NAME MsgBox(0,"",$oDiv.classname) _IEaction($oDiv,"focus") _IEaction($oDiv,"click") ConsoleWrite("clicked..." & @CRLF) ExitLoop 2 EndIf Next WEnd I'll take your "XPATHS" suggestion and try and come up with a solution in that direction. Thanks again! Link to comment Share on other sites More sharing options...
jdelaney Posted November 7, 2014 Share Posted November 7, 2014 Could it be there are multiple instances of your div, with that classname? Remove the exit loop. IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
tbwalker Posted November 7, 2014 Author Share Posted November 7, 2014 I took the loop out to let it click every instance, but still nothing happening. Would there be a way to click/activate the CLASS with a CONTROLCLICK? I tried the test below to see if I could get CONTROLCLICK to click it, but I'm not sure I'm formatting the command correctly, or even if this is a command that could possibly work. I didn't know which INSTANCE, if any, to tell it to click, so I took the shotgun approach. expandcollapse popup#include <Misc.au3> #include <MsgBoxConstants.au3> #include <IE.au3> Local $CameraAddress = "gc8883.myfoscam.org" Local $CameraPort = "20070" Local $CameraUsername = "user" Local $CameraPassword = "user" $oIE = _IECreate("http://" & $CameraAddress & ":" & $CameraPort);open the camera webpage _IELoadWait($oIE) ;Wait for slow page to load before continuing Local $oUserName = _IEGetObjById($oIE, "username") ;Get field name on login page to fill in Local $oPassword = _IEGetObjById($oIE, "passwd") ;Get field name on login page to fill in Local $oLogin = _IEGetObjById($oIE, "login_ok") ;Get button name to click to login _IEFormElementSetValue($oUserName, $CameraUsername) ;Set the username in the browser _IEFormElementSetValue($oPassword, $CameraPassword) ;Set the password in the browser _IEAction($oLogin, "click") ;Click the login button to continue to camera page Sleep(25000) $hWnd = WinActivate("IPCam Client - Windows Internet Explorer") $oResult = ControlClick($hWnd, "", "[CLASS:liveBtnBt5]", 1) ConsoleWrite("Result = " & $oResult & @CRLF) sleep(1000) $oResult = ControlClick($hWnd, "", "[CLASS:liveBtnBt5; INSTANCE:1]", 1) ConsoleWrite("Result = " & $oResult & @CRLF) sleep(1000) $oResult = ControlClick($hWnd, "", "[CLASS:liveBtnBt5; INSTANCE:2]", 1) ConsoleWrite("Result = " & $oResult & @CRLF) sleep(1000) $oResult = ControlClick($hWnd, "", "[CLASS:liveBtnBt5; INSTANCE:3]", 1) ConsoleWrite("Result = " & $oResult & @CRLF) sleep(1000) $oResult = ControlClick($hWnd, "", "[CLASS:liveBtnBt5; INSTANCE:4]", 1) ConsoleWrite("Result = " & $oResult & @CRLF) sleep(1000) $oResult = ControlClick($hWnd, "", "[CLASS:liveBtnBt5; INSTANCE:5]", 1) ConsoleWrite("Result = " & $oResult & @CRLF) sleep(1000) exit Link to comment Share on other sites More sharing options...
jdelaney Posted November 7, 2014 Share Posted November 7, 2014 (edited) Nope...you might be able to focus, and then send "{Enter}" at the browser, but you can't use control functions, reliably (x,y coords only, via mouseclick...bad option), on a browser. Edited November 7, 2014 by jdelaney IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
tbwalker Posted November 8, 2014 Author Share Posted November 8, 2014 I installed a firefox plugin to get the unique xpaths for what I want to click: for the audio on, XPath Checker told me its XPath was: id('ftLive')/x:div[10] for audio off: id('ftLive')/x:div[11] for the fullscreen: id('ftLive')/x:div[5] I went to your IEbyXPATH link and I'm trying to get a grasp on how to click the xpaths above, but I'm a bit stumped on how to take the code you provide and try and use it to click on the xpaths I have here... I'll keep playing with it and post back if I'm able to make it work. Thanks again for your help. Link to comment Share on other sites More sharing options...
tbwalker Posted November 8, 2014 Author Share Posted November 8, 2014 Oops... still learning about this XPATH stuff... the XPATH info I gave in my previous post was from FIREFOX, but what I'm trying to accomplish is in INTERNET EXPLORER... After a bit more reading I realized that the XPATH element format for IE would be different, so I found a utility ( Fire-IEBrowser.xlsm located at http://code.google.com/p/fire-ie-selenium/downloads/list ) and used it to get the XPATHs of the elements I'm trying to click. The results were, for audio on: //div[@id='ftLive']/div[10] for audio off: //div[@id='ftLive']/div[11] for the fullscreen: //div[@id='ftLive']/div[5] I'm going to keep plugging away at this. With any luck I'll be able to mark this solved by tomorrow with updated code! Link to comment Share on other sites More sharing options...
Broden Posted May 14, 2017 Share Posted May 14, 2017 Hello tbwalker, I know it's been a while since you posted above messages, but i'm trying to accomplish exactly the same. Did you find a solution at last? It would be great help for me. Bastiaan Link to comment Share on other sites More sharing options...
jdelaney Posted May 19, 2017 Share Posted May 19, 2017 (edited) Those xpath's look good (post #10)...my script should handle it, but I don't recall if I kept the initial post up to date...you might have to dig in deeper to find where the [n] can be used...probably a link to it in the post...edit: here it is: The function returns an array of matching objects. I'd suggest adding my script as a udf, and #include it in yours...it's rather long, and can be greatly optimized, but will work...I use some form if it at my work to reliably test our websites after builds. Edited May 19, 2017 by jdelaney IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. 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