最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

node基于puppeteer模擬登錄抓取頁面的實(shí)現(xiàn)

 更新時間:2018年05月09日 16:21:33   作者:JerremyZhang  
本篇文章主要介紹了node基于puppeteer模擬登錄抓取頁面的實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

關(guān)于熱圖

在網(wǎng)站分析行業(yè)中,網(wǎng)站熱圖能夠很好的反應(yīng)用戶在網(wǎng)站的操作行為,具體分析用戶的喜好,對網(wǎng)站進(jìn)行針對性的優(yōu)化,一個熱圖的例子(來源于ptengine)

上圖中能很清晰的看到用戶關(guān)注點(diǎn)在那,我們不關(guān)注產(chǎn)品中熱圖的功能如何,本篇文章就熱圖的實(shí)現(xiàn)做一下簡單的分析和總結(jié)。

熱圖主流的實(shí)現(xiàn)方式

一般實(shí)現(xiàn)熱圖顯示需要經(jīng)過如下階段:
1.獲取網(wǎng)站頁面
2.獲取經(jīng)過處理后的用戶數(shù)據(jù)
3.繪制熱圖
 本篇主要聚焦于階段1來詳細(xì)的介紹一下主流的在熱圖中獲取網(wǎng)站頁面的實(shí)現(xiàn)方式
4.使用iframe直接嵌入用戶網(wǎng)站
5.抓取用戶頁面保存到本地,通過iframe嵌入本地資源(所謂本地資源這里認(rèn)為是分析工具這一端)

兩種方式各有各的優(yōu)缺點(diǎn)

首先第一種直接嵌入用戶網(wǎng)站,這個有一定的限制條件,比如如果用戶網(wǎng)站為了防止iframe劫持,不允許iframe嵌套(設(shè)置meta X-FRAME-OPTIONS 為sameorgin 或者直接設(shè)置http header ,甚至直接通過js來控制if(window.top !== window.self){ window.top.location = window.location;} ),這種情況下就需要客戶網(wǎng)站做一部分工作才可以被分析工具的iframe加載,使用起來不一定那么方便,因?yàn)椴⒉皇撬械男枰獧z測分析的網(wǎng)站用戶都可以管理網(wǎng)站的。

第二種方式,直接抓取網(wǎng)站頁面到本地服務(wù)器,然后瀏覽的是本機(jī)服務(wù)器上抓取的頁面,這種情況下頁面已經(jīng)過來了,我們就可以為所欲為了,首先我們繞過了X-FRAME-OPTIONS 為sameorgin的問題,只需要解決js控制的問題,對于抓取的頁面來說,我們可以通過特殊的對應(yīng)來處理(比如移除對應(yīng)的js控制,或者添加我們自己的js);但是這種方式也有很多的不足:1、無法抓取spa頁面,無法抓取需要用戶登錄授權(quán)的頁面,無法抓取用戶設(shè)置了白明白的頁面等等。

兩種方式都存在https 和 http資源由于同源策略引起的另一個問題,https站無法加載http資源,所以如果為了最好的兼容性,熱圖分析工具需要被應(yīng)用http協(xié)議,當(dāng)然具體可以根據(jù)訪問的客戶網(wǎng)站而具體分站優(yōu)化。

抓取網(wǎng)站頁面如何優(yōu)化

這里我們針對抓取網(wǎng)站頁面遇到的問題基于puppeteer做一些優(yōu)化,提高抓取成功的概率,主要優(yōu)化以下兩種頁面:

1.spa頁面

spa頁面在當(dāng)前頁算是主流了,但是它總所周知的是其對搜索引擎的不友好;通常的頁面抓取程序其實(shí)就是一個簡單的爬蟲,其過程通常都是發(fā)起一個http get 請求到用戶網(wǎng)站(應(yīng)該是用戶網(wǎng)站服務(wù)器)。這種抓取方式本身就會有問題問題,首先,直接請求的是用戶服務(wù)器,用戶服務(wù)器對非瀏覽器的agent 應(yīng)該會有很多限制,需要繞過處理;其次,請求返回的是原始內(nèi)容,需要在瀏覽器中通過js渲染的部分無法獲?。ó?dāng)然,在iframe嵌入后,js執(zhí)行還是會再一定程度上彌補(bǔ)這個問題),最后如果頁面是spa頁面,那么此時獲取的只是模板,在熱圖中顯示效果非常不友好。

針對這種情況,如果基于puppeteer來做,流程就變成了

puppeteer啟動瀏覽器打開用戶網(wǎng)站-->頁面渲染-->返回渲染后結(jié)果,簡單的用偽代碼實(shí)現(xiàn)如下:

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();
}

這樣我們拿到的內(nèi)容就是渲染后的內(nèi)容,無論頁面的渲染方式如何(客戶端渲染抑或服務(wù)端)

需要登錄的頁面

對于需要登錄頁面其實(shí)分為多種情況:

需要登錄才可以查看頁面,如果沒有登錄,則跳轉(zhuǎn)到login頁面(各種管理系統(tǒng))

對于這種類型的頁面我們需要做的就是模擬登錄,所謂模擬登錄就是讓瀏覽器去登錄,這里需要用戶提供對應(yīng)網(wǎng)站的用戶名和密碼,然后我們走如下的流程:

訪問用戶網(wǎng)站-->用戶網(wǎng)站檢測到未登錄跳轉(zhuǎn)到login-->puppeteer控制瀏覽器自動登錄后跳轉(zhuǎn)到真正需要抓取的頁面,可用如下偽代碼來說明:

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 跳轉(zhuǎn)到請求的頁面
   await page.waitForNavigation();

   return await page.content();
}

