Golang+selenium+chrome headless + goquery 在Linux 上作爬虫实践

以前使用PhantomJS,但效果并不好,现在使用Golang+selenium 驱动 chrome headless 模式,再用 goquery 解析html 字符,很方便。

首先在服务器上安装最新版本的chrome 和 chromedriver

chrome headless 配置

启动 chrome 及简单配置

	var opts []selenium.ServiceOption
	caps := selenium.Capabilities{
		"browserName": "chrome",
	}

	// 禁止加载图片,加快渲染速度
	imgCaps := map[string]interface{}{
		"profile.managed_default_content_settings.images": 2,
	}

	chromeCaps := chrome.Capabilities{
		Prefs: imgCaps,
		Path:  "",
		Args: []string{
			"--headless",
			"--start-maximized",
			//"--window-size=1200x600",
			"--no-sandbox",
			"--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
			"--disable-gpu",
			"--disable-impl-side-painting",
			"--disable-gpu-sandbox",
			"--disable-accelerated-2d-canvas",
			"--disable-accelerated-jpeg-decoding",
			"--test-type=ui",
		},
	}
	caps.AddChrome(chromeCaps)
	
	// 启动 chromedriver server
	service, err := selenium.NewChromeDriverService("chromedriver", port, opts...)
	if err != nil {
		log.Printf("Error starting the ChromeDriver server: %v", err)
		return
	}
	defer service.Stop()

打开一个网页

	// 打开 chrome 浏览器
	wd, err := selenium.NewRemote(caps, fmt.Sprintf("http://localhost:%d/wd/hub", port))
	if err != nil {
		log.Println(err)
		return
	}
	defer wd.Quit()

然后加载URL

	err = wd.Get(curURL)
	if err != nil {
		log.Println(fmt.Sprintf("Failed to load page: %s\n", err))
	}

判断加载完成

	jsRt, err := wd.ExecuteScript("return document.readyState", nil)
	if err != nil {
		log.Println("exe js err", err)
	}
	fmt.Println("jsRt", jsRt)
	if jsRt != "complete" {
		log.Println("网页加载未完成")
		return
	}

获取网站内容

	var frameHtml string

	time.Sleep(1 * time.Second)
	frameHtml, err = wd.PageSource()
	if err != nil {
		log.Println(err)
		return
	}

解析html 文件

这里推荐使用 https://github.com/PuerkitoBio/goquery 32

	var doc *goquery.Document
	doc, err = goquery.NewDocumentFromReader(bytes.NewReader([]byte(frameHtml)))
	if err != nil {
		log.Println(err)
		return
	}

	doc.Find("li.s-result-item").Each(func(liIndex int, liItem *goquery.Selection) {
		// do something
	})

selenium go 驱动库

selenium https://github.com/tebeka/selenium 73

Relative Articles
本文网址: https://www.golangnote.com/topic/232.html (转载注明出处)
关于GolangNote:记录在工作中使用golang 遇到、面临的相关问题及解决方法。如果你在这里获得一些知识或信息,解决你的编程问题,请考虑捐赠给不幸的人或者你喜欢的慈善机构,除捐赠外,种植树木、志愿服务或减少排碳的行为也很有益处。