05笔趣阁小说爬取--爬取作者所有小说

2023-11-18

前面的程序已经实现了从笔趣阁自动爬取整部小说,接下来在之前的基础上,将功能进一步扩展,实现自动爬取某一作者在笔趣阁中的所有小说。

继续以方想为例,下图是方想作品列表的页面

https://www.52bqg.com/modules/article/authorarticle.php?author=%B7%BD%CF%EB


     

考虑到程序还会进一步扩展,这里将之前的代码重新调整,使之模块化,按照功能将程序划分为:

1.Get_novels() ,接收作者小说列表网址(target),返回作者所有小说的名称(novelName)、链接(novelUrl)、作者(novelAuthor)、状态(novelstate);

2.Get_titles() ,接收单部小说链接(novelUrl[i]),返回整部小说的章节名称(titleName)、链接(titleUrl);

3.Get_contents() ,接收单部小说章节名称(titleName)和章节链接(titleUrl),返回整本小说内容(contentTxt);

4.Txt_write() ,接收单部小说名称(novelName)和整本小说内容(contentTxt),在本地创建以作品名为命名的TXT文件,并将作品内容保存到TXT文件中;

整个程序划分4个模块,按照顺序结构自上而下依次运行,前面模块的返回值做为后面模块的输入值。

一、Get_novels()

这个模块的功能是接受外部输入的网址,返回方想所有小说的名称(novelName)、链接(novelUrl)、作者(novelAuthor)、状态(novelState)。

novelName, novelUrl, novelState是列表类型;

novelAuthor是字符串类型;

观察方想作品列表页面源代码,可以看到需要的信息都存放在标签<table class="grid">下的<td>标签中。

那就继续原来的配方,原来的味道。

def Get_novels(url):
    '''
    接受外部输入的作者作品列表的网址,
    返回所有小说的名称(novelName)、链接(novelUrl)、作者(novelAuthor)、状态(novelState)
    '''
    novelName = []
    novelUrl = []
    novelAuthor = ''
    novelSize = []
    novelState = []
    try:
        req = requests.get(url=url, timeout=3)
    except:
        print('获取小说列表失败,尝试再次连接!')
        req = requests.get(url=url, timeout=3)
    req.encoding = req.apparent_encoding  # 防止乱码
    bf = BeautifulSoup(req.text, 'html.parser')
    div = bf.find_all('table',class_='grid')  # 防止与python中的class重名,此处使用class_
    # 再次bs,取<td>
    bf_td = BeautifulSoup(str(div[0]), 'html.parser')
    td = bf_td.find_all('td')
    novelAuthor = td[2].text  # 小说作者
    for i in range(len(td)):
        # 一共有6部小说,每6个<td>包含一部小说的信息,以0开始
        if i%6==0:
            novelName.append(td[i].a.string)  # 小说名称
            novelUrl.append(td[i].a.get('href'))  # 小说链接
        elif i%6==5:
            novelState.append(td[i].text)  # 小说状态
    return novelName,novelUrl,novelAuthor,novelState

二、Get_titles()

此模块的功能是,接收单部小说链接(novelUrl[i]),返回整部小说的章节名称(titleName)、链接(titleUrl)。

novelUrl[i]是字符串类型;

titleName, titleUrl都是字符串列表类型;

def Get_titles(url):
    '''返回小说章节名称(titleName)、链接(titleUrl)'''
    try:
        req = requests.get(url = url, timeout=3)
    except:
        print('获取章节信息超时,尝试再次连接!')
        req = requests.get(url = url, timeout=3)
    req.encoding = req.apparent_encoding  # 编码转换
    # 使用beautifulsoup 筛选出id=list的div标签
    bf = BeautifulSoup(req.text, "html.parser")
    lists = bf.find_all('div', id='list')
    lists = lists[0]
    # 再次使用bs,从lists中筛选出所有的标签a
    bf_a = BeautifulSoup(str(lists), 'html.parser')  # 不加str()会报错
    a = bf_a.find_all('a')
    titleName = []  # 存放章节名称
    titleUrl = []  # 存放章节链接
    for s in a:
        titleName.append(s.string)
        titleUrl.append(url + s.get('href'))  # 完整链接
    return titleName, titleUrl

三、Get_contents()

此模块的功能是,接收单部小说章节名称(titleName)和章节链接(titleUrl),返回整本小说内容(contentTxt);

titleName, titleUrl都是字符串列表,

