0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

网页爬虫 JavaScript 页面渲染技术与应用

电子设计 来源:电子设计 作者:电子设计 2020-12-25 18:28 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

廖雨寒 杨彦松 张斌

睿哲科技股份有限公司

一、背景

随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战,网络爬虫(web crawler)随之而生。但是现在的网站很少有纯静态网页,大部分网站都通过JavaScript渲染、ajax异步等实现网页数据加载。对于目前的爬虫框架来说,基本都是爬取到的未渲染过的HTML源码,所以对于爬虫来说没真正做到浏览器的所见即所爬。对于scrapy来说,官方有一个scrapy-splash项目支持页面渲染解析,然而scrapy-splash在高并发状态下极其不稳定。一种方案是通过webkit浏览器引擎直接渲染,另一种方案是通过调用浏览器渲染。通过几种方案比较,最终选择了Google Chrome Devtools Protocol开发渲染功能。

二、渲染方案可行性分析

1.Scrapy-Splash

Scrapy-splash是scrapy官方团队提供的一个解决js渲染问题的方案。Splash是处理网页渲染的模块,它内部使用的开源的webkit浏览器引擎,通过HTTP API来使用渲染服务。在scrapy中通过DownloaderMiddleware处理网页请求,实际是去请求splash接口并得到渲染后的数据。

Splash优点:

可以并行处理多个网页

获取HTML结果和/或截取屏幕截图

关掉加载图片或使用 Adblock Plus规则使得渲染速度更快

使用JavaScript处理网页内容

使用Lua脚本

能够获得具体的HAR格式的渲染信息

然而在实际使用scrapy-splash的过程中,也遇到过一些splash的问题:

对于一些特殊网站,并不能很好的处理重定向,比如一些需要通过js渲染Cookie的页面,需要通过location对象重定向好几次才能到真正的页面,但是splash只是处理了第一次的渲染Cookie后并没有实现跳转

在并发的情况下,获取到的数据有时候是没有内容的

2.Scrapy-QtWebkit

Splash是采用Webkit引擎实现的网页渲染,可直接采用Webkit对接Scrapy实现渲染网页。在Qt库中有相应的QtWebkit模块,但是在Qt5.6版本以上QtWebkit就被淘汰了,代替它的是QtWebEngine,因此,选择QtWebKit时,建议使用Qt4或者Qt5.6之前的版本。

Webkit大致通过View-->Page-->Frame的流程来加载网页。通过这些模块,对于上面splash遇到重定向问题和空页面问题都能得到解决。

Webkit优点:

细粒度处理网页渲染

资源加载可控

直接交与webkit处理更效率

Webkit缺点:

内存资源占用较大

高并发处理网页过多容易引起C底层错误

三、Google Chrome Devtools Protocol

以上两种方案,都存在各自的缺点, 那有没有可能直接通过调用浏览器加载网页呢?事实上selenium可以操作浏览器。selenium操作chrome是使用chromedriver,chromedriver底层应用的是Chrome Devtools Protocol,因此,何不直接使用Chrome Devtools Protocol。

Chrome Devtools Protocol介绍

在Chrome/Chromium浏览器中,按F12会弹出调试工具,它是通过Chrome Devtools Protocol的协议来进行数据通讯。Chrome Devtools Protocol用来与浏览器页面(pages)交互和调试的协议通道。它采用websocket来与页面建立通信通道,由发送给页面的Commands和它所产生的Events组成。

在Chrome Devtools Protocol中,有很多不同的功能模块域(domains),类似于Chrome开发这工具的个功能模块。

然而对于此例的爬虫来说,只需要用到Network,Page,Runtime等几个功能模块域:

Network允许跟踪页面的网络活动,它公开http, file, data,网络请求和响应等数据信息

Page会检查与页面相关的动作和事件

Runtime主要用作运行JavaScript操作代码

启动调试实例

要使用Chrome Devtools Protocol,需要开启调试。我们的项目运行在服务器中,所以需要开启无头模式 --headless --disable-gpu --no-sandbox。

chrome.exe --remote-debugging-port=9222 --headless --disable-gpu --no-sandbox

如果需要远程调试,可以加上参数--remote-debugging-address='0.0.0.0'。

操作Chrome Devtools Protocol

通过以上命令可以启动一个Chrome调试实例,通过HTTP调用接口:

http://loacalhost:9222/json

会得到接口返回的JSON数据:

"description": "",

"devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/A6C1F7B23DFF222A87143ACB37CBF7C4",

"id": "A6C1F7B23DFF222A87143ACB37CBF7C4",

"title": "about:blank",

"type": "page",

"url": "about:blank",

"webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/A6C1F7B23DFF222A87143ACB37CBF7C4"

默认开启实例后会有一个空的标签页(Tab),要创建新的Tab,只需要通过调用接口

http://loacalhost:9222/json/new

或者在后面直接添加网址,Tab将会创建并加载网页

http://loacalhost:9222/json/new?http://www.example.com/

