Sign in to follow this  
Followers 0

Click a link on a webpage in IE

26 posts in this topic

Posted (edited)

I've been trying to figure this out for a long time... finally got it. This function allows you to specify the text a a link that you want to actvate on a webpage and it will click it for you.

Dale

Note: Requires the post 3.1.1 betas for COM support

$ObjIE = ObjCreate ("InternetExplorer.Application")
With $ObjIE
   .Visible = True
   .Navigate ("http://www.autoitscript.com/")
   
   While .ReadyState <> 4
      Sleep(50)
   WEnd
EndWith

clickLink($ObjIE, "forum", 2)

Exit

Func clickLink($obj, $searchText, $instance = 1)
  ; clickLink( $obj, $serachText [, $instance])
  ; $obj - Object Valiable pointing to an InternetExplorer.Application object
  ; $searchText - the text displayed on the web page for the desired link to click
  ; [$instance] - if the link text occurs more than once, specify which instance you want to click (numbering starts at 1)
   $doc = $obj.document
   $links = $doc.links
   $found = 0
   For $link in $links
      $linkText = $link.outerText
      If $linkText = $searchText Then
         $found = $found + 1
         if ($found = $instance) Then
            $result = $link.click
            ExitLoop
         EndIf
      EndIf
   Next
   
EndFunc  ;==>clickLink
Edited by DaleHohm

Share this post


Link to post
Share on other sites



Posted

Excellent / Thx for sharing

HardCopy

Share this post


Link to post
Share on other sites

Posted (edited)

Hi I like the potential....

It does not still find exact matches, though! - if i look for "Edit Post", it finds all manner of links; sure, I can specify them by picking link number, but this was not your intention?

I think your matching line needs fixing, but don't know the syntax;

    $doc = $obj.document

   $links = $doc.links

   $found = 0

   For $link in $links

      $linkText = $link.outerText

      If ($linkText = $searchText) Then

EDIT - I thought this script had a problem; but I see it is just that I don't know how to retrieve the text items from the variables - or ? from the function; I cannot use "return" from the function to seem to get any text?

Can anybody please help? *** -I will post on Support as well, thanks

Best, Randall

Edited by randallc

Share this post


Link to post
Share on other sites

Posted

Hi I like the potential....

It does not still find exact matches, though! - if i look for "Edit Post", it finds all manner of links; sure, I can specify them by picking link number, but this was not your intention?

I think your matching line needs fixing, but don't know the syntax;

Can anybody please help?  It should be correct?- is it a bug?; I think this is trying to compare a link number with the text?

Best, Randall

<{POST_SNAPBACK}>

Excellent but with a big problem, that's doesn't works with frames

Share this post


Link to post
Share on other sites

Posted

Hi,

Are you saying you can do that another way?; or only by pixel-raeding the screen etc?

Share this post


Link to post
Share on other sites

Posted

@radallc: I don't know why you'd get unpredictable links -- it is doing an exact match. After the "For $ link in $links" line you might want to insert something like this so you can better see what is happening: ConsoleWrite("$linkText = " & $link.outerText & @CR)

@LOULOU: regarding frames -- I haven't tested, but it is an issue. We'll have to figure out how to interate through the documents in the frameset -- drop an example of a framed page with a link you wnat here and I'll have a look.

Dale

Share this post


Link to post
Share on other sites

Posted (edited)

Thanks for that!

it seems to match the "$LinkText" as equal when it is "0"; (which seems to be the button links). So Button links are included in "links" but no text retrieved, and then matched as equal despite being zero!

What else....?

So in the "if =" statement I can access the other links if I "And $Link<>0".

      If ($linkText = $searchText) and ($linkText<>"0") Then

It is actually a button I'm trying to click right now!

Randall

PS When I do get a link matched, I am not getting to the link anyway as "popup blocked"; asks for "control-click"; can we do that in this script?

Edited by randallc

Share this post


Link to post
Share on other sites

Posted

OK, so I have the frames figured out. New functions here to be able to get info on Frames and to create an object variable pointing to the frame window.

Also believe there is a fix here for links that were being matched when there was no link text.

