Save opened website in html file Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
jonny_player
Posts: 15
Joined: 04 Jun 2021, 08:03

Save opened website in html file

05 Jun 2021, 11:19

Hello everybody,

I would like to save the website currently open in the browser in an html file.
It is a website that always has the same link, no matter how you navigate.
That's why "URLDownloadToFile" doesn't work.

Only Internet Explorer and Microsoft Edge are available on this PC.

Thank you for your help!
teadrinker
Posts: 4373
Joined: 29 Mar 2015, 09:41
Contact:

Re: Save opened website in html file  Topic is solved

05 Jun 2021, 19:57

Hi
For IE:

Code: Select all

$F1::
   if !IE := WBGet()
      throw "Failed to get WebBrowser object from IE"
   FileOpen(A_ScriptDir . "\page.html", "w", "UTF-8").Write( IE.document.documentElement.outerHTML )
   MsgBox, HTML saved
   Return

WBGet(WinTitle := "ahk_class IEFrame", Svr# := 1)
{
   static msg := DllCall("RegisterWindowMessage", Str, "WM_HTML_GETOBJECT")
        , IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}"
        , IID_IHTMLDocument2 := "{332C4425-26CB-11D0-B483-00C04FD90119}"
        , VT_DISPATCH := 9, F_OWNVALUE := 1
        
   SendMessage, msg, 0, 0, Internet Explorer_Server%Svr#%, %WinTitle%
   lResult := ErrorLevel
   if (lResult = "FAIL")
      return
   
   VarSetCapacity(GUID, 16, 0)
   DllCall("ole32\CLSIDFromString", WStr, IID_IHTMLDocument2, Ptr, &GUID)
   DllCall("oleacc\ObjectFromLresult", Ptr, lResult, Ptr, &GUID, Ptr, 0, PtrP, pdoc)
   oWb := ComObject(VT_DISPATCH, ComObjQuery(pdoc, IID_IWebBrowserApp, IID_IWebBrowserApp), F_OWNVALUE)
   ObjRelease(pdoc)
   return oWb
}
For MsEdge a little harder:

Code: Select all

SetBatchLines, -1

$F1::
   tempClip := ClipboardAll
   Clipboard := ""
   RunJsFromChromeAddressBar(GetJs(), "msedge.exe")
   ClipWait, 2
   err := ErrorLevel
   html := Clipboard
   Clipboard := tempClip
   if err
      MsgBox, Failed to get html
   else {
      FileOpen(A_ScriptDir . "\page.html", "w", "UTF-8").Write(html)
      MsgBox, HTML saved
   }
   Return
   
GetJs() {
   js =
   (
      ((textToCopy) => {
         if (window.location.protocol === 'https:') {
            document.documentElement.focus();
            const timer = setInterval(() => {
               if (document.hasFocus()) {
                  clearInterval(timer);
                  navigator.clipboard.writeText(textToCopy);
               }
            }, 10);
         }
         else {
            const textArea = document.createElement('textarea');
            textArea.value = textToCopy;
            textArea.wrap = 'off';
            textArea.rows = 100000;
            textArea.style.position = 'fixed';
            document.documentElement.appendChild(textArea);
            textArea.focus();
            textArea.select();
            document.execCommand('copy');
            textArea.parentNode.removeChild(textArea);
         }
      })(document.documentElement.outerHTML);
   )
   Return js
}
   
RunJsFromChromeAddressBar(js, exe := "chrome.exe") {
   static WM_GETOBJECT := 0x3D
        , ROLE_SYSTEM_TEXT := 0x2A
        , STATE_SYSTEM_FOCUSABLE := 0x100000
        , SELFLAG_TAKEFOCUS := 0x1
        , AccAddrBar
   if !AccAddrBar {
      window := "ahk_class Chrome_WidgetWin_1 ahk_exe " . exe
      SendMessage, WM_GETOBJECT, 0, 1, Chrome_RenderWidgetHostHWND1, % window
      AccChrome := AccObjectFromWindow( WinExist(window) )
      AccAddrBar := SearchElement(AccChrome, {Role: ROLE_SYSTEM_TEXT, State: STATE_SYSTEM_FOCUSABLE})
   }
   AccAddrBar.accValue(0) := "javascript:" . js
   AccAddrBar.accSelect(SELFLAG_TAKEFOCUS, 0)
   ControlSend,, {Enter}, % window, Chrome Legacy Window
}

SearchElement(parentElement, params)
{
   found := true
   for k, v in params {
      try {
         if (k = "ChildCount")
            (parentElement.accChildCount != v && found := false)
         else if (k = "State")
            (!(parentElement.accState(0) & v) && found := false)
         else
            (parentElement["acc" . k](0) != v && found := false)
      }
      catch 
         found := false
   } until !found
   if found
      Return parentElement
   
   for k, v in AccChildren(parentElement)
      if obj := SearchElement(v, params)
         Return obj
}

AccObjectFromWindow(hWnd, idObject = 0) {
   static IID_IDispatch   := "{00020400-0000-0000-C000-000000000046}"
        , IID_IAccessible := "{618736E0-3C3D-11CF-810C-00AA00389B71}"
        , OBJID_NATIVEOM  := 0xFFFFFFF0, VT_DISPATCH := 9, F_OWNVALUE := 1
        , h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
        
   VarSetCapacity(IID, 16), idObject &= 0xFFFFFFFF
   DllCall("ole32\CLSIDFromString", "Str", idObject = OBJID_NATIVEOM ? IID_IDispatch : IID_IAccessible, "Ptr", &IID)
   if DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject, "Ptr", &IID, "PtrP", pAcc) = 0
      Return ComObject(VT_DISPATCH, pAcc, F_OWNVALUE)
}

AccChildren(Acc) {
   static VT_DISPATCH := 9
   Loop 1  {
      if ComObjType(Acc, "Name") != "IAccessible"  {
         error := "Invalid IAccessible Object"
         break
      }
      try cChildren := Acc.accChildCount
      catch
         Return ""
      Children := []
      VarSetCapacity(varChildren, cChildren*(8 + A_PtrSize*2), 0)
      res := DllCall("oleacc\AccessibleChildren", "Ptr", ComObjValue(Acc), "Int", 0
                                                , "Int", cChildren, "Ptr", &varChildren, "IntP", cChildren)
      if (res != 0) {
         error := "AccessibleChildren DllCall Failed"
         break
      }
      Loop % cChildren  {
         i := (A_Index - 1)*(A_PtrSize*2 + 8)
         child := NumGet(varChildren, i + 8)
         Children.Push( (b := NumGet(varChildren, i) = VT_DISPATCH) ? AccQuery(child) : child )
         ( b && ObjRelease(child) )
      }
   }
   if error
      ErrorLevel := error
   else
      Return Children.MaxIndex() ? Children : ""
}

AccQuery(Acc) {
   static IAccessible := "{618736e0-3c3d-11cf-810c-00aa00389b71}", VT_DISPATCH := 9, F_OWNVALUE := 1
   try Return ComObject(VT_DISPATCH, ComObjQuery(Acc, IAccessible), F_OWNVALUE)
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Rohwedder and 233 guests