golang 使用agouti驱动phantomjs、headless chrome

借助agouti库我们可以在golang下实现对动态网页的爬取。

安装:

go get -u -v github.com/sclevine/agouti

1. phantomjs

package  main

import (
	"fmt"
	"math/rand"
	"time"

	"github.com/sclevine/agouti"
)

var UserAgentList = [...]string{
	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) " +
		"Chrome/14.0.835.163 Safari/535.1",
	"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; " +
		"SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E)",
	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1 " +
		"QQBrowser/6.9.11079.201",
}

func getRandUA() string {

	rand.Seed(time.Now().UnixNano())
	rd := rand.Intn(len(UserAgentList) - 1)
	return UserAgentList[rd]
}


func  main()  {
	capabilities := agouti.NewCapabilities()
	//使用随机的ua头
	capabilities["phantomjs.page.settings.userAgent"] = getRandUA()
	//是否加载图片
	capabilities["phantomjs.page.settings.loadImages"] = false
	capabilities["phantomjs.page.settings.resourceTimeout"] = 30
	capabilities["phantomjs.page.settings.disk-cache"] = false
	//phantomjs 不支持gzip
	capabilities["phantomjs.page.customHeaders.accept-encoding"] = "deflate, br"
	capabilities["phantomjs.page.settings.clearMemoryCaches"] = true

	capabilitiesOption := agouti.Desired(capabilities)

	dr := agouti.PhantomJS(capabilitiesOption)

	// driver启动超时时间
	dr.Timeout = time.Second*20

  // 启动phantomjs
	if err := dr.Start(); err != nil {
		fmt.Printf("failed to start driver, err:%s", err.Error())
		return
	}
	
	defer dr.Stop()
	// 打开一个新的页面
	page, err := dr.NewPage()
	if err != nil {
		fmt.Printf("failed to open page, err:%s", err.Error())
		return
	}

	defer page.CloseWindow()

	// 网页加载超时,单位毫秒
	page.SetPageLoad(10000)

	err = page.Navigate("http://www.toutiao.com")
	if err != nil {
		fmt.Printf("failed to navigate, err:%s ", err.Error())
		return
	}

	fmt.Println(page.HTML())

    //截图
	page.Screenshot(“./toutiao.png”)
}
	

使用phantomjs 有几个需要注意的点:

  1. phantomjs 不支持gzip压缩的网页
  2. phantomjs 在某些情况下设置下加载图片可以解决内存泄漏

capabilities[“phantomjs.page.settings.loadImages”] = true

具体参考这个讨论: https://github.com/ariya/phantomjs/issues/12903

  1. 一个phantomjs实例长期运行不关闭会造成内存泄漏,目前应该没办法解决。 所以,建议一个实例使用后马上关闭它, 可以避免内存泄漏问题。

  2. 启动phantomjs实例去做请求,可能会因为启动driver超时造成这次请求失败。所以,这种情况最好还是处理一下,比如找个地方把任务缓存一下,再做一次。

  3. phantomjs进程可能无法有效退出, 建议程序退出时强制杀死进行清理。

总之: phantomjs会有很多的bug,小心使用。

2. headless chrome

	optionList := []string{
		"--headless",
		"--window-size=1000,900",
		"--incognito", //隐身模式
		"--blink-settings=imagesEnabled=true",
		"--no-default-browser-check",
		"--ignore-ssl-errors=true",
		"--ssl-protocol=any",
		"--no-sandbox",
		"--disable-breakpad",
		"--disable-gpu",
		"--disable-logging",
		"--no-zygote",
		"--allow-running-insecure-content",
	}

	userAgent := "--user-agent=" + getRandUA()
	optionList = append(optionList, userAgent)

	dr := agouti.ChromeDriver(
		agouti.ChromeOptions("args", optionList),
		agouti.Desired(
			agouti.Capabilities{
				"loggingPrefs": map[string]string{
					"performance": "ALL",
				},
				"acceptSslCerts":      true,
				"acceptInsecureCerts": true,
			},
		),
	)

后面的部分跟phantomjs部分的代码一样。

这里也说明一个几个关键的选项和phantomjs使用上的区别。

//无头浏览器模式
–headless
//关闭崩溃日志
–disable-breakpad
//是否加载图片
–blink-settings=imagesEnabled=false
// 忽略ssl错误
–ignore-ssl-errors=true
// 允许非安全内容
–allow-running-insecure-content
//关闭沙箱
–no-sandbox
//关闭zygote进程
–no-zygote

注意两个问题:

  1. 如果不关闭崩溃日志的话,会在/tmp目录下创建大量的临时文件,浪费系统资源。
  2. 如果发生了内存泄漏,试试NewPage()后 调用

page.Destroy()

清理一下。
3. chrome的所有命令行参数可以参考这里:
https://peter.sh/experiments/chromium-command-line-switches/

你可能感兴趣的:(Golang,headless,browser)