欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-26 12:17:17
...

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

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

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

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

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

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>标签中。

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

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

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('所有小说下载完成')


 

相关标签: python爬虫 python