contentTxt是字符串类型;

def Get_contents(names,urls):
    '''返回小说内容(contentTxt)'''
    contentTxt = ''  # 存放整部小说
    for i in range(len(names)):
        title = names[i]  # 标题
        url = urls[i]  # 内容页地址
        try:
            req = requests.get(url=url, timeout=(3))  # 响应时间为3秒
        except:
            print('========响应时间过长,重新下载!========')
            req = requests.get(url=url, timeout=3)  # 响应时间为3秒
        req.encoding = req.apparent_encoding  # 编码转换
        print('%d/%d,%s 已下载'%(i+1,len(names),title))
        # 使用beautifulsoup 筛选出id=content的div标签
        bf = BeautifulSoup(req.text,"html.parser")
        content = bf.find_all('div',id='content')
        content = content[0].text
        # 内容优化
        content = content.replace('\r\n           一秒记住【笔趣阁 www.52bqg.com】,精彩小说无弹窗免费阅读!\r\n           \xa0\xa0', '')
        content = content.replace('\r\n\xa0\xa0','')  # 去空行和段首空格,保留\n实现换行,保留2个空格使首行缩进2空格
        content = '\n' + title + '\n' + content + '\n'  #  保存的内容加上章节名称
        contentTxt = contentTxt + content
    return contentTxt

四、Txt_write()

此模块的功能是,接收单部小说名称(novelName)和整本小说内容(contentTxt),在本地创建以作品名为命名的TXT文件,并将作品内容保存到TXT文件中。

novelName, contentTXT都是字符串类型;

def Txt_write(name, txt):
    '''将内容保存到本地'''
    path = name + '.txt'
    with open(path,'a',encoding='utf-8') as f:
        # f.write(name + '\n')  # 章节名称
        f.writelines(txt)  # 写入小说内容
        f.write('\n\n')

五、主程序

先使用Get_novels( )取得所有小说的相关信息,

然后利用for循环,依次将小说下载到本地。

if __name__ == '__main__':
    target = 'https://www.52bqg.com/modules/article/authorarticle.php?author=%B7%BD%CF%EB'
    # 书名,链接,状态都是列表,作者为字符串
    novelName,novelUrl,novelAuthor,novelState = Get_novels(target)
    print(novelAuthor, '一共有',len(novelName), '部小说')
    print(novelName)
    for i in range(len(novelName)):
        print('开始下载第%d部,%s'%(i+1, novelName[i]))
        titleName, titleUrl = Get_titles(novelUrl[i])  # 章节名称和章节链接
        contentTxt = Get_contents(titleName,titleUrl)  # 整部小说内容
        print('开始将《%s》保存到本地'%novelName[i])
        Txt_write(novelName[i], contentTxt)  # 保存到本地
        print('小说保存成功')

下面是程序的完整代码

# 爬取笔趣阁方想的所有小说
import requests
from bs4 import BeautifulSoup

def Get_novels(url):
    '''
    接受外部输入的网址,
    返回方想所有小说的名称(novelName)、链接(novelUrl)、作者(novelAuthor)、状态(novelState)
    '''
    novelName = []
    novelUrl = []
    novelAuthor = ''
    novelSize = []
    novelState = []
    try:
        req = requests.get(url=url, timeout=3)
    except:
        print('获取小说列表失败,尝试再次连接!')
        req = requests.get(url=url, timeout=3)
    req.encoding = req.apparent_encoding  # 防止乱码
    bf = BeautifulSoup(req.text, 'html.parser')
    div = bf.find_all('table',class_='grid')  # 防止与python中的class重名,此处使用class_
    # 再次bs,取<td>
    bf_td = BeautifulSoup(str(div[0]), 'html.parser')
    td = bf_td.find_all('td')
    novelAuthor = td[2].text  # 小说作者
    for i in range(len(td)):
        # 一共有6部小说,每6个<td>包含一部小说的信息,以0开始
        if i%6==0:
            novelName.append(td[i].a.string)  # 小说名称
            novelUrl.append(td[i].a.get('href'))  # 小说链接
        elif i%6==5:
            novelState.append(td[i].text)  # 小说状态
    return novelName,novelUrl,novelAuthor,novelState

