S
S
Seganapa2012-11-12 08:30:55
Python
Seganapa, 2012-11-12 08:30:55

Chromium Embedded Framework (cefpython) automation?

Good day everyone!
There was a need to create a GUI with a built-in browser.
But just embedding a browser is not enough, it still needs to be automated (authorize and press a couple of buttons) ...
First, I started looking towards Selenium, implemented authorization, implemented button presses, but I couldn’t embed a window with a browser in my GUI application. I asked several Selenium specialists, all unanimously said it was impossible.
The second step was customization and use of webkit. Here another problem emerged. If you visit the site (I'm interested in ru.grepolis.com) with a regular browser, a number of GET and POST requests are sent. But if you access this site through webkit, then at a certain stage, requests stop being sent, i.e. it turns out that the site is not loading up... At first I thought there was a problem with Flash, I connected the plugin, tried youtube.com, everything loads fine (it plays videos), but the site I need does not want to load completely... I tried Spynner, but since it was written using webkit, the same story, the site does not fully load ...
And finally, the most suitable IMHO option for me is the use of cefpython. I inserted a browser into my GUI window, loaded the page, everything was fully displayed, in general it works as it should ... But then another question arose: HOW TO AUTOMATED FILLING IN THE FIELDS AND PRESSING THE BUTTONS? By what means can this be done? I contacted the developer, he advised me to use JavaScript. But I don’t understand how to implement it, in Java it’s full 0.
Help someone who has come across how to solve my problem?
Let me give you an example code. He opens Google. How to automate, for example, entering text into the search bar?

# An example of embedding CEF in wxPython application.
#coding:utf-8

import wx
import sys
import time
import cefpython

# TODO: currently we use wx.Timer to imitate message loop, but
# it would probably be better to use wx.CallLater() and wx.lib.pubsub.

class MainFrame(wx.Frame):

  browser = None

  def __init__(self):
    
    wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, title='wxPython example', size=(1000,800))
    self.CreateMenu()
    self.browser = cefpython.CreateBrowser(self.GetHandle(), browserSettings={}, navigateURL="http://google.com")		
    
    self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
    self.Bind(wx.EVT_SIZE, self.OnSize)
    
  def CreateMenu(self):

    filemenu = wx.Menu()
    filemenu.Append(1, "Открыть")
    filemenu.Append(2, "Выход")

    aboutmenu = wx.Menu()
    aboutmenu.Append(1, "CEF Python")

    menubar = wx.MenuBar()
    menubar.Append(filemenu,"&File")
    menubar.Append(aboutmenu, "&About")

    self.SetMenuBar(menubar)

  def OnSetFocus(self, event):

    cefpython.wm_SetFocus(self.GetHandle(), 0, 0, 0)

  def OnSize(self, event):

    cefpython.wm_Size(self.GetHandle(), 0, 0, 0)

class MyApp(wx.App):

  timer = None
  timerID = 1

  def OnInit(self):

    cefpython.Initialize()
    sys.excepthook = cefpython.ExceptHook

    self.timer = wx.Timer(self, self.timerID)
    self.timer.Start(10) # 10ms
    wx.EVT_TIMER(self, self.timerID, self.OnTimer)
    
    frame = MainFrame()
    self.SetTopWindow(frame)
    frame.Show()
    
    return True

  def OnExit(self):

    self.timer.Stop()
    cefpython.Shutdown()

  def OnTimer(self, event):

    cefpython.SingleMessageLoop()

if __name__ == '__main__':
  
  print('wx.version=%s' % wx.version())
  app = MyApp(False)
  app.MainLoop()

Maybe there is some other way to implement my idea ... Please tell me. Second month in a dead end...

Answer the question

In order to leave comments, you need to log in

4 answer(s)
F
faddey0, 2015-03-21
@faddey0

I'm having the same problem myself. Haven't contacted the developer, but apparently the only solution so far is to use JavaScript. The simplest solution for cefpython3 looks something like this:

class MainFrame(wx.Frame):
    # ...

    def OnInit(self):
        # ...
        self.bind_js()
    
    def bind_js(self):
        js_code = """
        // write your js here
        """
        self.browser.SetClientCallback(
            'OnLoadEnd',
            lambda *args, **kwargs: self.execute_js(js_code),
        )
        
    def execute_js(self, code):
        self.browser.GetMailFrame().ExecuteJavascript(code)

Alas, I did not find a way to bind to the end of the page load not using js. Mb anyone give me a hint?

B
bndr, 2012-11-12
@bndr

jQuery is included on the Grepolis website. Accordingly, automating the filling in Javascript will look like this:
$(document).ready(function(){ $('#loginform #name').val('Мой логин'); $('#loginform #password').val('Мой пароль'); $('#loginform').submit(); });

S
Seganapa, 2012-11-12
@Seganapa

bndr how to apply it to my code?

G
goblin2oo8, 2019-02-21
@goblin2oo8

Dude, if you knew how much information I rummaged through on a similar task))
And the answer is simple:
Cling to cefpython - Selenium

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question