12

How can my Python script get the URL of the currently active Google Chrome tab in Windows? This has to be done without interrupting the user, so sending key strokes to copy/paste is not an option.

Christian Davén
  • 16,713
  • 12
  • 64
  • 77
  • Does this answer your question? [Get Chrome tab URL in Python](https://stackoverflow.com/questions/52675506/get-chrome-tab-url-in-python) – skjerns Jan 26 '20 at 14:03

3 Answers3

18

First, you need to download and install pywin32. Import these modules in your script:

import win32gui
import win32con

If Google Chrome is the currently active window, first get the window handle by:

hwnd = win32gui.GetForegroundWindow()

(Otherwise, find the Google Chrome window handle by using win32gui.FindWindow. Windows Detective is handy when finding out class names for windows.)

It seems the only way to get the URL is to get the text in the "omnibox" (address bar). This is usually the tab's URL, but could also be any partial URL or search string that the user is currently typing.

Also, the URL in the omnibox won't include the "http://" prefix unless the user has typed it explicitly (and not yet pressed enter), but it will in fact include "https://" or "ftp://" if those protocols are used.

So, we find the omnibox child window inside the current Chrome window:

omniboxHwnd = win32gui.FindWindowEx(hwnd, 0, 'Chrome_OmniboxView', None)

This will of course break if the Google Chrome team decides to rename their window classes.

And then we get the "window text" of the omnibox, which doesn't seem to work with win32gui.GetWindowText for me. Good thing there's an alternative that does work:

def getWindowText(hwnd):
    buf_size = 1 + win32gui.SendMessage(hwnd, win32con.WM_GETTEXTLENGTH, 0, 0)
    buf = win32gui.PyMakeBuffer(buf_size)
    win32gui.SendMessage(hwnd, win32con.WM_GETTEXT, buf_size, buf)
    return str(buf)

This little function sends the WM_GETTEXT message to the window and returns the window text (in this case, the text in the omnibox).

There you go!

Christian Davén
  • 16,713
  • 12
  • 64
  • 77
  • Could you clear such "tricky" thing: when some "villain-app" (python script, WindowDetective, ..) tries to read any data (hwnd, class, text, smth. else) from "victim-app" (Chrome, IE, "SomeParanoidApp") is it possible that "victim" can feel/see/check that ih has been scanned? – akaRem Feb 21 '13 at 19:04
  • Is this applicable only on Windows platform or this library works across platforms? If no, is there any equivalent library for Mac OS. – Gaurav Parashar Jan 21 '18 at 09:51
  • Any alternatives for Linux systems?? – Amulya Acharya Aug 12 '21 at 01:50
4

Christian's answer did not work for me as internal structure of Chrome changed entirely and you can't really access elements of Chrome window using win32gui anymore.

The only possible way I managed to find was through UI Automation API, which has this python wrapper with some examples of usage

Run this and switch to Chrome window you want to grab address from:

from time import sleep
import uiautomation as automation

if __name__ == '__main__':
    sleep(3)
    control = automation.GetFocusedControl()
    controlList = []
    while control:
        controlList.insert(0, control)
        control = control.GetParentControl()
    if len(controlList) == 1:
        control = controlList[0]
    else:
        control = controlList[1]
    address_control = automation.FindControl(control, lambda c, d: isinstance(c, automation.EditControl) and "Address and search bar" in c.Name)
    print address_control.CurrentValue()
proggeo
  • 609
  • 5
  • 11
  • have you tested when the browser is in full screen mode... The url getting captured.. I am using c# i am not able to get the control – jan_kiran Dec 23 '21 at 04:25
1

I quite new to StackOverFlow so apologies if the comment is out of tone.

After looking at :

  • Selenium,
  • launching chrome://History directly,
  • doing some keyboard emulation : copy/paste with Pywinauto,
  • trying to use SOCK_RAW connections to capture the headers as per the Network tab of the DevTool (this one was very interesting),
  • trying to get text of the omnibus/searchBar window element,
  • closing and reopening chrome to read the history tables, ....

I resulted in copy/pasting the History file itself (\AppData\Local\Google\Chrome\User Data\Default\History) into my application folder when the title of the window (retrieved using the hwnd + win32) is missing from "my" urls table. This can be done even if the sqlite db is locked and does not interfere with the user experience.

Very basic solution that requires : sqlite3, psutil, win32gui. Hope that helps.

JRaph74
  • 11
  • 2