是否可以使用Python开发Web浏览器?

时间:2009-05-18 10:43:59

标签: python browser

用Python开发Web浏览器 - 有可能吗?

11 个答案:

答案 0 :(得分:15)

当然,这是可能的。为什么它与其他语言有什么不同? Python仍然是一种完整而恰当的编程语言,即使它是相当高级的。现在我不确定它会产生出色的性能,这对于浏览器的呈现和JavaScript引擎来说尤其令人满意。尽管如此,你可以在没有任何非常困难的情况下(主要是通常的那些)在Python中创建一个完全成熟的浏览器。

问题是:无论如何,你为什么要这样做,所有的浏览器已经有了巨大的开端?您将从头开始编写代码库,因此在接近Firefox或IE等流行浏览器的功能集之前,您需要查看很多年。

答案 1 :(得分:6)

Grail是一个用Python编写的Web浏览器。

答案 2 :(得分:5)

使用PyQt4,您可以通过将Python与Qt4相结合来编写功能非常强大的浏览器。或者,wxPython使用wxWidgets做同样的事情。

答案 3 :(得分:4)

是的。

使用PyQt4QtWebKit,您可以使用Python制作完整的浏览器。但是,已经有一个。它被称为PyPhantomJS。它完全无头,可通过JavaScript完全控制(如果这就是你要找的东西)。

如果无头不是你的目标,你也可以使用QWebView。

答案 4 :(得分:3)

这是wx python示例代码包中的一个示例:

import  os
import  sys
import  wx
import  wx.html as html
import  wx.lib.wxpTag

#----------------------------------------------------------------------

# This shows how to catch the OnLinkClicked non-event.  (It's a virtual
# method in the C++ code...)
class MyHtmlWindow(html.HtmlWindow):
    def __init__(self, parent, id):
        html.HtmlWindow.__init__(self, parent, id, style=wx.NO_FULL_REPAINT_ON_RESIZE)
        if "gtk2" in wx.PlatformInfo:
            self.SetStandardFonts()

    def OnLinkClicked(self, linkinfo):
        print('OnLinkClicked: %s\n' % linkinfo.GetHref())
        super(MyHtmlWindow, self).OnLinkClicked(linkinfo)

    def OnSetTitle(self, title):
        print('OnSetTitle: %s\n' % title)
        super(MyHtmlWindow, self).OnSetTitle(title)

    def OnCellMouseHover(self, cell, x, y):
        print('OnCellMouseHover: %s, (%d %d)\n' % (cell, x, y))
        super(MyHtmlWindow, self).OnCellMouseHover(cell, x, y)

    def OnCellClicked(self, cell, x, y, evt):
        print('OnCellClicked: %s, (%d %d)\n' % (cell, x, y))
        if isinstance(cell, html.HtmlWordCell):
            sel = html.HtmlSelection()
            print('     %s\n' % cell.ConvertToText(sel))
        super(MyHtmlWindow, self).OnCellClicked(cell, x, y, evt)

    def SelectionToText(self):
        print "selection:"#, cell.SelectionToText(), ":"
        super(MyHtmlWindow, self).SelectionToText()

# This filter doesn't really do anything but show how to use filters
class MyHtmlFilter(html.HtmlFilter):
    def __init__(self, log):
        html.HtmlFilter.__init__(self)

    # This method decides if this filter is able to read the file
    def CanRead(self, fsfile):
        print("CanRead: %s\n" % fsfile.GetMimeType())
        return False

    # If CanRead returns True then this method is called to actually
    # read the file and return the contents.
    def ReadFile(self, fsfile):
        return ""


class TestHtmlPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id, style=wx.NO_FULL_REPAINT_ON_RESIZE)
        self.frame = parent
        self.cwd = os.path.split(sys.argv[0])[0]
        if not self.cwd:
            self.cwd = os.getcwd()
        if parent:
            self.titleBase = parent.GetTitle()
        #html.HtmlWindow_AddFilter(MyHtmlFilter(log))
        self.html = MyHtmlWindow(self, -1)
        self.html.SetRelatedFrame(parent, self.titleBase + " -- %s")
        self.html.SetRelatedStatusBar(0)
        self.printer = html.HtmlEasyPrinting()
        self.box = wx.BoxSizer(wx.VERTICAL)
        self.box.Add(self.html, 1, wx.GROW)
        subbox = wx.BoxSizer(wx.HORIZONTAL)
        btn = wx.Button(self, -1, "Load File")
        self.Bind(wx.EVT_BUTTON, self.OnLoadFile, btn)
        subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
        btn = wx.Button(self, -1, "Load URL")
        self.Bind(wx.EVT_BUTTON, self.OnLoadURL, btn)
        subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
        btn = wx.Button(self, -1, "With Widgets")
        self.Bind(wx.EVT_BUTTON, self.OnWithWidgets, btn)
        subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
        btn = wx.Button(self, -1, "Back")
        self.Bind(wx.EVT_BUTTON, self.OnBack, btn)
        subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
        btn = wx.Button(self, -1, "Forward")
        self.Bind(wx.EVT_BUTTON, self.OnForward, btn)
        subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
        btn = wx.Button(self, -1, "Print")
        self.Bind(wx.EVT_BUTTON, self.OnPrint, btn)
        subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
        btn = wx.Button(self, -1, "View Source")
        self.Bind(wx.EVT_BUTTON, self.OnViewSource, btn)
        subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
        self.box.Add(subbox, 0, wx.GROW)
        self.SetSizer(self.box)
        self.SetAutoLayout(True)
        # A button with this ID is created on the widget test page.
        self.Bind(wx.EVT_BUTTON, self.OnOk, id=wx.ID_OK)
        self.OnShowDefault(None)

    def ShutdownDemo(self):
        # put the frame title back
        if self.frame:
            self.frame.SetTitle(self.titleBase)

    def OnShowDefault(self, event):
        name = os.path.join(self.cwd, 'data/test.htm')
        self.html.LoadPage(name)

    def OnLoadFile(self, event):
        dlg = wx.FileDialog(self, style=wx.OPEN,
                            wildcard='HTML Files|*.htm;*.html', )
        if dlg.ShowModal():
            path = dlg.GetPath()
            self.html.LoadPage(path)
        dlg.Destroy()

    def OnLoadURL(self, event):
        dlg = wx.TextEntryDialog(self, "Enter a URL")
        if dlg.ShowModal():
            url = dlg.GetValue()
            self.html.LoadPage(url)
        dlg.Destroy()

    def OnWithWidgets(self, event):
        os.chdir(self.cwd)
        name = os.path.join(self.cwd, 'data/widgetTest.htm')
        self.html.LoadPage(name)

    def OnOk(self, event):
        print("It works!\n")

    def OnBack(self, event):
        if not self.html.HistoryBack():
            wx.MessageBox("No more items in history!")

    def OnForward(self, event):
        if not self.html.HistoryForward():
            wx.MessageBox("No more items in history!")

    def OnViewSource(self, event):
        import  wx.lib.dialogs
        source = self.html.GetParser().GetSource()
        dlg = wx.lib.dialogs.ScrolledMessageDialog(self, source, 'HTML Source')
        dlg.ShowModal()
        dlg.Destroy()

    def OnPrint(self, event):
        self.printer.GetPrintData().SetPaperId(wx.PAPER_LETTER)
        self.printer.PrintFile(self.html.GetOpenedPage())

overview = """<html><body>
<h2>wx.HtmlWindow</h2>

<p>wx.HtmlWindow is capable of parsing and rendering most
simple HTML tags.

<p>It is not intended to be a high-end HTML browser.  If you're
looking for something like that see the IEHtmlWin class, which
wraps the core MSIE HTML viewer.

</body></html>
"""

app = wx.PySimpleApp()
# create a window/frame, no parent, -1 is default ID
# increase the size of the frame for larger images
frame1 = wx.Frame(None, -1, "A simple web browser", size = (800, 600))
frame1.CreateStatusBar()
# call the derived class
TestHtmlPanel(frame1, -1)
frame1.Show(1)
app.MainLoop()

答案 5 :(得分:2)

详细说明Paul Dixon的答案,使用PyQt会相对容易。从Qt 4.4开始,QtWebKit模块已经可用,为您提供了一个没有任何额外工作的渲染引擎。当然,这可以通过Qt(PyQt)的Python风格来访问。

Here就是它的一些例子!

答案 6 :(得分:1)

是。这是使用GNOME和Python的example

答案 7 :(得分:1)

Grail是用Python编写的Web浏览器的一个例子,但该项目现在已经死了。

答案 8 :(得分:0)

这个问题很难回答。许多使用内置库的脚本语言允许您使用极少的命令连接到主机并下载网页(以原始html格式)。

可以说,这可以称为网络浏览器。但是下载和显示图像呢? JavaScript的?饼干?历史记录,书签,保存密码和其他“标准”Web浏览器功能?

但正如OregonGhost所说; “为什么[它与python]或多或少比任何其他语言更可能?”如果有足够的时间和处理能力,任何图灵完整的机制都可以用任何图灵完整的语言建模,例如python。

您的问题的答案是肯定的。不多也不少。您必须更具体地获取更好的信息,否则您将获得解释如何解释您的问题的答案。就像我的回答一样。

答案 9 :(得分:0)

至少写了一篇,Grail。虽然不再维护,但这是一个有趣的起点。

答案 10 :(得分:0)

fastPATX 是我自己的小型网络浏览器。它具有选项卡式浏览功能和更多功能。用PyQt4,BuzHug和Python编写 对于那些不知道的人,PyQt4和BuzHug是用Python编写的:)