在每个Tab中有一个webSocketDebuggerUrl字段,它提供了一个WebSocket接口与Chrome交互。比如要启用Page模块域,通过WebSocket发送以下命令开启:

{"id":1, "method":"Page.enable", "params":{}}

关闭Tab

http://loacalhost:9222/json/close/A6C1F7B23DFF222A87143ACB37CBF7C4

四、Scrapy实现Chrome Protocol下载渲染页面

Scrapy是一个爬虫框架,它使用了Twisted异步网络库来处理网络通讯,他的大致架构流程如图

图 1 Scrapy框架

在图1中我们看到scrapy处理网络请求的是Downloader模块,他通过DownloaderHandler下载处理器完成下载网络请求,下载处理器使用的是Twisted网络库实现的,对于Chrome Protocol来说我们通过接口操作命令实现网页加载本质上是Chrome加载网页,也就是说下载处理是通过Chrome Protocol接口操作Chrome浏览器请求加载并渲染网页,因此我们需要拿到渲染后的网页HTML源码,需要改写DownloaderHandler。

然而原生操作Chrome Protocol太繁琐,我们需要封装它。在Github上有多种语言实现了Chrome Devtools Protocol的封装。对于Python来说,我们使用Pychrome库来操作Chrome Protocol,可以直接用pip安装模块:

pip install pychrome

当然要使用该模块得要启动Chrome调试实例,通过实例的地址和端口号连接:

browser = pychrome.Browser(url="http://<your_ip>:9222")

通过new_tab()方法创建tab标签页,通过tab.start()启动当前tab的websocket链接,例如需要启动Network功能域,通过调用tab.Network.enable()来启动,通过tab.Page.navigate(url="http://www.example.com")加载网页,该页面加载时的一切网络活动都可以通过接收websocket响应得到json数据。

这时会有一个问题,何时才算是真正渲染完成页面?

图 2 JS渲染流程

在图2中是浏览器从输入网址到页面加载完成的处理流程,loadEventEnd是真正加载完成,但是在一些使用ajax异步请求的网页使用loadEventEnd并不能很好的判断为渲染结束,所以这里我们使用JavaScript命令获取readyState状态判断页面是否加载完成:

document.readyState

readyState一共有五种状态:

uninitialized - XML 对象被产生,但没有任何文件被加载

loading - 加载程序进行中,但文件尚未开始解析

loaded - 部分的文件已经加载且进行解析,但对象模型尚未生效

interactive - 仅对已加载的部分文件有效,在此情况下,对象模型是有效但只读的

complete - 文件已完全加载,代表加载成功

通过document.readyState == complate来判断数据的加载进度。当加载完成时通过javascript命令获取渲染后的HTML源码:

document.documentElement.outerHTML

在这里我们就可以使用Pychrome替代scrapy的twisted下载处理。

五、结语

使用chrome devtools protocol来操作chrome浏览器来渲染页面,能基本完成渲染页面的需求,一些需要与浏览器交互的页面也大致能使用JavaScript操作命令,重点是使用chrome操作页面渲染会很占用资源,因此不宜过多的开启渲染进程,多线程下载尽量重用Tab标签页,因为每多创建一个Tab相当于开了一个进程,最后,爬虫结束时,应该调用相关接口关闭所有Tab,释放资源。