In addition, there is a new function here to click a link based on its 0 based index instead of matchine text... this allows clicking links even if they are images and have no text.

Sometimes a link requires using ctrl-click to get around a pop-up blocker... I don't know how to do that and my search has come up dry so far.

Enjoy!

Dale

Example calling script:

; Open browser, load a page and wait for load to complete
$ObjIE = ObjCreate ("InternetExplorer.Application")
With $ObjIE
	.Visible = True
	.Navigate("http://www.mme.state.va.us/")
	While .ReadyState <> 4
		Sleep(50)
	WEnd
EndWith

ConsoleWrite(_IE_IsFrameSet($ObjIE) & @CR)
ConsoleWrite(_IE_NumFrames($ObjIE) & @CR)

; Loop through the frames and show the URL of each
For $i = 1 To _IE_NumFrames($ObjIE)
	$ObjF = _IE_FrameObj($ObjIE, $i - 1)
	ConsoleWrite("Frame" & $i & " - " & $ObjF.document.location.href & @CR)
Next

; Click on the "Our Values" link in the third frame (0 based)
_IE_clickLinkText(_IE_FrameObj($ObjIE, 2), "Our Values")

; Click on the third link on the third frame
;_IE_clickLinkIndex(_IE_FrameObj($ObjIE, 2), 2)

Exit

Functions:

Func _IE_IsFrameSet($_obj)
   ; Returns 1 if the object references a FrameSet page, else 0
   ;
   ; Note: this is more reliable test for a FrameSet than checking the
   ; number of frames (...frames.length) because an iFrame embedded on a normal
   ; page is included in the frame collection
	$_t = $_obj.document.body.tagName
	If $_t = "FRAMESET" Then
		Return 1
	Else
		Return 0
	EndIf
EndFunc  ;==>_IE_IsFrameSet

Func _IE_NumFrames($_obj)
   ; Returns the number of frames in a FrameSet or the number of iFrames on a normal page
	Return $_obj.document.parentwindow.frames.length
EndFunc  ;==>_IE_NumFrames

Func _IE_FrameObj($_obj, $_f)
   ; Returns an object reference to a window within the specified frame (note that frame collection is 0 based)
   ; This object can be used in the same manner as the InternetExplorer.Application object
	If IsObj ($_obj.document.parentwindow.frames.item ($_f)) Then
		Return $_obj.document.parentwindow.frames.item ($_f)
	Else
		Return 0
	EndIf
EndFunc  ;==>_IE_FrameObj

Func _IE_clickLinkText($_obj, $_l, $_i = 1)
   ; _IE_clickLinkText( $_obj, $_l [, $_i])
   ; $_obj - Object Valiable pointing to an InternetExplorer.Application object
   ; $_l - linkText, the text displayed on the web page for the desired link to click
   ; [$_i] - if the link text occurs more than once, specify which instance you want to click
   ;		note: instance numbering starts at 1
	$doc = $_obj.document
	$links = $doc.links
	$found = 0
	For $link in $links
		$linkText = $link.outerText & ""; Append empty string to prevent problem with no outerText (image) links
	   ;ConsoleWrite("$linkText = " & $linkText & @CR)
		ConsoleWrite("$linkText = " & $link.href & @CR)
		If $linkText = $_l Then
			$found = $found + 1
			if ($found = $_i) Then
				$result = $link.click
				return 1
			EndIf
		EndIf
	Next
	return 0
EndFunc  ;==>_IE_clickLinkText

Func _IE_clickLinkIndex($_obj, $_i)
   ; _IE_clickLinkText( $_obj, $_i)
   ; $_obj - Object Valiable pointing to an InternetExplorer.Application object
   ; $_i - 0 based index of the link number to click
	$doc = $_obj.document
	if IsObj($doc.links($_i)) Then
		ConsoleWrite("$linkHref = " & $doc.links($_i).href & @CR)
		$doc.links($_i).click
		return 1
	Else
		return 0
	EndIf
EndFunc  ;==>_IE_clickLinkIndex

Share this post


Link to post
Share on other sites

Posted

Thanks dalehorn, good stuff.

One question Did you know how to control individually the READYSTATE function for a frameset ?

