基于cefpython3的浏览器

有些网站兼容性较低,不支持新版浏览器,比如这一段:

t.addEventListener("change", function(t) {
                        var o = t.path[0].files[0];
                        if (!/(image\/png)|(image\/jp(e?)g)|(image\/gif)/.test(o.type))
                            return n.publish("show_tips", "请选择图片类型"),
                            !1;
                        e.file_type = o.type;
                        var i = new FileReader;
                        i.readAsDataURL(o),
                        i.onload = function() {
                            e.cropper.replace(i.result)
                        }
                    }

这个例子就不兼容较新版的浏览器(上传图片会失败)。我们可以使用cefpython3,借助它版本较旧的特点。

我基于一个开源的浏览器代码(博客太久找不到了),制作了一个简单的标签页浏览器。


from cefpython3 import cefpython as cef
import tkinter as tk
import platform
import urllib.request
import requests
def pd(text):
    try:
        a=requests.get('https://openphish.com/feed.txt')
        t=a.text.split('\n')
        if text in t:
            return 1
        if text[:text.replace('//','||').index('/')+1] in t:
            return 1
        if text[:text.replace('//','||').index('/')] in t:
            return 1

        if not '/' in text:
            text=text+'/'
        if text in t:
            return 1
        if text[:text.replace('//','||').index('/')+1] in t:
            return 1
        if text[:text.replace('//','||').index('/')] in t:
            return 1
        
        return 0
    except:
        return 0

WINDOWS = (platform.system() == "Windows")
LINUX = (platform.system() == "Linux")
MAC = (platform.system() == "Darwin")
# Fix for PyCharm hints warnings
WindowUtils = cef.WindowUtils()

cef.Initialize() #init
class Browser(tk.Frame):
    class LoadHandler(object):
        def __init__(self, browser):
            self.browser = browser
        def OnBeforePopup(self,target_url,**a):
            user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
            res = self.browser.NewWindow(target_url)
            if res == "break":
                return True
    class FocusHandler(object):
        "From cefpython3.example.tkinter_"
        def __init__(self, browser_frame):
            self.browser_frame = browser_frame
        def OnSetFocus(self, source, **_):
            return False
        def OnGotFocus(self, **_):
            """Fix CEF focus issues (#255). Call browser frame's focus_set
               to get rid of type cursor in url entry widget."""
            self.browser_frame.focus_set()
    def __init__(self,*a,url="",**b):
        super().__init__(*a,**b)
        #create browser
        window_info = cef.WindowInfo()
        rect = [0, 0, self.winfo_width(), self.winfo_height()]
        window_info.SetAsChild(self.get_window_handle(), rect)
        if not url:
            url="https://www.baidu.com/"
        self.browser = cef.CreateBrowserSync(window_info,url=url)
        assert self.browser
        self.browser.SetClientHandler(self.LoadHandler(self))
        self.browser.SetClientHandler(self.FocusHandler(self))
        #fit frame
        self.bind("", self._configure)
    def _configure(self, event):
        res=self.event_generate("<>")
        if res=="break":
            return
        width = event.width
        height = event.height
        if WINDOWS:
            WindowUtils.OnSize(self.winfo_id(), 0, 0, 0)
        elif LINUX:
            self.browser.SetBounds(0, 0, width, height)
        self.browser.NotifyMoveOrResizeStarted()
    def NewWindow(self,url):
        self.load(url)
        return "break"
    def loadurl(self,url):
        self.browser.StopLoad()
        self.browser.LoadUrl(url)
    def geturl(self):
        return self.browser.GetUrl()
    def reload(self):
        self.browser.Reload()
    def get_window_handle(self):
        "From cef"
        if self.winfo_id() > 0:
            return self.winfo_id()
        elif MAC:
            # On Mac window id is an invalid negative value (Issue #308).
            # This is kind of a dirty hack to get window handle using
            # PyObjC package. If you change structure of windows then you
            # need to do modifications here as well.
            # noinspection PyUnresolvedReferences
            from AppKit import NSApp
            # noinspection PyUnresolvedReferences
            import objc
            # Sometimes there is more than one window, when application
            # didn't close cleanly last time Python displays an NSAlert
            # window asking whether to Reopen that window.
            # noinspection PyUnresolvedReferences
            return objc.pyobjc_id(NSApp.windows()[-1].contentView())
        else:
            raise Exception("Couldn't obtain window handle")     
def maincefloop(n=200):
    cef.MessageLoopWork()
    tk._default_root.after(n, maincefloop,n)
def bye():
    cef.Shutdown()
def test():
    def makenew(url):
        b = Browser(note,url=url)
        note.add(b,text=str(note.index("end"))+': '+url.replace("https://","").replace("http://","").replace("blob://","")[:20])
        note.select(note.index("end")-1)
        b.NewWindow=lambda url:makenew(url) or "break"
    def rm():
        import tkinter.simpledialog
        result = tk.simpledialog.askstring(title = '获取信息',prompt='请输入标签页编号:',initialvalue = str(note.index("end")-1))
        url=int(result)
        note.hide(url)
    from tkinter import ttk
    root = tk.Tk()
    note = ttk.Notebook()
    note.pack(expand=1,fill="both")
    makenew('https://www.baidu.com/')
    
    root.title("cefweb.Browser")
    root.geometry("800x600")
    maincefloop()
    def qq(url):
        # Python判断网站是否可以访问
        
        try:
            status = urllib.request.urlopen(url).code
            return True
        except Exception as err:
            return False
    def ntb():
        import tkinter.simpledialog
        result = tk.simpledialog.askstring(title = '获取信息',prompt='请输入网址:',initialvalue = 'https://www.baidu.com/')
        if result!=None:
            if not pd(result):
                if qq(result):
                    makenew(result)
                else:
                    makenew('https://www.baidu.com/s?wd='+result)
    root2 = tk.Tk()
    root2.title('用户命令')
    
    root2.geometry("250x70")
    bu=tk.Button(root2,text='新建标签页',command=ntb)
    bu.pack()
    bu=tk.Button(root2,text='删除标签页',command=rm)
    bu.pack()

    root.mainloop()
    bye()

if __name__ == "__main__":
    test()


 含有基本的功能,但是不支持cookie保存,可以自己加上。

你可能感兴趣的:(前端,javascript,python)