def Get_titles(url):
    '''获得小说章节名称(titleName)、链接(titleUrl)'''
    try:
        req = requests.get(url = url, timeout=3)
    except:
        print('获取章节信息超时,尝试再次连接!')
        req = requests.get(url = url, timeout=3)
    req.encoding = req.apparent_encoding  # 编码转换
    # 使用beautifulsoup 筛选出id=list的div标签
    bf = BeautifulSoup(req.text, "html.parser")
    lists = bf.find_all('div', id='list')
    lists = lists[0]
    # 再次使用bs,从lists中筛选出所有的标签a
    bf_a = BeautifulSoup(str(lists), 'html.parser')  # 不加str()会报错
    a = bf_a.find_all('a')
    titleName = []  # 存放章节名称
    titleUrl = []  # 存放章节链接
    for s in a:
        titleName.append(s.string)
        titleUrl.append(url + s.get('href'))  # 完整链接
    return titleName, titleUrl

def Get_contents(names,urls):
    '''返回小说内容(contentTxt)'''
    contentTxt = ''  # 存放整部小说
    for i in range(len(names)):
        title = names[i]  # 标题
        url = urls[i]  # 内容页地址
        try:
            req = requests.get(url=url, timeout=(3))  # 响应时间为3秒
        except:
            print('========响应时间过长,重新下载!========')
            req = requests.get(url=url, timeout=3)  # 响应时间为3秒
        req.encoding = req.apparent_encoding  # 编码转换
        print('%d/%d,%s 已下载'%(i+1,len(names),title))
        # 使用beautifulsoup 筛选出id=content的div标签
        bf = BeautifulSoup(req.text,"html.parser")
        content = bf.find_all('div',id='content')
        content = content[0].text
        # 内容优化
        content = content.replace('\r\n           一秒记住【笔趣阁 www.52bqg.com】,精彩小说无弹窗免费阅读!\r\n           \xa0\xa0', '')
        content = content.replace('\r\n\xa0\xa0','')  # 去空行和段首空格,保留\n实现换行,保留2个空格使首行缩进2空格
        content = '\n' + title + '\n' + content + '\n'  #  保存的内容加上章节名称
        contentTxt = contentTxt + content
    return contentTxt
def Txt_write(name, txt):
    '''将内容保存到本地'''
    path = name + '.txt'
    with open(path,'a',encoding='utf-8') as f:
        # f.write(name + '\n')  # 章节名称
        f.writelines(txt)  # 写入小说内容
        f.write('\n\n')

if __name__ == '__main__':
    target = 'https://www.52bqg.com/modules/article/authorarticle.php?author=%B7%BD%CF%EB'
    # 书名,链接,状态都是列表,作者为字符串
    novelName,novelUrl,novelAuthor,novelState = Get_novels(target)
    print(novelAuthor, '一共有',len(novelName), '部小说')
    print(novelName)
    for i in range(len(novelName)):
        print('开始下载第%d部,%s'%(i+1, novelName[i]))
        titleName, titleUrl = Get_titles(novelUrl[i])  # 章节名称和章节链接
        contentTxt = Get_contents(titleName,titleUrl)  # 整部小说内容
        print('开始将《%s》保存到本地'%novelName[i])
        Txt_write(novelName[i], contentTxt)  # 保存到本地
        print('小说保存成功')
    print('所有小说下载完成')



==================================华丽丽的分割线=================================================

+++++++++++++++++++++++++++++++++2020.6.12代码微调+++++++++++++++++++++++++++++++++++++++++++++++

1.控制台输出信息优化:去掉Get_novels() ,.Get_titles() ,Get_contents() 中的“响应超时”输出信息;章节下载信息变为动态显示。

2.Txt_write() 中增加文件夹新建及检测功能,TXT文件存放位置变为当前目录下的作者姓名文件夹,若下载多位作者小说分类更直观;

下为微调后完整代码:

# 爬取笔趣阁方想的所有小说
import requests
import os
from bs4 import BeautifulSoup

def Get_novels(url):
    '''
    接受外部输入的网址,
    返回方想所有小说的名称(novelName)、链接(novelUrl)、作者(novelAuthor)、状态(novelState)
    '''
    novelName = []
    novelUrl = []
    novelAuthor = ''
    novelState = []
    try:
        req = requests.get(url=url, timeout=3)
    except:
        # print('获取小说列表失败,尝试再次连接!')
        req = requests.get(url=url, timeout=3)
    req.encoding = req.apparent_encoding  # 防止乱码
    bf = BeautifulSoup(req.text, 'html.parser')
    div = bf.find_all('table',class_='grid')  # 防止与python中的class重名,此处使用class_
    # 再次bs,取<td>
    bf_td = BeautifulSoup(str(div[0]), 'html.parser')
    td = bf_td.find_all('td')
    novelAuthor = td[2].text  # 小说作者
    for i in range(len(td)):
        # 一共有6部小说,每6个<td>包含一部小说的信息,以0开始
        if i%6==0:
            novelName.append(td[i].a.string)  # 小说名称
            novelUrl.append(td[i].a.get('href'))  # 小说链接
        elif i%6==5:
            novelState.append(td[i].text)  # 小说状态
    return novelName,novelUrl,novelAuthor,novelState

