【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】實(shí)例:使用puppeteer headless方式抓取JS網(wǎng)_第1頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】實(shí)例:使用puppeteer headless方式抓取JS網(wǎng)_第2頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】實(shí)例:使用puppeteer headless方式抓取JS網(wǎng)_第3頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】實(shí)例:使用puppeteer headless方式抓取JS網(wǎng)_第4頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】實(shí)例:使用puppeteer headless方式抓取JS網(wǎng)_第5頁(yè)
已閱讀5頁(yè),還剩4頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】實(shí)例:使用puppeteerheadless方式抓取JS網(wǎng)

puppeteergooglechrome團(tuán)隊(duì)出品的puppeteer是依賴nodejs和chromium的自動(dòng)化測(cè)試庫(kù),它的最大優(yōu)點(diǎn)就是可以處理網(wǎng)頁(yè)中的動(dòng)態(tài)內(nèi)容,如JavaScript,能夠更好的模擬用戶。有些網(wǎng)站的反爬蟲手段是將部分內(nèi)容隱藏于某些javascript/ajax請(qǐng)求中,致使直接獲取a標(biāo)簽的方式不奏效。甚至有些網(wǎng)站會(huì)設(shè)置隱藏元素“陷阱”,對(duì)用戶不可見(jiàn),腳本觸發(fā)則認(rèn)為是機(jī)器。這種情況下,puppeteer的優(yōu)勢(shì)就凸顯出來(lái)了。它可實(shí)現(xiàn)如下功能:開(kāi)源地址:[/GoogleChrome/puppeteer/][1]npmipuppeteer注意先安裝nodejs,并在nodejs文件根目錄下執(zhí)行(npm文件同級(jí))。安裝過(guò)程中會(huì)下載chromium,大約120M。用兩天(大約10小時(shí))摸索,繞過(guò)了相當(dāng)多的異步的坑,筆者對(duì)puppeteer和nodejs有了一定的掌握。一張長(zhǎng)圖,抓取blog文章列表:抓取blog文章以csdnblog為例,文章內(nèi)容需要點(diǎn)擊“閱讀全文”來(lái)獲取,這就導(dǎo)致只能讀取dom的腳本失效。/**

*loadarticletolocalfiles

**/

constpuppeteer=require('puppeteer');

//emulateiphone

constuserAgent='Mozilla/5.0(iPhone;CPUiPhoneOS11_0likeMacOSX)AppleWebKit/604.1.38(KHTML,likeGecko)Version/11.0Mobile/15A372Safari/604.1';

constworkPath='./contents';

constfs=require("fs");

if(!fs.existsSync(workPath)){

fs.mkdirSync(workPath)

}

//baseurl

constrootUrl='/';

//maxwaitmilliseconds

constmaxWait=100;

//maxloopscrolltimes

constmakLoop=10;

(async()=>{

leturl;

letcountUrl=0;

constbrowser=awaitpuppeteer.launch({headless:false});//setheadless:truewillhidechromiumUI

constpage=awaitbrowser.newPage();

awaitpage.setUserAgent(userAgent);

awaitpage.setViewport({width:414,height:736});

awaitpage.setRequestInterception(true);

//filtertoblockimages

page.on('request',request=>{

if(request.resourceType()==='image')

request.abort();

else

request.continue();

});

awaitpage.goto(rootUrl);

for(leti=0;i<makLoop;i++){

try{

awaitpage.evaluate(()=>window.scrollTo(0,document.body.scrollHeight));

awaitpage.waitForNavigation({timeout:maxWait,waitUntil:['networkidle0']});

}catch(err){

console.log('scrolltobottomandthenwait'+maxWait+'ms.');

}

}

awaitpage.screenshot({path:workPath+'/screenshot.png',fullPage:true,quality:100,type:'jpeg'});

//#feedlist_idli[data-type="blog"]a

constsel='#feedlist_idli[data-type="blog"]h3a';

consthrefs=awaitpage.evaluate((sel)=>{

letelements=Array.from(document.querySelectorAll(sel));

letlinks=elements.map(element=>{

returnelement.href

})

returnlinks;

},sel);

console.log('totallinks:'+hrefs.length);

process();

asyncfunctionprocess(){

if(countUrl<hrefs.length){

url=hrefs[countUrl];

countUrl++;

}else{

browser.close();

return;

}

console.log('processingurl:'+url);

try{

consttab=awaitbrowser.newPage();

awaittab.setUserAgent(userAgent);

awaittab.setViewport({width:414,height:736});

awaittab.setRequestInterception(true);

//filtertoblockimages

tab.on('request',request=>{

if(request.resourceType()==='image')

request.abort();

else

request.continue();

});

awaittab.goto(url);

//executetaprequest

try{

awaittab.tap('.read_more_btn');

}catch(err){

console.log('there\'snonereadmorebutton.NoneedtoTAP');

}

lettitle=awaittab.evaluate(()=>document.querySelector('#article.article_title').innerText);

letcontents=awaittab.evaluate(()=>document.querySelector('#article.article_content').innerText);

contents='TITLE:'+title+'\nURL:'+url+'\nCONTENTS:\n'+contents;

constfs=require("fs");

fs.writeFileSync(workPath+'/'+tab.url().substring(tab.url().lastIndexOf('/'),tab.url().length)+'.txt',contents);

console.log(title+"hasbeendownloadedtolocal.");

awaittab.close();

}catch(err){

console.log('url:'+tab.url()+'\n'+err.toString());

}finally{

process();

}

}

})();

執(zhí)行過(guò)程錄屏可以在我公眾號(hào)查看,下邊是截圖:執(zhí)行結(jié)果文章內(nèi)容列表:文章內(nèi)容:結(jié)束語(yǔ)以前就想過(guò)既然nodejs是使用JavaScript腳本語(yǔ)言,那么它肯定能處理網(wǎng)頁(yè)的JavaScript內(nèi)容,但并沒(méi)有發(fā)現(xiàn)合適的/高效率的庫(kù)。直到發(fā)現(xiàn)puppeteer,才下定決心試水。話說(shuō)回來(lái),nodejs的異步真的是很頭疼的一件事,這上百行代碼我竟然折騰了10個(gè)小時(shí)。大家可拓展下代碼中process()方法,使用async.eachSeries,我使用的遞歸方式并不是最優(yōu)解。事實(shí)上,逐一處理并不高效,原本我寫了一個(gè)異步的關(guān)閉browser方法:lettryCloseBrowser=setInterval(function(){

console.log("checkifanyprocessrunning...")

if(countDown<=0){

clearInterval(tryCloseBrowser);

console.log("noneprocessrunning,close.")

browser.close();

}

},3000);按照這個(gè)思路

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論