登錄與否都可以查看頁面,只是登錄后看到內(nèi)容會所有不同 (各種電商或者portal頁面)

這種情況處理會比較簡單一些,可以簡單的認(rèn)為是如下步驟:

通過puppeteer啟動瀏覽器打開請求頁面-->點(diǎn)擊登錄按鈕-->輸入用戶名和密碼登錄 -->重新加載頁面

基本代碼如下圖:

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 根據(jù)實(shí)際情況來確定
   await page.reload();

   return await page.content();
}

總結(jié)

明天總結(jié)吧,今天下班了。

補(bǔ)充(還昨天的債):基于puppeteer雖然可以很友好的抓取頁面內(nèi)容,但是也存在這很多的局限

1.抓取的內(nèi)容為渲染后的原始html,即資源路徑(css、image、javascript)等都是相對路徑,保存到本地后無法正常顯示,需要特殊處理(js不需要特殊處理,甚至可以移除,因?yàn)殇秩镜慕Y(jié)構(gòu)已經(jīng)完成)

2.通過puppeteer抓取頁面性能會比直接http get 性能會差一些,因?yàn)槎嗔虽秩镜倪^程

3.同樣無法保證頁面的完整性,只是很大的提高了完整的概率,雖然通過page對象提供的各種wait 方法能夠解決這個問題,但是網(wǎng)站不同,處理方式就會不同,無法復(fù)用。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 輕松創(chuàng)建nodejs服務(wù)器(4):路由

    輕松創(chuàng)建nodejs服務(wù)器(4):路由

    這篇文章主要介紹了輕松創(chuàng)建nodejs服務(wù)器(4):路由,服務(wù)器需要根據(jù)不同的URL或請求來執(zhí)行不一樣的操作,我們可以通過路由來實(shí)現(xiàn)這個步驟,需要的朋友可以參考下
    2014-12-12
  • node.js監(jiān)聽文件變化的實(shí)現(xiàn)方法

    node.js監(jiān)聽文件變化的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于node.js監(jiān)聽文件變化的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用node.js具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • npm報(bào)錯:request to httpsregistry.npm.taobao.org failed, reason certificate has expired的解決方案

    npm報(bào)錯:request to httpsregistry.npm.taobao.org 

    這篇文章主要介紹了npm報(bào)錯:request to httpsregistry.npm.taobao.org failed, reason certificate has expired的解決方案,文中有詳細(xì)的解決方案,需要的朋友可以參考下
    2024-03-03
  • windows系統(tǒng)下更新nodejs版本的方案

    windows系統(tǒng)下更新nodejs版本的方案

    這篇文章主要介紹了windows系統(tǒng)下更新nodejs版本的方案,在文章給大家介紹了NodeJS 與 npm 在Windows下升級問題,需要的朋友可以參考下
    2017-11-11
  • Node.js進(jìn)程退出的深入理解

    Node.js進(jìn)程退出的深入理解

    NodeJS可以感知和控制自身進(jìn)程的運(yùn)行環(huán)境和狀態(tài),也可以創(chuàng)建子進(jìn)程并與其協(xié)同工作,這使得NodeJS可以把多個程序組合在一起共同完成某項(xiàng)工作,下面這篇文章主要給大家介紹了關(guān)于Node.js進(jìn)程退出的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • nodejs微信公眾號支付開發(fā)

    nodejs微信公眾號支付開發(fā)

    這篇文章主要為大家詳細(xì)介紹了nodejs微信公眾號支付開發(fā),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • node.js平臺下的mysql數(shù)據(jù)庫配置及連接

    node.js平臺下的mysql數(shù)據(jù)庫配置及連接

    本文主要介紹了node.js平臺下的mysql數(shù)據(jù)庫配置及連接的相關(guān)知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-03-03
  • 詳解用node編寫自己的cli工具

    詳解用node編寫自己的cli工具

    這篇文章主要介紹了詳解用node編寫自己的cli工具,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Ubuntu安裝Node.js的2種方式

    Ubuntu安裝Node.js的2種方式

    這篇文章主要給大家介紹了關(guān)于Ubuntu安裝Node.js的2種方式,在Ubuntu系統(tǒng)上安裝Node.js和npm非常簡單,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • Nodejs提取網(wǎng)址參數(shù)解決“querystring”已棄用問題

    Nodejs提取網(wǎng)址參數(shù)解決“querystring”已棄用問題

    無論是前端還是后端,經(jīng)常出現(xiàn)的應(yīng)用場景是URL中參數(shù)的處理,下面這篇文章主要給大家介紹了關(guān)于Nodejs提取網(wǎng)址參數(shù)解決“querystring”已棄用問題的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08

最新評論

岚皋县| 遂昌县| 施秉县| 木兰县| 宜阳县| 鹰潭市| 西畴县| 沁水县| 北碚区| 武宣县| 荥经县| 云南省| 大连市| 礼泉县| 晋城| 沅陵县| 抚顺县| 巨鹿县| 巢湖市| 宁海县| 分宜县| 资兴市| 林甸县| 万荣县| 长沙县| 永年县| 墨竹工卡县| 六盘水市| 普兰县| 冷水江市| 蓬莱市| 裕民县| 营口市| 安平县| 唐海县| 多伦县| 名山县| 蕉岭县| 东城区| 巴马| 民权县|