js抓取网页内容(热图主流的实现方式一般实现热图显示需要经过如下阶段)
优采云 发布时间: 2021-10-23 12:18js抓取网页内容(热图主流的实现方式一般实现热图显示需要经过如下阶段)
主流热图的实现
热图展示的一般实现需要经过以下几个阶段:
1.获取网站页面
2.获取处理过的用户数据
3.绘制热图
本文主要围绕stage 1详细介绍获取热图中网站页面的主流实现
4.使用iframe直接嵌入用户网站
5. 抓取用户页面并保存到本地,通过iframe嵌入本地资源(这里所谓的本地资源被认为是分析工具端)
两种方法各有优缺点
首先,第一种是直接嵌入用户网站。这有一定的限制。比如用户网站阻止了iframe劫持,就不允许嵌套iframe(设置meta x-frame-options为sameorgin或者直接设置http头,甚至控制if (!== window.self){ .location = window.location;}) 直接通过js。在这种情况下,客户网站需要做一些工作才能通过工具进行分析加载iframe使用起来不是那么方便,因为并不是所有需要检测和分析的网站用户都可以管理网站。
第二种方式是直接抓取网站页面到本地服务器,然后在本地服务器上浏览抓取的页面。在这种情况下,页面已经来了,我们可以为所欲为。首先,我们绕过x-frame-options是sameorgin的问题,只需要解决js控制的问题。对于抓取到的页面,我们可以通过特殊对应的方式进行处理(比如去掉对应的js控件,或者添加我们自己的js);但是这种方法也有很多缺点:1、不能抓取spa页面,不能抓取需要用户登录授权的页面,不能抓取用户白白设置的页面等等。
这两种方法都有 https 和 http 资源。同源策略带来的另一个问题是https站无法加载http资源。因此,为了获得最佳的兼容性,热图分析工具需要与http协议一起应用。当然,可以根据详细信息进行访问。对客户网站及具体分站优化。
如何优化网站页面的抓取
这里我们针对爬取网站页面遇到的问题,基于puppeteer做了一些优化,增加爬取成功的概率,主要优化了以下两个页面:
1.水疗页面
spa页面在当前页面被认为是主流,但一直都知道对搜索引擎不友好;通常的页面爬虫程序其实就是一个简单的爬虫程序,过程通常是向用户网站(应该是用户网站服务器)发起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();
}
这样我们得到的内容就是渲染出来的内容,不管页面是怎么渲染的(客户端渲染还是服务端)
需要登录的页面
需要登录页面的情况其实有很多:
您需要登录才能查看该页面。未登录会跳转到登录页面(各种管理系统)
对于这种类型的页面,我们需要做的是模拟登录。所谓模拟登录就是让浏览器登录,这里需要用户提供网站对应的用户名和密码,然后我们按照以下流程进行:
访问用户网站-->用户网站检测未登录跳转登录-->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. 也不能保证页面的完整性,但是大大提高了完整性的概率。虽然页面对象提供的各种wait方法都可以解决这个问题,但是网站不同,处理方法也会不同,不能复用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持万千网。