版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 福建省福州市福州師范大學(xué)附屬中學(xué)2024屆高三3月聯(lián)合檢測(cè)試題(數(shù)學(xué)試題文)試題
- 2024年那曲c1客運(yùn)資格證考試
- 算法設(shè)計(jì)與分析 課件 6.2-貪心法-基本原理
- 算法設(shè)計(jì)與分析 課件 1.2.3-算法分析準(zhǔn)則 - 時(shí)間復(fù)雜度 - 漸近分析及符號(hào)表示
- 2024年貴陽(yáng)客運(yùn)從業(yè)資格證考試題目及答案詳解
- 2024年百色考客運(yùn)從業(yè)資格證考試題目
- 2024年天津客運(yùn)從業(yè)資格證模擬考試題庫(kù)電子版
- 2024年哈爾濱客運(yùn)資格證考試模擬題答案
- 廠房租賃協(xié)議
- 吉首大學(xué)《空間解析幾何》2021-2022學(xué)年第一學(xué)期期末試卷
- 與小三斷絕協(xié)議書
- 典型事例綜合素質(zhì)評(píng)價(jià)范文六篇
- 電力用油中顆粒污染度測(cè)量方法
- 運(yùn)輸包裝收發(fā)貨標(biāo)志
- 2016春季高考英語(yǔ)真題
- 江蘇省無(wú)錫市惠山區(qū)2022-2023學(xué)年八年級(jí)上學(xué)期期中英語(yǔ)試卷(含答案)
- 高中心理健康《情緒調(diào)適》憤怒情緒的建設(shè)性表達(dá) 課件
- 擬與用工單位簽訂的勞務(wù)派遣協(xié)議文本
- 廢氣治理工程施工組織設(shè)計(jì)方案
- 消毒產(chǎn)品人員崗位責(zé)任制度
- 袁隆平的英文簡(jiǎn)介課件
評(píng)論
0/150
提交評(píng)論