审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • javascript
    +关注

    关注

    0

    文章

    525

    浏览量

    56005
  • 应用软件
    +关注

    关注

    0

    文章

    53

    浏览量

    9375
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    # 深度解析:爬虫技术获取淘宝商品详情并封装为API的全流程应用

    需求。本文将深入探讨如何借助爬虫技术实现淘宝商品详情的获取,并将其高效封装为API。 一、爬虫技术核心原理与工具 1.1 爬虫运行机制 网络
    的头像 发表于 11-17 09:29 168次阅读

    Nginx限流与防爬虫配置方案

    在互联网业务快速发展的今天,网站面临着各种流量冲击和恶意爬虫的威胁。作为运维工程师,我们需要在保证正常用户访问的同时,有效防范恶意流量和爬虫攻击。本文将深入探讨基于Nginx的限流与防爬虫解决方案,从原理到实践,为大家提供一套完
    的头像 发表于 09-09 15:52 655次阅读

    从 CPU 到 GPU,渲染技术如何重塑游戏、影视与设计?

    渲染技术是计算机图形学的核心内容之一,它是将三维场景转换为二维图像的过程。渲染技术一直在不断演进,从最初的CPU渲染到后来的GPU
    的头像 发表于 09-01 12:16 673次阅读
    从 CPU 到 GPU,<b class='flag-5'>渲染</b><b class='flag-5'>技术</b>如何重塑游戏、影视与设计?

    知乎开源“智能预渲染框架” 几行代码实现鸿蒙应用页面“秒开”

    近日,知乎在Gitee平台开源了其自研的鸿蒙“智能预渲染框架”,并将该框架的Har包上架到OpenHarmony三方库中心仓。该框架在鸿蒙平台首创“智能预渲染技术,旨在破解应用复杂页面
    的头像 发表于 08-29 14:32 471次阅读
    知乎开源“智能预<b class='flag-5'>渲染</b>框架” 几行代码实现鸿蒙应用<b class='flag-5'>页面</b>“秒开”

    ArkUI介绍

    是共用的,但是相比类Web开发范式,声明式开发范式无需JS框架进行页面DOM管理,渲染更新链路更为精简,占用内存更少,应用性能更佳。 发展趋势:声明式开发范式后续会作为主推的开发范式持续演进,为开发者
    发表于 06-24 06:41

    CPU渲染、GPU渲染、XPU渲染详细对比:哪个渲染最快,哪个效果最好?

    动画渲染动画3D渲染技术需要应对复杂的计算任务和精细的图像处理,作为渲染技术人员,选择合适的渲染
    的头像 发表于 04-15 09:28 1205次阅读
    CPU<b class='flag-5'>渲染</b>、GPU<b class='flag-5'>渲染</b>、XPU<b class='flag-5'>渲染</b>详细对比:哪个<b class='flag-5'>渲染</b>最快,哪个效果最好?

    HarmonyOS应用高负载场景分帧渲染

    ,可以采用分帧渲染技术,将原本在一帧内加载的数据分散到多帧中逐步加载,从而减轻单帧的渲染压力。不过,分帧渲染需要开发者精确计算每帧加载的数据量,操作较为复杂,因此建议仅在性能瓶颈明显且
    的头像 发表于 03-25 10:28 860次阅读
    HarmonyOS应用高负载场景分帧<b class='flag-5'>渲染</b>

    Get这个秘籍,鸿蒙原生应用页面滑动丝滑无比

    问题的解决方案,通过创新技术手段解决不同技术栈下的性能瓶颈,为开发者提供更流畅的页面渲染体验,有效提升鸿蒙应用的页面滑动流畅度。 ArkUI
    发表于 03-06 14:41

    从CPU到GPU:渲染技术的演进和趋势

    渲染技术是计算机图形学的核心内容之一,它是将三维场景转换为二维图像的过程。渲染技术一直在不断演进,从最初的CPU渲染到后来的GPU
    的头像 发表于 02-21 11:11 1376次阅读
    从CPU到GPU:<b class='flag-5'>渲染</b><b class='flag-5'>技术</b>的演进和趋势

    GPU渲染才是大势所趋?CPU渲染与GPU渲染的现状与未来

    在3D建模和渲染领域,随着技术的发展,CPU渲染和GPU渲染这两种方法逐渐呈现出各自独特的优势,并且在不同的应用场景中各有侧重。尽管当前我们处在一个CPU
    的头像 发表于 02-06 11:04 1235次阅读
    GPU<b class='flag-5'>渲染</b>才是大势所趋?CPU<b class='flag-5'>渲染</b>与GPU<b class='flag-5'>渲染</b>的现状与未来

    SciChart—高性能的JavaScript图表和图形库

    使用 SciChart 的 JavaScript 图表库为您的 JS 应用程序发现终极解决方案。 使用 WebGL 创建动态、高速的图表和图形,非常适合实时处理复杂的数据可视化。使用我们强大而灵活
    的头像 发表于 01-22 10:15 2532次阅读
    SciChart—高性能的<b class='flag-5'>JavaScript</b>图表和图形库

    Spire.XLS for JavaScript——多功能JavaScript电子表格库(一)

    Spire.XLS for JavaScript 是一款专为开发人员设计的 JavaScript Excel 工具库,支持在任何 JavaScript 环境下直接创建、读取、编辑和转换 Excel
    的头像 发表于 01-21 09:29 797次阅读
    Spire.XLS for <b class='flag-5'>JavaScript</b>——多功能<b class='flag-5'>JavaScript</b>电子表格库(一)

    javascript:void(0) 是否影响SEO优化

    GoogleBot)在解析网页时,会尝试理解每个链接的目的和指向。然而,当爬虫遇到 javascript:void(0) 这样的伪URL时,它无法确定这个链接的真实意图或指向的具体内容。因此,这样的链接
    的头像 发表于 12-31 16:08 981次阅读

    javascript:void(0) 的作用是什么

    : 阻止链接跳转 : 当你有一个 标签但不想让它跳转到另一个页面时,可以使用 javascript:void(0) 作为 href 属性的值。这样可以防止浏览器加载一个新的页面。 a href
    的头像 发表于 12-31 15:55 4062次阅读

    IP地址数据信息和爬虫拦截的关联

    多样的数据,那么我们应该怎么利用IP地址信息来对爬虫行为进行识别呢? 访问频率异常的大概率是爬虫行为 正常用户访问:浏览网站时,操作速度会受到人类行为习惯的限制,通常会在页面上停留一定时间进行阅读、思考,所以访问频率相对较低且具
    的头像 发表于 12-23 10:13 678次阅读