Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
GetHtmlElement
#1
I want to get an HTML element from an adjacent element without waiting for IE to process javascript ads. I'm using HtmlDoc.GetHtmlElement to find the reference element, but it only works if I already know the index number. How can I search an element based on the contents of the tag? Kind of like doing
Macro Yahoo Key Statistics2
Trigger AF8     Help - how to add the trigger to the macro
Code:
Copy      Help
Htm el1=htm("TD" "Market Cap (intraday)*:" "" win(" Internet Explorer" "IEFrame") 0 0 0x21 5 +3)
but without a browser

Here's my sample code.
Macro Test HTML
Code:
Copy      Help
// Download the raw HTML to text
str url = "http://finance.yahoo.com/q/ks?s=MSFT"
str s
IntGetFile(url s)

// strip out the javascript
s.replacerx("[\r\n]+")
s.replacerx("<script.*>.*</script>" "" RX_UNGREEDY)

// Locate the "Market Cap" element
HtmlDoc hd.InitFromText(s)
MSHTML.IHTMLElement el=hd.GetHtmlElement("td" 21)
;MSHTML.IHTMLElement el=hd.GetHtmlElement("td" "Market Cap (intraday)")
if(!el) end "element not found"
out el.innerText
out el.sourceIndex
int MCInd = el.sourceIndex

// Get the Market Cap number (3rd next element)
MSHTML.IHTMLElement el2=hd.GetHtmlElement("" MCInd+3)
if(!el2) end "element not found"
out el2.innerText
#2
Member function HtmlDoc.FindHtmlElement
Code:
Copy      Help
;/
function'MSHTML.IHTMLElement $text [flags] [$tag] [$containerTag] [VARIANT'containerNameOrIndex] [&index] ;;flags: 0 exact, 1 contains, 2 wildcard, 3 regex, 4 in HTML

;Finds HTML element containing certain text.
;Error if something fails, eg container not found.
;Returns 0 if element not found.

;text - element's text or HTML (flag 4). It can be exact text, or part (flag 1), or wildcard expression (flag 2) or regular expression (flag 3). Must match case (regex has option (?i) for case insensitive).
;tag - if used, searches only elements of this type. Example: "td".
;containerTag, containerNameOrIndex - if used, searches only elements within this element. It for example can be a table.
;index - if used, receives element index. If tag used, in collection of tag elements, else in all elements.


ARRAY(MSHTML.IHTMLElement) a
this.GetHtmlElements(a tag containerTag containerNameOrIndex)
int i; str s
for i 0 a.len
,MSHTML.IHTMLElement& el=a[i]
,if(flags&4) s=el.outerHTML; else s=el.innerText
,sel flags&3
,,case 0 if(s=text) break
,,case 1 if(find(s text)>=0) break
,,case 2 if(matchw(s text)) break
,,case 3 if(findrx(s text)>=0) break
if(i=a.len) ret
if(&index) index=i
;ret el ;;exception
;ret a[i] ;;same
MSHTML.IHTMLElement el2=el
ret el2
err+ end _error

now replace GetHtmlElement line with
Macro Test HTML
Code:
Copy      Help
MSHTML.IHTMLElement el=hd.FindHtmlElement("Market Cap (intraday)*" 2 "td")
#3
Thanks Gintaras. I was going to write a function, but didn't know to make it a member function. I made a modification to include the navigation parameter.
Member function HtmlDoc.FindHtmlElement
Code:
Copy      Help
function'MSHTML.IHTMLElement $text [flags] [$tag] [$containerTag] [VARIANT'containerNameOrIndex] [navig] [&index]
;;flags: 0 exact, 1 contains, 2 wildcard, 3 regex, 4 in HTML
Then, at the end,
Member function HtmlDoc.FindHtmlElement
Code:
Copy      Help
if (navig)
,el=this.GetHtmlElement("" el.sourceIndex+navig)
MSHTML.IHTMLElement el2=el
ret el2
err+ end _error
and to call it:
Macro Test HTML
Code:
Copy      Help
MSHTML.IHTMLElement el=hd.FindHtmlElement("Market Cap (intraday)*:" 2 "td" "" 0 +3)
That works. Thanks so much!


Forum Jump:


Users browsing this thread: 1 Guest(s)