在這篇教程中,我們會用 Python 的 PyQt 框架編寫一個簡單的 web 瀏覽器。關於 PyQt ,你可能已經有所耳聞了,它是 Qt 框架下的一系列 Python 組件,而 Qt(發音類似“cute”)是用來開發 GUI 的 C++ 框架。嚴格來講, Qt 也可用於開發不帶圖形界面的程序,但是開發用戶界面應該是 Qt 框架最為廣泛的應用了。Qt 的主要優勢是可以開發跨平臺的圖形界面程序,基於 Qt 的應用能夠藉助於各平臺的原生性在不同類的設備上運行,而無須修改任何代碼庫。
本文福利:私信回覆【PDF】可獲取Python電子書一套Qt 附帶了 webkit 的接口,你可以直接使用 PyQt 來開發一個基於 webkit 的瀏覽器。
我們本次教程所開發的瀏覽器可以完成如下功能:
- 加載用戶輸入的url
- 顯示在渲染頁面過程中發起的所有請求
- 允許用戶在頁面中執行自定義的 JavaScript 腳本
牛刀小試
讓我們從最簡單的 PyQt 的 Webkit 用例開始吧:輸入 url,打開窗口並在窗口中加載頁面。
這個例子十分短小,連 import 語句和空行在內也只有 13 行代碼。
當你通過命令行將 url 傳給腳本時,程序會加載 url 並且在窗口中顯示加載完成的頁面。
現在,看似你已經有一個“命令行瀏覽器”啦!至少比 python 的 requests 模塊強多了,甚至比 Lynx 還略高一籌,因為我們的瀏覽器還可以加載 JavaScript 腳本呢。但是目前為止還沒有跟 Lynx 拉開差距,因為在啟用瀏覽器的時候只能通過命令行傳入 url。那麼,必然需要通過某種方式把需要加載的 url 傳入瀏覽器。沒錯,就是地址欄!
添加地址欄
其實地址欄的實現非常簡單,我們只需要在窗口頂端加一個輸入框就夠了。用戶在文本框中輸入 url 之後,瀏覽器就會加載這個地址。下面,我們將用到 QLineEdit 控件來實現輸入框。鑑於我們的瀏覽器現在有地址欄和瀏覽器顯示框兩部分,因此還要給我們的應用增加一個網格佈局。
到這裡,我們已經有一個瀏覽器的雛形啦!看上去和當年的 Google Chrome 還有幾分相像呢,畢竟兩者採用了相同的渲染引擎。現在,你可以在輸入框中輸入 url ,程序便會將地址傳入瀏覽器,接著渲染出所有的 HTML 頁面和 JavaScript 腳本並展示出來。
添加開發工具
一個瀏覽器最有趣也最重要的部分是什麼?當然是各種各樣的開發工具了!一個沒有開發者控制檯的瀏覽器怎麼能算是瀏覽器呢?所以,我們的 Python 瀏覽器當然也要有一些開發者工具才行。
現在,我們就來添加一些類似於 Chrome 的開發者工具中 “Network” 標籤的功能吧!這個功能就是簡單地追蹤瀏覽器引擎在加載頁面的時候所執行的所有請求。在瀏覽器主頁面的下方,我們將通過一個表來顯示這些請求。簡單起見,我們只會記錄登錄的 url、返回的狀態碼和響應的內容類型。
首先我們要通過 QTableWidget 組件創建一個表格,表頭包括需要存儲的字段名稱,表格可以根據每次新插入的記錄來自動調整大小。
想要追蹤所有請求的話,我們還需要對 PyQt 的內部構件有更深入的瞭解。瞭解到,Qt 提供了一個 NetworkAccessManager類作為 API 接口,通過調用它可以監控應用加載頁面時所執行的請求。我們需要自己編寫一個繼承自 NetworkAccessManager 的子類,添加必要的事件監聽器,然後使用我們自己編寫的 manager 來通知 webkit 視圖執行相應的請求。
首先我們需要以 NetworkAccessManager 為基類創建我們自己的網絡訪問管理器。
在這裡需要提醒大家的是, Qt 的某些實現並不像想象中那麼簡單明瞭,比如說從響應中獲取狀態碼就十分繁瑣。首先,你得把請求對象的類屬性作為參數傳入 response 的方法 .attribute() 中,.attribute() 方法的返回值是 QVariant 類型而非 int 類型。接著,需要調用內置函數 .toInt() 將其轉換成一個包含兩個元素的元組,最終得到響應的狀態碼。
現在,我們終於有了一個記錄請求的表和一個監控網絡的 manager,接下來只要把他們聚攏起來就可以了。
現在,運行瀏覽器程序,在地址欄鍵入 url,就可以看到在主頁面下方的記錄表中記錄下的所有請求。
如果你有興趣的話,還可以為瀏覽器添加很多新的功能:
- 通過content-type添加篩選功能
- 添加記錄表的排序功能
- 添加計時器
- 高亮顯示出錯的請求(比如說把錯誤信息置為紅色)
- 顯示出更為具體的請求內容,比如說完整的頭信息、響應內容、請求方法等。
- 增加一個重複發送請求並加載出來的選項。比如說用戶可以點擊在記錄表中的請求來重試請求。
其實還有太多的功能可以繼續完善和改進,你可以一一嘗試一下,這會是一個非常有趣而且收穫良多的學習過程。但是如果想把這些功能都說完,估計都能寫一本書了。所以限於篇幅,本文就不一一介紹了,感興趣的朋友可以參考其他書籍和網上教程。
增加解析自定義 JavaScript 腳本的功能
我們終於迎來最後一個功能了!就是解析在頁面中包含的 JavaScript 腳本。
基於我們之前已經打下的基礎,要完成這個功能非常簡單。我們只需要在添加一個 QLineEdit 組件,把它和頁面聯繫起來,然後調用 evaulateJavaScript 方法就可以了。
下面是這個功能的示例。看,我們的開發者工具已經整裝待發了!
現在唯一缺少的就是在頁面中不能執行 Python 腳本。你可以開發自己的瀏覽器,提供對 JavaScript 和 Python 的支持,這樣其他開發者就可以針對你的瀏覽器開發應用了。
後退、前進和其他頁面操作
我們在前面已經使用了 QWebPage 對象來開發瀏覽器,當然作為一個合格的瀏覽器,我們也需要為終端用戶提供一些重要功能。Qt 的網頁對象支持很多不同操作,我們可以把它們全都添加到瀏覽器中。
現在我們可以先嚐試著添加“後退”、“前進”和“刷新”這幾個操作。你可以在界面上添加這些操作按鈕,簡單起見,這裡只加一個文本框來執行這些動作。
和之前一樣,我們要創建一個 ActionInputBox 的實例,把參數傳入頁面對象並把輸入框對象添加到頁面中。
- Graphical User Interface,圖形用戶界面,又稱圖形用戶接口,是指採用圖形方式顯示的計算機操作用戶界面。
- WebKit是一個開源的瀏覽器引擎,與之相對應的引擎有 Gecko(Mozilla Firefox 等使用)和 Trident(也稱 MSHTML ,IE 使用)。
是不是很簡單!
閱讀更多 虎瘦oo雄心在 的文章
關鍵字: Qt 瀏覽器 JavaScript