httpunit 抓取网页(热图主流的实现方式一般实现热图显示需要经过如下阶段)

优采云 发布时间: 2021-09-30 06:17

  httpunit 抓取网页(热图主流的实现方式一般实现热图显示需要经过如下阶段)

  主流热图的实现

  一般来说,热图展示的实现需要经过以下几个阶段:

  获取网站页面,获取处理后的用户数据,绘制热图。本文主要针对stage 1,详细介绍获取热图中网站页面的主流实现。使用iframe直接嵌入用户网站 抓取用户页面并保存在本地,通过iframe嵌入本地资源(这里所谓的本地资源被认为是分析工具端)

  这两种方法各有优缺点。首先,第一种方法直接嵌入用户网站。这有一定的限制。比如用户网站阻止了iframe劫持,则不允许嵌套iframe(设置meta X-FRAME-OPTIONS为sameorgin或者直接设置http header,甚至直接通过js控制

  if(window.top !== window.self){ window.top.location = window.location;}

  )。在这种情况下,客户网站需要做一部分工作才能被分析工具的iframe加载。使用起来可能不太方便,因为并不是所有需要检测分析的网站用户都可以做Manage 网站。

  第二种方式是直接抓取网站页面到本地服务器,然后在本地服务器上浏览抓取的页面。在这种情况下,页面已经来了,我们可以为所欲为。首先我们绕过X-FRAME-OPTIONS是同源问题,只需要解决js控件的问题,对于抓取到的页面,我们可以通过特殊的对应来处理(比如去掉对应的js控件,或者添加我们自己的js); 但是这种方法也有很多缺点:1、不能抓取spa页面,不能抓取需要用户登录授权的页面,不能抓取用户白白设置的页面等等。

  这两种方法都有 https 和 http 资源。同源策略带来的另一个问题是https站无法加载http资源。因此,为了获得最佳的兼容性,热图分析工具需要与http协议一起应用。当然,可以根据详细信息进行访问。对客户网站及具体分站优化。

  如何优化网站页面的抓取

  这里我们针对爬取网站页面遇到的问题,基于puppeteer做了一些优化,增加爬取成功的概率,主要优化了以下两个页面:

  spa页面spa页面在当前页面被认为是主流,但一直都知道对搜索引擎不友好;通常的页面爬虫程序其实就是一个简单的爬虫程序,过程通常是向User 网站(应该是user 网站 server)发起http get请求。这种爬取方式本身就会有问题。首先,直接请求用户服务器。用户服务器对非浏览器代理应该有很多限制,需要绕过处理;其次,请求返回原创内容,需要处理。浏览器中js渲染的部分无法获取(当然嵌入iframe后,js的执行还是会一定程度上弥补这个问题的)。最后,如果页面是spa页面,那么此时只获取到模板,在热图中间的显示效果非常不友好。针对这种情况,如果是基于puppeteer的,流程就变成了puppeteer启动浏览器打开用户网站-->页面渲染-->返回渲染结果,简单的用伪代码实现为如下:

  const puppeteer = require('puppeteer');

async getHtml = (url) =>{

const browser = await puppeteer.launch();

const page = await browser.newPage();

await page.goto(url);

return await page.content();

}

  这样我们得到的内容就是渲染出来的内容,不管页面是怎么渲染的(客户端渲染还是服务端)

  需要登录的页面

  需要登录页面的情况其实有很多:

  const puppeteer = require("puppeteer");

async autoLogin =(url)=>{

const browser = await puppeteer.launch();

const page =await browser.newPage();

await page.goto(url);

await page.waitForNavigation();

//登录

await page.type('#username',"用户提供的用户名");

await page.type('#password','用户提供的密码');

await page.click('#btn_login');

//页面登录成功后,需要保证redirect 跳转到请求的页面

await page.waitForNavigation();

return await page.content();

}

  这种情况会更容易处理,你可以简单地认为是以下步骤:

  通过puppeteer启动浏览器打开请求页面-->点击登录按钮-->输入用户名密码登录-->重新加载页面

  基本代码如下:

  const puppeteer = require("puppeteer");

async autoLoginV2 =(url)=>{

const browser = await puppeteer.launch();

const page =await browser.newPage();

await page.goto(url);

await page.click('#btn_show_login');

//登录

await page.type('#username',"用户提供的用户名");

await page.type('#password','用户提供的密码');

await page.click('#btn_login');

//页面登录成功后,是否需要reload 根据实际情况来确定

await page.reload();

return await page.content();

}

  总结

  明天总结,今天下班了。

  补充(偿还昨天的债务):puppeteer虽然可以友好地抓取页面内容,但也有很多限制

  抓取的内容是渲染后的原创html,即资源​​路径(css、image、javascript)等都是相对路径,本地保存后无法正常显示。需要特殊处理(js不需要特殊处理,甚至可以去掉。因为渲染的结构已经完成) 通过puppeteer爬取页面的性能会比直接http get的性能差,因为渲染进程也不能保证页面的完整性,但是完整性的概率大大提高,虽然通过页面对象提供的各种wait方法可以解决这个问题,但是网站不同,处理方法会不同,不能重复使用。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线