httpunit 抓取网页(热图主流的实现方式一般实现热图显示需要经过如下阶段)
优采云 发布时间: 2022-02-17 21:05httpunit 抓取网页(热图主流的实现方式一般实现热图显示需要经过如下阶段)
热图的主流实现
一般来说,热图展示的实现需要经过以下几个阶段:
1.获取网站页面
2.获取处理后的用户数据
3.绘制热图
本文主要以stage 1为重点,详细介绍heatmaps中获取网站页面的主流实现
4.使用 iframe 直接嵌入用户网站
5. 抓取用户页面并保存在本地,通过iframe嵌入本地资源(所谓本地资源被认为是分析工具的终点)
两种方法都有各自的优缺点
首先,第一个直接嵌入用户网站,这个有一定的限制,比如如果用户网站为了防止iframe劫持,不允许iframe嵌套(将meta X-FRAME-OPTIONS设置为sameorgin或者直接设置http头,甚至直接通过js控制if(!== window.self){.location = window.location;}),这种情况下客户端网站需要做一些工作在能被工具分析之前,iframe加载不一定那么好用,因为不是所有需要检测分析的网站用户都能管理网站。
第二种方式是直接将网站页面抓取到本地服务器,然后在本地服务器上浏览抓取的页面。在这种情况下,页面已经过来了,我们可以为所欲为。首先,我们绕过X-FRAME-OPTIONS同orgin的问题,只需要解决js控制的问题。对于抓取的页面,我们可以通过特殊的对应处理(比如去掉对应的js控件,或者添加我们自己的js);但这种方法也有很多不足:1、不能爬取spa页面,不能爬取需要用户登录授权的页面,不能爬取用户设置的白懂的页面等等。
两种方法中的https和http资源之间的同源策略还存在另一个问题。HTTPS 站点无法加载 http 资源。因此,为了获得最佳兼容性,热图分析工具需要与http协议一起应用。当然也可以根据具体情况进行访问。网站 的客户和特定的变电站进行了优化。
如何优化爬取网站页面
这里我们针对爬取网站页面遇到的问题,基于puppeteer做了一些优化,以提高爬取成功的概率,主要优化以下两个页面:
1.水疗页面
spa页面是当前页面中的主流,但一直都知道它对搜索引擎不友好;通常的页面爬取程序其实就是一个简单的爬虫程序,进程通常会向用户网站(应该是用户网站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();
}
这样,无论页面如何渲染(客户端渲染或服务器端),我们得到的内容都是渲染后的内容
需要登录的页面
需要登录页面的情况有很多:
您需要登录才能查看该页面。如果没有登录,跳转到登录页面(各种管理系统)
对于这种类型的页面,我们需要做的是模拟登录。所谓模拟登录,就是让浏览器登录。这里,用户需要提供网站对应的用户名和密码,然后我们经过如下流程:
访问用户网站-->User网站检测到自己没有登录,跳转到登录-->puppeteer控制浏览器自动登录,然后跳转到真正需要爬取的页面. 下面的伪代码可以用来说明:
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虽然可以非常友好的抓取页面内容,但是也有很多限制。
1.抓取的内容是渲染后的原创html,即资源路径(css、image、javascript)等都是相对路径,保存到本地后无法正常显示,需要特殊处理(js不需要特殊处理,甚至可以去掉,因为渲染的结构已经做好了)
2.通过puppeteer爬取页面的性能会比直接http get差,因为渲染进程比较多
3.同样不能保证页面的完整性,但是大大提高了完整性的概率。虽然页面对象提供的各种等待方法都可以解决这个问题,但是网站处理方法会有所不同。不同,不能重复使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Scripting Home。