之前寫了個現在看來很不完美的小爬蟲,很多地方沒有處理好,比如說在知乎點開一個問題的時候,它的所有回答并不是全部加載好了的,當你拉到回答的尾部時,點擊加載更多,回答才會再加載一部分,所以說如果直接發送一個問題的請求鏈接,取得的頁面是不完整的。還有就是我們通過發送鏈接下載圖片的時候,是一張一張來下的,如果圖片數量太多的話,真的是下到你睡完覺它還在下,而且我們用nodejs寫的爬蟲,卻竟然沒有用到nodejs最牛逼的異步并發的特性,太浪費了啊。
思路
這次的的爬蟲是上次那個的升級版,不過呢,上次那個雖然是簡單,但是很適合新手學習啊。這次的爬蟲代碼在我的github上可以找到=>NodeSpider。
整個爬蟲的思路是這樣的:在一開始我們通過請求問題的鏈接抓取到部分頁面數據,接下來我們在代碼中模擬ajax請求截取剩余頁面的數據,當然在這里也是可以通過異步來實現并發的,對于小規模的異步流程控制,可以用這個模塊=>eventproxy,但這里我就沒有用啦!我們通過分析獲取到的頁面從中截取出所有圖片的鏈接,再通過異步并發來實現對這些圖片的批量下載。
抓取頁面初始的數據很簡單啊,這里就不做多解釋啦
/*獲取首屏所有圖片鏈接*/var getInitUrlList=function(){request.get("https://www.zhihu.com/question/").end(function(err,res){if(err){console.log(err);}else{var $=cheerio.load(res.text);var answerList=$(".zm-item-answer");answerList.map(function(i,answer){var images=$(answer).find('.zm-item-rich-text img');images.map(function(i,image){photos.push($(image).attr("src"));});});console.log("已成功抓取"+photos.length+"張圖片的鏈接");getIAjaxUrlList();}});}
模擬ajax請求獲取完整頁面
接下來就是怎么去模擬點擊加載更多時發出的ajax請求了,去知乎看一下吧!
有了這些信息,就可以來模擬發送相同的請求來獲得這些數據啦。
/*每隔毫秒模擬發送ajax請求,并獲取請求結果中所有的圖片鏈接*/var getIAjaxUrlList=function(offset){request.post("https://www.zhihu.com/node/QuestionAnswerListV").set(config).send("method=next¶ms=%B%url_token%%A%C%pagesize%%A%C%offset%%A" +offset+ "%D&_xsrf=adfdeee").end(function(err,res){if(err){console.log(err);}else{var response=JSON.parse(res.text);/*想用json的話對json序列化即可,提交json的話需要對json進行反序列化*/if(response.msg&&response.msg.length){var $=cheerio.load(response.msg.join(""));/*把所有的數組元素拼接在一起,以空白符分隔,不要這樣join(),它會默認數組元素以逗號分隔*/var answerList=$(".zm-item-answer");answerList.map(function(i,answer){var images=$(answer).find('.zm-item-rich-text img');images.map(function(i,image){photos.push($(image).attr("src"));});});setTimeout(function(){offset+=;console.log("已成功抓取"+photos.length+"張圖片的鏈接");getIAjaxUrlList(offset);},);}else{console.log("圖片鏈接全部獲取完畢,一共有"+photos.length+"條圖片鏈接");// console.log(photos);return downloadImg();}}});}
在代碼中post這條請求https://www.zhihu.com/node/QuestionAnswerListV2,把原請求頭和請求參數復制下來,作為我們的請求頭和請求參數,superagent的set方法可用來設置請求頭,send方法可以用來發送請求參數。我們把請求參數中的offset初始為20,每隔一定時間offset再加20,再重新發送請求,這樣就相當于我們每隔一定時間發送了一條ajax請求,獲取到最新的20條數據,每獲取到了數據,我們再對這些數據進行一定的處理,讓它們變成一整段的html,便于后面的提取鏈接處理。 異步并發控制下載圖片再獲取完了所有的圖片鏈接之后,即判定response.msg為空時,我們就要對這些圖片進行下載了,不可能一條一條下對不對,因為如你所看到的,我們的圖片足足有
沒錯,2萬多張,不過幸好nodejs擁有神奇的單線程異步特性,我們可以同時對這些圖片進行下載。但這個時候問題來了,聽說同時發送請求太多的話會被網站封ip噠!這是真的嗎?我不知道啊,沒試過,因為我也不想去試( ̄ 主站蜘蛛池模板: 在线天堂资源 | 久久精品国产99久久久古代 | 黄色视频一级毛片 | 激情大乳女做爰办公室韩国 | 国产日产精品一区二区三区四区 | av电影网在线观看 | av免播放 | 九九热免费精品视频 | 看91| 蜜桃一本色道久久综合亚洲精品冫 | 92看片淫黄大片欧美看国产片 | 特大黑人videos与另类娇小 | chinese乱子伦xxxx国语对白 | 国产一区免费在线 | 日日爱99 | 精品久久久久久久久久久久久久 | 成人三级在线播放 | 国产精品久久久久久久久久妇女 | 国产超碰人人做人人爱ⅴa 国产精品久久久久久久hd | 毛片韩国 | 亚洲精品一区二区三区免 | 国产午夜亚洲精品理论片大丰影院 | 日本教室三级在线看 | 久久出精品 | 亚洲精品aⅴ中文字幕乱码 欧美囗交 | 久久91久久久久麻豆精品 | 黄视频网站免费 | 男人的天堂毛片 | 羞羞视频一区 | 北原夏美av | 日韩深夜视频 | 黄色毛片免费视频 | 国产一区二区影视 | 欧美成人精品h版在线观看 国产一级淫片在线观看 | omofun 动漫在线观看 | 欧美性生话视频 | 蜜桃一本色道久久综合亚洲精品冫 | 污污短视频 | 特大黑人videos与另类娇小 | 久久综合伊人 | 日本看片一区二区三区高清 |