Chromedp不在ActionFunc

时间:2018-01-29 16:27:41

标签: go web-scraping automation

我有一个包含术语列表的切片,我想在某个搜索引擎页面中搜索每个术语,所以我这样做:

func risk(slice []string) chromedp.Tasks {

    return chromedp.Tasks{
        chromedp.Navigate("https://testpage"),
        chromedp.WaitVisible("#query_box", chromedp.ByID),
        chromedp.ActionFunc(func(context.Context, cdp.Executor) error {
            for _, element := range slice[2:] {
                fmt.Println(element)
                chromedp.SendKeys("#query_box", element, chromedp.ByID)
                chromedp.Click("#searchButton", chromedp.ByID),
            }
            return nil
        }),
    }
} 

main内调用此内容时

err = c.Run(ctxt, risk(items))
    if err != nil {
        log.Fatal(err)
    }

一切都有效,直到ActionFunc。无论我在功能之前添加什么动作(截取屏幕等等)都可以正常工作。

但是,ActionFunc内的操作无法执行。

原因是return nil吗?我想返回一组任务,就像我在循环外做的那样,但我找不到如何在ActionFunc的循环中做到这一点,因为返回始终是最新的项而不是全套...返回nil是让函数至少开始的唯一方法。

在一组chromedp.Tasks

中执行此类循环操作的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

chromedp.ActionFunc用于构建自定义操作。您提供的功能将在Run阶段执行。

这意味着您的函数需要实际运行您在内部使用的操作。这是通过调用操作上的.Do方法并将其传递给context.Contextcdp.Executor来完成的。

对于错误,该函数应该返回运行时遇到的任何错误。在嵌入式操作上调用.Do时,请检查错误并在非零时返回。

您的代码应如下所示:

func risk(slice []string) chromedp.Tasks {

    return chromedp.Tasks{
        // ... other actions ...
        chromedp.ActionFunc(func(c context.Context, e cdp.Executor) error {
            for _, element := range slice[2:] {
                fmt.Println(element)
                err := chromedp.SendKeys("#query_box", element, chromedp.ByID).Do(c, e)
                if err != nil {
                  return err
                }
                err = chromedp.Click("#searchButton", chromedp.ByID).Do(c, e)
                if err != nil {
                  return err
                }
            }
            return nil
        }),
    }
}

免责声明:我还没有对此代码进行测试,因此可能会出现问题,但这应该会为您提供定义与执行操作以及正确返回错误的一般概念。