Giter Site home page Giter Site logo

Comments (1)

Lua12138 avatar Lua12138 commented on June 8, 2024

I used a less elegant implementation here. Please let me know if there is a better way later.

example.go

func examples(){
  // Omit the content of the creation context.
        ctx, cancel := .......
	chromedp.ListenTarget(ctx, func(ev interface{}) {
		switch ev := ev.(type) {
		case *runtime.EventExecutionContextCreated:
			data := EventExecutionContextAuxData{}
			json.Unmarshal(ev.Context.AuxData, &data)
			if data.FrameId != "" {
				GlobalExecutionContextPool.Push(data.FrameId, ev.Context.UniqueID)
			}
		case *runtime.EventExecutionContextDestroyed:
			GlobalExecutionContextPool.RemoveByUniqueId(ev.ExecutionContextUniqueID)
		case *page.EventFrameNavigated:
			// This is my method for executing JavaScript after the frame is navigated, and matching UniqueID through frameId.
			go onTargetNavigated(ev, ctx)
	})
}

func onTargetNavigated(ev *page.EventFrameNavigated, ctx context.Context){
	if strings.HasPrefix(ev.Frame.URL, "http") {
		var err error
		if ev.Frame.ParentID == "" {
			// Parent Page/Non-iframe
		} else {
			uniqueId := ""
			deadline := time.Now().Add(5 * time.Second)
			for uniqueId == "" {
				time.Sleep(10 * time.Millisecond)
				uniqueId = GlobalExecutionContextPool.Find(ev.Frame.ID.String())
				if time.Now().UnixMilli() > deadline.UnixMilli() {
					break
				}
			}

			if uniqueId == "" {
				log.Println("cannot match frame execution context")
				return
			}
			err = chromedp.Run(
				ctx,
				chromedp.EvaluateAsDevTools(
					"alert('current page is ' + location.href)", // this is the script
					nil,
					func(ep *runtime.EvaluateParams) *runtime.EvaluateParams {
						return ep.WithUniqueContextID(uniqueId)
					},
				),
			)
		}
	}
}

type ExecutionContextPool struct {
	pool   map[string]string
	locker sync.RWMutex
}

var GlobalExecutionContextPool ExecutionContextPool = ExecutionContextPool{
	pool: map[string]string{},
}

func (s *ExecutionContextPool) Push(frameId string, uniqueId string) {
	log.Println("ExecutionContextPool.Push:", frameId, uniqueId)
	// s.pool.Store(frameId, uniqueId)
	s.locker.Lock()
	defer s.locker.Unlock()
	s.pool[frameId] = uniqueId
}
func (s *ExecutionContextPool) Find(frameId string) string {
	s.locker.RLock()
	defer s.locker.RUnlock()
	if val, ok := s.pool[frameId]; ok {
		return val
	}
	return ""
}
func (s *ExecutionContextPool) RemoveByFrameId(frameId string) {
	s.locker.Lock()
	defer s.locker.Unlock()
	delete(s.pool, frameId)
}
func (s *ExecutionContextPool) RemoveByUniqueId(uniqueId string) {
	s.locker.Lock()
	defer s.locker.Unlock()
	for k, v := range s.pool {
		if v == uniqueId {
			log.Println("ExecutionContextPool.RemoveByUniqueId", k, v)
			delete(s.pool, k)
			return
		}
	}
}

from chromedp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.