Share this post


Link to post
Share on other sites

Posted

Haven't done much testing yet, but this function seems to work. I think there is more tha can be done to generalize this because many objects can return a ReadyState...

Func _IE_ReadyState($_obj)

; Returns ReadyState value for Window or Frame objects

Return $_obj.document.ReadyState

EndFunc ;==>_IE_ReadyState

Share this post


Link to post
Share on other sites

Posted

Haven't done much testing yet, but this function seems to work.  I think there is more tha can be done to generalize this because many objects can return a ReadyState...

Func _IE_ReadyState($_obj)

  ; Returns ReadyState value for Window or Frame objects

    Return $_obj.document.ReadyState

EndFunc  ;==>_IE_ReadyState

<{POST_SNAPBACK}>

I will test it and after i will retrun you a comment. And for a form ?

Share this post


Link to post
Share on other sites

Posted (edited)

Hi, Dale,

I'm keen to keep this developing; here's my attempt to use Scripkitty's" form as well to do a listing of

1. All links and forms if no frames at a site.

2. Same for all links and forms within frames (needs the different calls) at that site

(please try it in your original site)

Do you think the forms are likely to work in forms with frames?; do you know of a site I could test?

Best, Randall

Edited by randallc

Share this post


Link to post
Share on other sites

Posted

Hi, Dale,

I'm keen to keep this developing; here's my attempt to use Scripkitty's" form as well to do a listing of

1.  All links and forms if no frames at a site.

2. Same for all links and forms  within frames (needs the different calls) at that site

(please try it in your original site)

Do you think the forms are likely to work in forms with frames?; do you know of a site I could test?

Best, Randall

<{POST_SNAPBACK}>

If you use the UDFs that I created here to create an object pointing to a Frame Window, you do not have to special-case documents with frames. I don't think it makes a lot of sense to have a set of funtions for regular documents and another for frames... just check for frames, then get the frame object and use it like a normal IE object.

Regarding forms in frames -- once you have the frame window object there is nothing special about the fact that they happen to be displayed in a frame, so there should be no issue.

Dale

Share this post


Link to post
Share on other sites

Posted

Hi, Dale,

I'm not sure what you mean; you have used 3 different calls for in or out of frames;

clickLink($ObjIE, "forum", 2)

_IE_clickLinkText(_IE_FrameObj($ObjIE, 2), "Our Values")

;_IE_clickLinkIndex(_IE_FrameObj($ObjIE, 2), 2)

Are you saying (assuming I want to click as chosen by a "value" of some kind) that i can simplify the code to

1. List all possible clicks or fields (eg input for user from listview box)

2. Enter or read fields or links as cchosen

whether in frame or not?

What if you wanted to click ot list all fields returnig "Virginia" whether in form or frame?

Thanks, Randall

Share this post


Link to post
Share on other sites

Posted (edited)

I guess I was confused about your question. What I'm saying about frames is that the _IE_FrameObj($_obj, $_f) function can be used to get the window object for a specific frame... use that object in place of the $ObjIE references you see in most of the COM examples here and it works the same.

If you are asking about 'clicking' forms, that is is a different issue and may be what I missed in your question. None of the functions here are designed to do that -- there are better ways to work with forms.

There is a seperate form collection within each document, the form elements for each can be manipulated and the form has a submit method you can call.

The functions in this thread are primarily for <a href= types of links on a page.

Dale

Edited by DaleHohm

Share this post


Link to post
Share on other sites

Posted

I've been trying to figure this out for a long time... finally got it.  This function allows you to specify the text a a link that you want to actvate on a webpage and it will click it for you.

Dale

Note: Requires the post 3.1.1 betas for COM support

$ObjIE = ObjCreate ("InternetExplorer.Application")
With $ObjIE
   .Visible = True
   .Navigate ("http://www.autoitscript.com/")
   
   While .ReadyState <> 4
      Sleep(50)
   WEnd
EndWith

clickLink($ObjIE, "forum", 2)

Exit

