如何在Windows中获取当前Google Chrome标签页的URL?

12

如何在Windows中,让我的Python脚本获取当前活动的Google Chrome选项卡的URL?必须在不打扰用户的情况下完成,因此发送按键以复制/粘贴不是一个选项。


这个回答解决了您的问题吗?在Python中获取Chrome标签页URL - skjerns
3个回答

18

首先,您需要下载并安装pywin32。在您的脚本中导入这些模块:

import win32gui
import win32con
如果 Google Chrome 是当前活动窗口,则首先通过以下方式获取窗口句柄:
hwnd = win32gui.GetForegroundWindow()

(否则,通过使用 win32gui.FindWindow 找到 Google Chrome 窗口的句柄。在查找窗口类名时,Windows Detective 是很方便的工具。)

似乎唯一的方法是获取"omnibox"(地址栏)中的文本,这通常是选项卡的URL,但也可能是用户当前正在输入的任何部分URL或搜索字符串。

此外,除非用户已经明确输入了 "http://" 前缀(但尚未按 Enter 键),否则 omnibox 中的 URL 不会包含该前缀,但如果使用了这些协议,则实际上将包括 "https://" 或 "ftp://"。

因此,我们在当前的 Chrome 窗口中找到 omnibox 子窗口:

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

如果Google Chrome团队决定重命名窗口类,这当然会导致问题。

然后我们获取地址栏的“窗口文本”,但似乎对我而言无法使用win32gui.GetWindowText。好在有另一种可行的替代方法:

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)

这个小函数发送WM_GETTEXT消息到窗口并返回窗口文本(在这种情况下,是地址栏中的文本)。

就是这样!


你能否澄清一下这个“棘手”的问题:当某些“恶意应用程序”(如Python脚本、WindowDetective等)尝试从“受害应用程序”(Chrome、IE、“SomeParanoidApp”)读取任何数据(hwnd、class、text、其他内容)时,是否可能“受害者”会感觉到/看到/检查到自己已经被扫描了? - akaRem
这个库只适用于 Windows 平台吗?还是可以跨平台使用?如果不行,有没有 Mac OS 的等效库可用? - Gaurav Parashar
Linux系统有什么替代方案吗? - Amulya Acharya

4

由于Chrome的内部结构已经完全改变,无法再使用win32gui来访问Chrome窗口元素,因此Christian的答案对我没有用。

我找到的唯一可能途径是通过UI Automation API,可以使用这个Python封装库并参考其中的一些示例。

运行代码后,切换到你想要获取地址的Chrome窗口:

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()

你测试过浏览器全屏模式下的情况吗?URL是否被捕获?我正在使用C#,但无法获取控制。 - jan_kiran

1

我是StackOverFlow的新手,如果评论有些不恰当,请见谅。

在研究了以下内容后:

  • Selenium,
  • 直接启动chrome://History,
  • 使用Pywinauto进行键盘模拟:复制/粘贴,
  • 尝试使用SOCK_RAW连接来捕获DevTool的Network选项卡中的标头(这个非常有趣),
  • 尝试获取omnibus/searchBar窗口元素的文本,
  • 关闭并重新打开Chrome以读取历史记录表, ....

我最终选择将历史记录文件(\AppData\Local\Google\Chrome\User Data\Default\History)复制/粘贴到我的应用程序文件夹中,当窗口标题(使用hwnd + win32检索)在“我的”URL表中缺失时。 即使sqlite数据库被锁定,也可以执行此操作,而且不会影响用户体验。

这是一种非常基本的解决方案,需要使用:sqlite3、psutil、win32gui。

希望这能对您有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接