设为首页 收藏本站
查看: 1608|回复: 0

[经验分享] golang使用chrome headless获取网页内容

[复制链接]

尚未签到

发表于 2018-9-20 12:22:12 | 显示全部楼层 |阅读模式
  如今动态渲染的页面越来越多,爬虫们或多或少都需要用到headless browser来渲染待爬取的页面。
  而最近广泛使用的headless browser解决方案PhantomJS已经宣布不再继续维护,转而推荐使用headless chrome。
  那么headless chrome究竟是什么呢,Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序。
  简而言之,除了没有图形界面,headless chrome具有所有现代浏览器的特性,可以像在其他现代浏览器里一样渲染目标网页,并能进行网页截图,获取cookie,获取html等操作。
  详细信息可以在这获取:https://developers.google.cn/web/updates/2017/04/headless-chrome
  有关headless chrome如何使用网上有许多不错的文章,这里就不重复了。
  想要在golang程序里使用headless chrome,需要借助一些开源库,实现和headless chrome交互的库有很多,这里选择chromedp,接口和Selenium类似,易上手。
  安装:
  

go get -u github.com/chromedp/chromedp  

  引入:
  

import (  "github.com/chromedp/chromedp"
  // runner用于配置headless chrome
  "github.com/chromedp/chromedp/runner"
  
)
  

  

  创建headless chrome实例,每一个实例就相当于一个浏览器,可以用它浏览、调试网页内容,默认情况下chromedp会直接启动带GUI的chrome,所以需要使用runner启动headless chrome。默认端口为9222,可以自定义。
  

// NewHeadless 创建headless chrome实例  
// chromedp内部有自己的超时设置,你也可以通过ctx来设置更短的超时
  
func NewHeadless(ctx context.Context, starturl string) (*chromedp.CDP, error) {
  // runner.Flag设置启动headless chrome时的命令行参数
  // runner.URL设置启动时打开的URL
  // Windows用户需要设置runner.Flag("disable-gpu", true),具体信息参见文档的FAQ
  run, err := runner.New(runner.Flag("headless", true),
  runner.URL(starturl))
  

  if err != nil {
  return nil, err
  }
  

  // run.Start启动实例
  err = run.Start(ctx)
  if err != nil {
  return nil, err
  }
  

  // 默认情况chromedp会输出大量log,因为是示例所以选择屏蔽
  // 使用runner初始化chromedp实例
  // 实例在使用完毕后需要调用c.Shutdown()来释放资源
  c, err := chromedp.New(ctx, chromedp.WithRunner(run), chromedp.WithErrorf(dropChromeLogs))
  if err != nil {
  return nil, err
  }
  

  return c, nil
  
}
  

  

  

ctx, cancel := context.WithCancel(context.Background())  
defer cancel()
  
cdp := NewHeadless(ctx, "www.cnblogs.com")
  

  

  实例启动后我们就能通过这个实例来访问你想爬取的URL了。
  chromedp的实例类型为*chromedp.CDP,它拥有一个func (c *CDP) Run(ctxt context.Context, a Action) error 方法来执行所有的操作。
  Action是chromedp的api返回的对象,代表对headless chrome的一个操作,多个操作可以放入chromedp.Tasks里,它是一个元素为Action的slice,也可以作为Run的参数调用。
  下面是部分常用的api:
  

// chromedp.Sleep使headless chrome睡眠d表示的时间长度  
func Sleep(d time.Duration) Action
  

  
// chromedp.Navigate使浏览器访问参数给出的URL
  
func Navigate(urlstr string) Action
  

  
// chromedp.SendKeys向指定的html元素内输入内容
  
// sel是选择器字符串或是选择器要求的数据类型
  
// opts指定使用何种选择器
  
// 常用的选择器有:
  
// chromedp.ByID:根据id来选择元素
  
// chromedp.ByQuery:根据DOM.querySelector的规则选择元素
  
func SendKeys(sel interface{}, v string, opts ...QueryOption) Action
  

  
// chromedp.Submit将指定的元素(通常是form)提交
  
func Submit(sel interface{}, opts ...QueryOption) Action
  

  
// chromedp.WaitReady等待指定元素加载完毕
  
func WaitReady(sel interface{}, opts ...QueryOption) Action
  

  
// chromedp.Click在指定元素上触发鼠标点击事件
  
func Click(sel interface{}, opts ...QueryOption) Action
  

  
// chromedp.OuterHTML获取指定元素的HTML代码(包括其子元素)
  
// html参数用于存放返回的HTML
  
func OuterHTML(sel interface{}, html *string, opts ...QueryOption) Action
  

  

  一个获取页面内容的小例子,更多例子在 https://github.com/chromedp/examples
  

// 获取服务列表  
func GetServiceList(res *string) chromedp.Tasks {
  return chromedp.Tasks{
  // 访问服务列表
  chromedp.Navigate(ServiceListURL),
  // 等待直到body加载完毕
  chromedp.WaitReady("servicesList", chromedp.ByID),
  // 选择显示可用服务
  chromedp.Click("statusActive", chromedp.ByID),
  // 等待列表渲染
  chromedp.Sleep(2 * time.Second),
  // 获取获取服务列表HTML
  chromedp.OuterHTML("#servicesList table", res, chromedp.ByQuery),
  }
  
}
  

  
var html string
  
// cdp是chromedp实例
  
// ctx是创建cdp时使用的context.Context
  
err := cdp.Run(ctx, GetServiceList(&html) )
  
if err != nil {
  // 错误处理
  
}
  

  
// 成功取得HTML内容进行后续处理
  
fmt.Println(html)
  

  

  至此golang通过chromedp(https://github.com/chromedp/chromedp)使用headless chrome进行动态网页的渲染和操作就介绍完了。
  希望这篇文章能给你带来帮助,如有错误之处,欢迎交流指正。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-598864-1-1.html 上篇帖子: Golang项目开发管理 下篇帖子: linux golang开发环境配置(离线方式)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表