Golang Selenium包 – 连接到Selenium服务器和无头Chrome。

huangapple go评论79阅读模式
英文:

Golang Selenium package - connect to selenium server and headless chrome

问题

我正在使用Go的selenium包https://godoc.org/github.com/tebeka/selenium

我在一个Docker容器中运行无头Chrome + selenium-server,地址是localhost:4444

由于我可以通过http://localhost:4444/wd/hub/static/resource/hub.html访问Web控制台,所以服务器似乎正常。

但是我正在尝试让现有的Docker容器与"Hello world"示例一起工作。

这是来自selenium驱动的GoDocs页面的示例代码:

// 在play.golang.org上运行一些代码并显示结果
package main

import (
	"fmt"
	"time"

	"github.com/tebeka/selenium"
)

var code = `
package main
import "fmt"

func main() {
	fmt.Println("Hello WebDriver!\n")
}
`

// 为简洁起见,忽略了错误。

func main() {
	// 连接到selenium服务器
	caps := selenium.Capabilities{"browserName": "firefox"}
	wd, err := selenium.NewRemote(caps, "http://127.0.0.1:4444")
	if err != nil {
		fmt.Println(err)
	}
	defer wd.Quit()

	// 获取简单的playground界面
	wd.Get("http://play.golang.org/?simple=1")
	
	// 在文本区域中输入代码
	elem, _ := wd.FindElement(selenium.ByCSSSelector, "#code")
	elem.Clear()
	elem.SendKeys(code)

	// 点击运行按钮
	btn, _ := wd.FindElement(selenium.ByCSSSelector, "#run")
	btn.Click()

	// 获取结果
	div, _ := wd.FindElement(selenium.ByCSSSelector, "#output")

	output := ""
	// 等待运行完成
	for {
		output, _ = div.Text()
		if output != "Waiting for remote server..." {
			break
		}
		time.Sleep(time.Millisecond * 100)
	}

	fmt.Printf("Got: %s\n", output)
}

我尝试将"browserName"更改为"chrome",但是出现以下错误:

panic: got content type "text/html", expected "application/json"

goroutine 1 [running]:
main.main()
	/home/user01/Code/golang_src/golang_exercises/33_selenium/selenium.go:28 +0x457
exit status 2

我在GoDoc的selenium文档中找不到关于Chrome浏览器以及如何通过selenium-server连接到它的任何信息。

我会很感激任何关于可能出错的提示。

更新:

似乎删除URL地址并将其留空修复了连接问题:

wd, err := selenium.NewRemote(caps, "")

话虽如此,我仍然在示例中遇到问题。主要问题是它连接到Go Playground网站,获取了正确的元素,但是当它尝试发送输入elem.SendKeys(code)时,它无法正确发送,并且文本框为空。这导致Playground输出错误:

Got: can't load package: package main: 
tmp/sandbox573608783/main.go:1:1: expected 'package', found 'EOF'

Program exited.
英文:

I'm using the Go selenium package https://godoc.org/github.com/tebeka/selenium

And I'm running headless chrome + selenium-server inside a docker container on localhost:4444

The server seems to be fine since I can access the web console via http://localhost:4444/wd/hub/static/resource/hub.html

But I'm trying to get the "Hello world" example to work with the existing docker container.

This is the example from the GoDocs page for the selenium driver:

// Run some code on play.golang.org and display the result
package main

import (
	"fmt"
	"time"

	"github.com/tebeka/selenium"
)

var code = `
package main
import "fmt"

func main() {
	fmt.Println("Hello WebDriver!\n")
}
`

// Errors are ignored for brevity.

func main() {
	// Connect to the selenium server
	caps := selenium.Capabilities{"browserName": "firefox"}
	wd, err := selenium.NewRemote(caps, "http://127.0.0.1:4444")
	if err != nil {
		fmt.Println(err)
	}
	defer wd.Quit()

	// Get simple playground interface
	wd.Get("http://play.golang.org/?simple=1")
	
	// Enter code in textarea
	elem, _ := wd.FindElement(selenium.ByCSSSelector, "#code")
	elem.Clear()
	elem.SendKeys(code)

	// Click the run button
	btn, _ := wd.FindElement(selenium.ByCSSSelector, "#run")
	btn.Click()

	// Get the result
	div, _ := wd.FindElement(selenium.ByCSSSelector, "#output")

	output := ""
	// Wait for run to finish
	for {
		output, _ = div.Text()
		if output != "Waiting for remote server..." {
			break
		}
		time.Sleep(time.Millisecond * 100)
	}

	fmt.Printf("Got: %s\n", output)
}

I tried changing the "browserName" to "chrome" but I get this error:

panic: got content type "text/html", expected "application/json"

goroutine 1 [running]:
main.main()
	/home/user01/Code/golang_src/golang_exercises/33_selenium/selenium.go:28 +0x457
exit status 2

I can't find anything in the GoDoc selenium documentation regarding the chrome browser and how to connect to it via the selenium-server.