def Get_titles(url):
    '''获得小说章节名称(titleName)、链接(titleUrl)'''
    try:
        req = requests.get(url = url, timeout=3)
    except:
        # print('获取章节信息超时,尝试再次连接!')
        req = requests.get(url = url, timeout=3)
    req.encoding = req.apparent_encoding  # 编码转换
    # 使用beautifulsoup 筛选出id=list的div标签
    bf = BeautifulSoup(req.text, "html.parser")
    lists = bf.find_all('div', id='list')
    lists = lists[0]
    # 再次使用bs,从lists中筛选出所有的标签a
    bf_a = BeautifulSoup(str(lists), 'html.parser')  # 不加str()会报错
    a = bf_a.find_all('a')
    titleName = []  # 存放章节名称
    titleUrl = []  # 存放章节链接
    for s in a:
        titleName.append(s.string)
        titleUrl.append(url + s.get('href'))  # 完整链接
    return titleName, titleUrl

def Get_contents(names,urls):
    '''返回小说内容(contentTxt)'''
    contentTxt = ''  # 存放整部小说
    for i in range(len(names)-2,len(names)):
        title = names[i]  # 标题
        url = urls[i]  # 内容页地址
        print('\r正在下载%d/%d,%s'%(i+1,len(names),title), end='')  #动态显示下载信息
        try:
            req = requests.get(url=url, timeout=(3))  # 响应时间为3秒
        except:
            # print('========响应时间过长,重新下载!========')
            req = requests.get(url=url, timeout=3)  # 响应时间为3秒
        req.encoding = req.apparent_encoding  # 编码转换
        # 使用beautifulsoup 筛选出id=content的div标签
        bf = BeautifulSoup(req.text,"html.parser")
        content = bf.find_all('div',id='content')
        content = content[0].text
        # 内容优化
        content = content.replace('\r\n           一秒记住【笔趣阁 www.52bqg.com】,精彩小说无弹窗免费阅读!\r\n           \xa0\xa0', '')
        content = content.replace('\r\n\xa0\xa0','')  # 去空行和段首空格,保留\n实现换行,保留2个空格使首行缩进2空格
        content = '\n' + title + '\n' + content + '\n'  #  保存的内容加上章节名称
        contentTxt = contentTxt + content
    print('\r',end='')  # 不加这句输出,控制台输出的提示信息会有空行
    return contentTxt
def Txt_write(author, name, txt):
    '''将内容保存到当前目录下作者名字的文件夹中,如果文件夹不存在,则先创建一个'''
    dirPath = '.\\' + author + '\\'
    fileName = name + '.txt'
    filePath = dirPath + fileName
    # 检测文件夹
    if os.path.exists(dirPath):
        pass
    else:
        os.mkdir(dirPath)
    with open(filePath,'a',encoding='utf-8') as f:
        f.writelines(txt)  # 写入小说内容
        f.write('\n\n')

if __name__ == '__main__':
    target = 'https://www.52bqg.com/modules/article/authorarticle.php?author=%B7%BD%CF%EB'
    # 书名,链接,状态都是列表,作者为字符串
    novelName,novelUrl,novelAuthor,novelState = Get_novels(target)
    print(novelAuthor, '一共有',len(novelName), '部小说')
    print(novelName)
    for i in range(len(novelName)):
        print('开始下载第%d部:《%s》'%(i+1, novelName[i]))
        titleName, titleUrl = Get_titles(novelUrl[i])  # 章节名称和章节链接
        contentTxt = Get_contents(titleName,titleUrl)  # 整部小说内容
        Txt_write(novelAuthor, novelName[i], contentTxt)  # 保存到本地
    print('============================================================')
    print('%s小说全部下载到本地'%novelAuthor)


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

05笔趣阁小说爬取--爬取作者所有小说 的相关文章

随机推荐