如何使用golang knq / chromedp检查页面中是否存在元素

时间:2017-09-27 02:00:21

标签: go web web-testing

我正在使用[chromedp]创建一个应用[1]

如何检查页面中是否存在元素?

我尝试使用cdp.WaitVisible(),但它没有给我我想要的东西。

我需要这个,所以如果应用程序会做一件事,我可以做出决定。

对于这个例子,假设我需要知道搜索输入是否存在

我该怎么做?

[1]:https://github.com/knq/chromedp

  package main

import (
    "context"
    "fmt"
    "io/ioutil"
    "log"
    "time"

    cdp "github.com/knq/chromedp"
    cdptypes "github.com/knq/chromedp/cdp"
)

func main() {
    var err error

    // create context
    ctxt, cancel := context.WithCancel(context.Background())
    defer cancel()

    // create chrome instance
    c, err := cdp.New(ctxt, cdp.WithLog(log.Printf))
    if err != nil {
        log.Fatal(err)
    }

    // run task list
    var site, res string
    err = c.Run(ctxt, googleSearch("site:brank.as", "Easy Money Management", &site, &res))
    if err != nil {
        log.Fatal(err)
    }

    // shutdown chrome
    err = c.Shutdown(ctxt)
    if err != nil {
        log.Fatal(err)
    }

    // wait for chrome to finish
    err = c.Wait()
    if err != nil {
        log.Fatal(err)
    }

    log.Printf("saved screenshot of #testimonials from search result listing `%s` (%s)", res, site)
}

func googleSearch(q, text string, site, res *string) cdp.Tasks {
    var buf []byte
    sel := fmt.Sprintf(`//a[text()[contains(., '%s')]]`, text)
    return cdp.Tasks{
        cdp.Navigate(`https://www.google.com`),
        cdp.Sleep(2 * time.Second),
        cdp.WaitVisible(`#hplogo`, cdp.ByID),
        cdp.SendKeys(`#lst-ib`, q+"\n", cdp.ByID),
        cdp.WaitVisible(`#res`, cdp.ByID),
        cdp.Text(sel, res),
        cdp.Click(sel),
        cdp.Sleep(2 * time.Second),
        cdp.WaitVisible(`#footer`, cdp.ByQuery),
        cdp.WaitNotVisible(`div.v-middle > div.la-ball-clip-rotate`, cdp.ByQuery),
        cdp.Location(site),
        cdp.Screenshot(`#testimonials`, &buf, cdp.ByID),
        cdp.ActionFunc(func(context.Context, cdptypes.Handler) error {
            return ioutil.WriteFile("testimonials.png", buf, 0644)
        }),
    }
}

2 个答案:

答案 0 :(得分:2)

这是我的答案。 该网页为www.google.co.in。使用的元素是lst-ib,页面上显示文本框。

  1. 浏览页面。

  2. 等到元素可见。

  3. 读取元素的值。这是第一次加载页面,因此显然值为""

  4. 假设您已通过在文本框中键入来修改元素的值。现在,如果我们尝试读取相同元素lst-ib的值,那么我们应该获取更新的值。

  5. 我的代码如下,

    package main
    
    import (
        "context"
        "log"
    
        cdp "github.com/knq/chromedp"
    )
    
    func main() {
        var err error
    
        // create context
        ctxt, cancel := context.WithCancel(context.Background())
        defer cancel()
    
        // create chrome instance
        c, err := cdp.New(ctxt)
        if err != nil {
            log.Fatal(err)
        }
    
        // run task list
        var res, value, newValue string
        err = c.Run(ctxt, text(&res, &value, &newValue))
        if err != nil {
            log.Fatal(err)
        }
    
        // shutdown chrome
        err = c.Shutdown(ctxt)
        if err != nil {
            log.Fatal(err)
        }
    
        // wait for chrome to finish
        err = c.Wait()
        if err != nil {
            log.Fatal(err)
        }
    
        if len(value) > 1 {
            log.Println("Search Input is present.")
        } else {
            log.Println("Search Input is NOT present.")
        }
    
        log.Println("New updated value: ", newValue);   
    
    }
    
    func text(res, value, newValue *string) cdp.Tasks {
        return cdp.Tasks{
            cdp.Navigate(`https://www.google.co.in`),
            cdp.WaitVisible(`lst-ib`, cdp.ByID),
            cdp.EvaluateAsDevTools("document.getElementById('lst-ib').value", value),
            cdp.EvaluateAsDevTools("document.getElementById('lst-ib').value='Hello';document.getElementById('lst-ib').value", newValue),
        }
    }
    

    使用go run <FileName>.go

    运行代码

    我正在获得预期的输出:

    $ go run main.go 
    2017/09/28 20:05:20 Search Input is NOT present.
    2017/09/28 20:05:20 New updated value:  Hello
    

    NOTE:

    首先,我使用Google Chrome Developer Tools进行了检查,以确定Javascript符合我的需要。它有很大帮助。 我添加了我在Chrome开发者工具上试过的Javascript的屏幕截图。

    Screen shot of the Chrome Developer Tool

    我希望它可以帮到你。 :)

答案 1 :(得分:0)

我正面临相同的问题,不确定是否相同,这是我的代码:

ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()

var existingNodes []*cdp.Node
var nonExistingNodes []*cdp.Node
err := chromedp.Run(ctx,
    chromedp.Navigate(`https://www.google.com`),
    chromedp.WaitVisible("div.ctr-p"),
    chromedp.Query("#fsl a", chromedp.AtLeast(0), chromedp.After(func(i context.Context, n ...*cdp.Node) error {
        existingNodes = n
        return nil
    })),
    chromedp.Query("#fsl div.nonexists", chromedp.AtLeast(0), chromedp.After(func(i context.Context, n ...*cdp.Node) error {
        nonExistingNodes = n
        return nil
    })),
)
if err != nil {
    panic(err)
}
fmt.Printf("existingNodes count: %d\n", len(existingNodes))
fmt.Printf("nonExistingNodes count: %d\n", len(nonExistingNodes))

结果是: 现有节点数:3 nonExistingNodes计数:0