I would appreciate any hints as to what might be going wrong here.

Update:

It seems that removing the URL address and leaving it empty has fixed the connection problems:

wd, err := selenium.NewRemote(caps, "")

That said, I'm still having issues with the example. Mainly it seems like it connects to the Go Playground website, gets the right elements, but when it comes to sending the input elem.SendKeys(code) it doesn't send it properly and the text box is empty. Resulting in bad output from the Playground:

Got: can't load package: package main: 
tmp/sandbox573608783/main.go:1:1: expected 'package', found 'EOF'

Program exited.

答案1

得分: 3

尝试在无头模式下运行:

caps := selenium.Capabilities{"browserName": "chrome"}

chromeCaps := chrome.Capabilities{
    Path: "",
    Args: []string{
        "--headless", // <<<<
        "--no-sandbox",
        "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7",
    },
}
caps.AddChrome(chromeCaps)

wd, err := selenium.NewRemote(caps, fmt.Sprintf("http://127.0.0.1:%d", port))
英文:

try run it in headless mode:

caps := selenium.Capabilities{&quot;browserName&quot;: &quot;chrome&quot;}

chromeCaps := chrome.Capabilities{
	Path:  &quot;&quot;,
	Args: []string{
		&quot;--headless&quot;, // &lt;&lt;&lt;
		&quot;--no-sandbox&quot;,
		&quot;--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7&quot;,
	},
}
caps.AddChrome(chromeCaps)

wd, err := selenium.NewRemote(caps, fmt.Sprintf(&quot;http://127.0.0.1:%d&quot;, port))

答案2

得分: 2

我也在Docker中使用selenium,可以通过以下方式运行:

wd, err := selenium.NewRemote(caps, "http://127.0.0.1:4444/wd/hub")

英文:

I also use selenium in Docker, it can run by this:

wd, err := selenium.NewRemote(caps, &quot;http://127.0.0.1:4444/wd/hub&quot;)

答案3

得分: 0

经过一些调试,我发现问题是因为我的Docker容器内没有X服务器。

当selenium包尝试发送输入时,会生成以下错误消息:

未知错误:未知错误:键码转换需要X显示,考虑使用Xvfb
  (会话信息:无头chrome=60.0.3095.5)
  (驱动程序信息:chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),平台=Linux 4.4.0-77-generic x86_64) (警告:服务器未提供任何堆栈跟踪信息)
命令持续时间或超时:40毫秒
构建信息:版本:'3.3.1',修订版:'5234b32',时间:'2017-03-10 09:04:52 -0800'
系统信息:主机:'e3bf5382c62d',IP:'171.14.0.3',os.name:'Linux',os.arch:'amd64',os.version:'4.4.0-77-generic',java.version:'1.8.0_121'
驱动程序信息:org.openqa.selenium.chrome.ChromeDriver
能力 [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, networkConnectionEnabled=false, chrome={chromedriverVersion=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5), userDataDir=/tmp/.org.chromium.Chromium.mFhqlU}, takesHeapSnapshot=true, pageLoadStrategy=normal, databaseEnabled=false, handlesAlerts=true, hasTouchScreen=false, version=60.0.3095.5, platform=LINUX, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true, unexpectedAlertBehaviour=}]
会话ID:681f9de5f91baeaaa3100cf297767a2d

我还没有在Docker容器内安装X服务器,但我相信这将修复通过selenium发送输入到无头chrome实例时出现的错误。

英文:

After some debugging I found out that the issue was due to the fact that my Docker container did not have the X server inside it.

When the selenium package tried to send input it would generate this error message:

unknown error: unknown error: an X display is required for keycode conversions, consider using Xvfb
  (Session info: headless chrome=60.0.3095.5)
  (Driver info: chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 4.4.0-77-generic x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 40 milliseconds
Build info: version: &#39;3.3.1&#39;, revision: &#39;5234b32&#39;, time: &#39;2017-03-10 09:04:52 -0800&#39;
System info: host: &#39;e3bf5382c62d&#39;, ip: &#39;171.14.0.3&#39;, os.name: &#39;Linux&#39;, os.arch: &#39;amd64&#39;, os.version: &#39;4.4.0-77-generic&#39;, java.version: &#39;1.8.0_121&#39;
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, networkConnectionEnabled=false, chrome={chromedriverVersion=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5), userDataDir=/tmp/.org.chromium.Chromium.mFhqlU}, takesHeapSnapshot=true, pageLoadStrategy=normal, databaseEnabled=false, handlesAlerts=true, hasTouchScreen=false, version=60.0.3095.5, platform=LINUX, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true, unexpectedAlertBehaviour=}]
Session ID: 681f9de5f91baeaaa3100cf297767a2d

I have not yet installed the X server inside the Docker container but I'm confident that it will fix the error that occurs when sending input to the headless chrome instance via selenium.

huangapple
  • 本文由 发表于 2017年5月17日 07:09:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/44013029.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定