账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    用node做一个爬虫,无法获存储全部数据
    • 2020-01-01 00:00
    • 11
    31
    0

    问题描述

    做了一个小说爬虫,能获取到数据,但是无法获取全部的章节,会有章节缺失,并且爬到一定书籍之后程序就不在卡主不在运行,

    问题出现的环境背景及自己尝试过哪些方法

    相关代码

    // 请把代码文本粘贴到下方(请勿用图片代替代码)

    class Chapter{
        constructor(){
    
        }
        // 解析每一章的书籍信息内容
        async getChapter(url,obj){
            
            try{
                obj = obj || {}
                let chapterId = url.substring(url.lastIndexOf('/')+1,url.lastIndexOf('.'))
                let bookId = url.substring(0,url.lastIndexOf('/')).substring(url.substring(0,url.lastIndexOf('/')).lastIndexOf('/')+1)
                let databaseChapter = await modelBook.Chapter.find({chapter_id: chapterId})
                
    
                let chapter = await superagent.get(url)
                let $ = cheerio.load(chapter.text)
                let newChapter = {
                    title: $('.bookname h1').text(),
                    content: $('#content').text(),
                    chapter_id: chapterId,
                    book_id: bookId,
                    name: obj.name || '',
                    author: obj.author || '',
                }
                let newChapterModel = new modelBook.Chapter(newChapter)
                if(databaseChapter.length > 0){
                    // console.log('数据已存在')
                    await modelBook.Chapter.update({chapter_id: chapterId},newChapter)
                    return
                }
                newChapterModel.save()
                console.log('数据保存成功',chapterId)
            }catch(err){
                console.log('爬虫失败',url)
                throw Error(err)
            }
            
        }
        
    }
    
    class Book extends Chapter{
        constructor(){
            super()
            this.allcount = 0
        }
    
        // 根据书籍地址获取书籍的章节列表信息(并处理书籍的信息保存到数据库中)
        async getChapterList(url){
            
            try{
                let result = await superagent.get(url)
                let $ = cheerio.load(result.text)
                let book_id = url.substring(0,url.lastIndexOf('/'))
                book_id = book_id.substring(book_id.lastIndexOf('/')+1)
                let author = $('#info p').eq(0).text().substring($('#info p').eq(0).text().lastIndexOf(':')+1)
                let newBook = {
                    name: $('#info h1').text(),
                    author: author,
                    introduction: $('#intro p').eq(1).text(),
                    book_id: book_id,
                    img_url: $('#fmimg img').attr('src'),
                    tag: $('.con_top a').eq(2).text()
                }
                let newBookModel = new modelBook.Book(newBook)
                let bookArr = await modelBook.Book.find({book_id: book_id})
                let chapterCount = await modelBook.Chapter.find({book_id: book_id})
                                    .count()
                
                if(bookArr.length > 0){
                    // console.log('书籍信息已经存在 ')
                    await modelBook.Book.update({book_id: book_id},newBook)
                }else{
                    newBookModel.save()
                    console.log('书籍保存成功')
                }
                let oneBookChapterList = []
                $('#list dd a').map(async (index,val) => {
                    let href = $(val).attr('href')
                    oneBookChapterList.push({
                        url: urlBase + href,
                        data: {
                            name: $('#info h1').text(),
                            author: author,
                        }
                    })
                    
                })
                if(chapterCount == $('#list dd a').length){
                    console.log('书籍信息完整'+book_id)
                    return
                }else{
                    console.log('开始获取章节书籍信息不完整'+book_id)
                    async.mapLimit(oneBookChapterList,3, async (val) => {
                        await this.getChapter(val.url, val.data)
                    })
                }
                
    
    
            }catch(err){
                console.log('获取文章列表失败')
            }
        }
    
        init(){
            this.getAll(url)
        }
        async getAll(url){
            console.log(url)
            try{
                let result = await superagent.get(url)
                let $ = cheerio.load(result.text)
                let urls = []
                $('#main .novellist li').map((index, val) => {
                    let bookUrl = $(val).find('a').attr('href')
                    urls.push(bookUrl)
                })
                console.log(urls.length)
                async.mapLimit(urls,1,async (url) => {
                    await this.getChapterList(url)
                    this.allcount += 1
                    console.log('这是第'+this.allcount + '本书,地址:'+url)
                })
            }catch(err){
                console.log('书籍列表请求失败')
            }
        }
    }
    
    

    你期待的结果是什么?实际看到的错误信息又是什么?

    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 11 元积分
        全部回答
    • 0
    • 一个人坐在角落 普通会员 1楼

      如果你在使用Node.js进行爬虫时遇到无法获取全部数据的问题,可能有以下几个原因:

      1. 请求方法:检查你的网络请求是否使用了正确的请求方法,比如get、post、put等。不同的请求方法对应不同的数据获取方式,例如get方法用于获取静态资源,而post方法用于提交数据。

      2. 请求参数:检查你的请求是否包含了所有需要的参数。如果某个参数缺失或为空,请求可能无法正常进行。

      3. 数据格式:确认你的请求参数和返回的数据格式是否匹配。如果格式不匹配,可能会导致数据无法正确解析。

      4. 网络问题:如果网络连接不稳定或者速度过慢,也可能导致数据获取失败。

      5. 超时设置:检查你的请求是否设置了合理的超时时间,如果超时时间设置过短,请求可能会被中断。

      6. API限制:有些网站可能会对爬虫进行限制,比如登录、数据限制等。你需要检查这些限制是否被遵守。

      在处理这些问题时,你可以尝试使用一些库来帮助你,例如axios、request等。同时,你也可以尝试使用代理或者限速来提高爬取的效率。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部