Func clickLink($obj, $searchText, $instance = 1)
  ; clickLink( $obj, $serachText [, $instance])
  ; $obj - Object Valiable pointing to an InternetExplorer.Application object
  ; $searchText - the text displayed on the web page for the desired link to click
  ; [$instance] - if the link text occurs more than once, specify which instance you want to click (numbering starts at 1)
   $doc = $obj.document
   $links = $doc.links
   $found = 0
   For $link in $links
      $linkText = $link.outerText
      If $linkText = $searchText Then
         $found = $found + 1
         if ($found = $instance) Then
            $result = $link.click
            ExitLoop
         EndIf
      EndIf
   Next
   
EndFunc  ;==>clickLink

<{POST_SNAPBACK}>

On mine this program does not search for the text of the name of the button, and simply touches all Links on page.

Try instead of clickLink ($ObjIE, "forum", 2)

clickLink ($ObjIE, "lalalalala", 2)

or

clickLink ($ObjIE, "forum", 3)

Thanks.

:)

Share this post


Link to post
Share on other sites

Posted

Sorry, I'm not certain what you are saying. What is written here is primarily for <a href= links, not for graphic buttons. There is an updated set of functions later in the post that 1) fix a bug that caused an erroneous match when there was no link text (like img links) and 2) added the ability to activate a link by index rather than text.

Please try the newer functions and let me know if you still have questions or trouble.

Dale

Share this post


Link to post
Share on other sites

Posted

This one is better.

$ObjIE = ObjCreate ("InternetExplorer.Application")
With $ObjIE
   .Visible = True
   .Navigate ("http://webdesign.about.com/library/weekly/n030600.htm")
  
   While .Busy
	  Sleep(50)
   WEnd
EndWith

;Sleep(2000)
clickLink($ObjIE, "click to open")

Exit

Func clickLink($obj, $searchText, $instance = 1)
 ; clickLink( $obj, $serachText [, $instance])
 ; $obj - Object Valiable pointing to an InternetExplorer.Application object
 ; $searchText - the text displayed on the web page for the desired link to click
 ; [$instance] - if the link text occurs more than once, specify which instance you want to click (numbering starts at 1)
   $doc = $obj.document
   $links = $doc.links
   $found = 0
   For $link in $links
	  $linkText = $link.outerText
	  If StringInStr($linkText, $searchText) Then
		 $found = $found + 1
		 if ($found = $instance) Then
			$result = $link.click
			ExitLoop
		 EndIf
	  EndIf
   Next
  
EndFunc ;==>clickLink

Share this post


Link to post
Share on other sites

Posted

Hi slim,

We're going in circles here!

Did you see my posts on this thread, and the modified scrip by Dale in the thread; to access links in frames and forms in frames; your scrip duplicates his first one only, and therefore is no more widely applicable?....

I am optimistic we might be able to get a decent function which will click on any of the options, no matter what sort of page, including frames and forms, by search criteria.

did you run my script on this thread too?

Best, Randall

Share this post


Link to post
Share on other sites

Posted

OK, I think it's time to start working on some formal UDFs for IE Automation. I've read up on the standards and and starting some work on them. More soon.

Dale

Share this post


Link to post
Share on other sites

Posted

Dale,

Good news; let me know if there's anything I can do...

Look forward to hearing progress.

Best, randall

Share this post


Link to post
Share on other sites

Posted

"If you are asking about 'clicking' forms, that is is a different issue and may be what I missed in your question. None of the functions here are designed to do that -- there are better ways to work with forms."

Is there any documentation / previous discussion on working with forms in a web browser? I tried looking in the forum but came up empty. A better way than our current method of moving the mouse to the right coordinates would be much less work when the data changes...

Thanks,

Phibian

Share this post


Link to post
Share on other sites

Posted

I'll be releasing some functions to do this and many other things shortly... please stand by.

Dale

Share this post


Link to post
Share on other sites

Posted

Sometimes a link requires using ctrl-click to get around a pop-up blocker... I don't know how to do that and my search has come up dry so far.

Don't know if you have found a solution to this or not but couldn't you look in the registry to see if the pop-up blocker is turned on. If it is then just hold control until the next page loads or a set time. I'm sure holding CTRL even on a non popup link won't affect it. Hope it helps

-Aaron

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0