最近因为没小说看,也无聊,就想着用Node来写爬虫爬书下来,弄了好几天有些问题。
爬小说异步的话章节不是顺序排列的,所以用了sync-request进行同步操作,我爬的是笔趣阁这个网站上的书,现在由于刚学,只是做了爬单本书的。我发现在爬取的时候,会假死掉,停在那不动了,而且每次的章节数不同,我就加了个十秒的timeout超时,但是还是会出现这种假死的情况。后来百度了下,说网站是有防止爬虫的东东的,具体我也不太清楚==,我就想,那我就加个间隔咯,我让他每请求十次就休息20秒钟,再重新爬。结果!!!还是会假死,233333。所以现在有点不明白为啥了,想求教一下,给点思路。拜托各位~~
下面是我請求的程式碼,具體章節列表我在另一個js裡面爬出來寫在json裡面了,這邊是直接請求每個連結的了:
var http = require('http')
var fs = require('fs')
var cheerio = require('cheerio')
var iconv = require('iconv-lite')
var request = require('sync-request')
var urlList = JSON.parse(fs.readFileSync('list.json', 'utf-8'))
var header = JSON.parse(fs.readFileSync('header.json'), 'utf-8')
//爬取每章节正文并存在txt中
function getContent(list,title) {
//用try catch进行错误捕获,防止报错跳出
try{
var res = request('GET',list.link,{
'timeout': 10000,
'retry': true,
'retryDelay': 10000
})
var html = iconv.decode(res.body, 'utf8')
var $ = cheerio.load(html,{
decodeEntities: false
})
var ContentTitle = $('.bookname h1').text()
var ContentText = $('#content').text().trim().replace('readx();', '').replace(/\ /g, '')
fs.appendFileSync(title+".txt", ContentTitle)
fs.appendFileSync(title+".txt", ContentText)
console.log("爬取" + list.link + "成功")
}catch(err) {
console.log("爬取" + list.link + "出错")
}
}
//为了达到间隔的调用请求做了递归调用
function getUrl(index) {
for (let i = index;i < urlList.length;i++){
if (i>0 && i%10 == 0){
getContent(urlList[i],header.title)
console.log("休息一下")
setTimeout(() => {
i++
getUrl(i)
},20000)
return
}else {
console.log(i)
getContent(urlList[i],header.title)
}
}
}
getUrl(0)
#就跟這個一樣,爬了一段時間就這樣了,就跟死機了似得,後面不管等多久都沒動靜,設定的超時啥的也沒有反應
這兩天一直在弄這個問題,起初是以為是sync-request的問題,後來換了別的還是一樣。我就猜可能是ip網站給封鎖了還是什麼的,後來中午吃飯和同事閒聊,順便就請教了下,他們也就是說大概就這個問題。既然如此,我就去弄了些免費的代理IP,然後在請求的時候,只要是請求超時或者報錯就立刻切換一個IP地址去請求。這樣下來,昨天特地爬了一個很大的小說,今天上班過來一看,全部爬下來了,沒有出現問題,哈哈。不過免費的代理IP很多都用不了,所以在這上面浪費了部分時間。現在要開始看看怎麼爬多本書了,↖(^ω^)↗