python 爬取国内小说网站

 更新时间:2021年06月07日 14:31:08   作者:勤劳上班的卑微小张  
国内小说网站的结构,大概都如出一辙,改改地址,就差不多了,有此需求的朋友可以参考下本文的爬虫写法

原理先行

作为一个资深的小说爱好者,国内很多小说网站如出一辙,什么 🖊*阁啊等等,大都是 get 请求返回 html 内容,而且会有标志性的<dl><dd>等标签。
所以大概的原理,就是先 get 请求这个网站,然后对获取的内容进行清洗,写进文本里面,变成一个 txt,导入手机,方便看小说。

实践篇

之前踩过一个坑,一开始我看了几页小说,大概小说的内容网站是https://www.xxx.com/小说编号/章节编号.html,一开始看前几章,我发现章节编号是连续的, 于是我一开始想的就是记住起始章节编号,然后在循环的时候章节编号自增就行,后面发现草率了,可能看个 100 章之后,章节列表会出现断层现象,这个具体为啥 还真不知道,按理说小说编号固定,可以算是一个数据表,那里面的章节编号不就是一个自增 id 就完了嘛?有懂王可以科普一下!
所以这里要先获取小说的目录列表,并把目录列表洗成一个数组方便我们后期查找!getList.py文件:

定义一个请求书签的方法

# 请求书签地址
def req():
    url = "https://www.24kwx.com/book/4/4020/"
    strHtml = requests.get(url)
    return strHtml.text

将获取到的内容提取出(id:唯一值/或第 X 章小说)(name:小说的章节名称)(key:小说的章节 id)

# 定义一个章节对象
class Xs(object):
    def __init__(self,id,key,name):
        self._id = id
        self._key = key
        self._name = name

    @property
    def id(self):
        self._id
    @property
    def key(self):
        self._key
    @property
    def name(self):
        self._name

    def getString(self):
        return 'id:%s,name:%s,key:%s' %(self._id,self._name,self._key)

# 转换成书列表
def tranceList():
    key = 0
    name = ""
    xsList = []
    idrule = r'/4020/(.+?).html'
    keyrule = r'第(.+?)章'
    html = req()
    html = re.split("</dt>",html)[2]
    html = re.split("</dl>",html)[0]
    htmlList = re.split("</dd>",html)
    for i in htmlList:
        i = i.strip()
        if(i):
            # 获取id
            id = re.findall(idrule,i)[0]
            lsKeyList = re.findall(keyrule,i)
            # 如果有章节
            if len(lsKeyList) > 0 :
                key = int(lsKeyList[0])
                lsname = re.findall(r'章(.+?)</a>',i)
            else :
                key = key + 1
            # 获取名字
            # lsname = re.findall(r'.html">(.+?)</a>',i)[0]
            # name = re.sub(',',' ', lsname, flags=re.IGNORECASE)
            name = re.findall(r'.html">(.+?)</a>',i)[0]
            xsobj = Xs(id,key,name)
            xsList.append(xsobj.getString())
    writeList(xsList)

注意一下我:如果你从别的语言转 py,第一次写object对象可能会比较懵,没错因为他的object是一个class,这里我创建的对象就是{id,key,name}但是你写入 txt 的时候还是要getString,所以后面想想我直接写个{id:xxx,name:xxx,key:xxx}的字符串不就完了,还弄啥class,后面还是想想给兄弟盟留点看点,就留着了

最后写入 txt 文件

# 写入到文本
def writeList(list):
    f = open("xsList.txt",'w',encoding='utf-8')
    # 这里不能写list,要先转字符串 TypeError: write() argument must be str, not list
    f.write('\n'.join(list))
    print('写入成功')

# 大概写完的txt是这样的
id:3798160,name:第1章 孙子,我是你爷爷,key:1
id:3798161,name:第2章 孙子,等等我!,key:2
id:3798162,name:第3章 天上掉下个亲爷爷,key:3
id:3798163,name:第4章 超级大客户,key:4
id:3798164,name:第5章 一张退婚证明,key:5

ok ! Last one
这里已经写好了小说的目录,那我们就要读取小说的内容,同理

先写个请求

# 请求内容地址
def req(id):
    url = "https://www.24kwx.com/book/4/4020/"+id+".html"
    strHtml = requests.get(url)
    return strHtml.text

读取我们刚刚保存的目录

def getList():
    f = open("xsList.txt",'r', encoding='utf-8')
    # 这里按行读取,读取完后line是个数组
    line = f.readlines()
    f.close()
    return line

定义好一个清洗数据的规则

contextRule = r'<div class="content">(.+?)<script>downByJs();</script>'
titleRule = r'<h1>(.+?)</h1>'
def getcontext(objstr):
    xsobj = re.split(",",objstr)
    id = re.split("id:",xsobj[0])[1]
    name = re.split("name:",xsobj[1])[1]
    html = req(id)
    lstitle = re.findall(titleRule,html)
    title = lstitle[0] if len(lstitle) > 0 else name
    context = re.split('<div id="content" class="showtxt">',html)[1]
    context = re.split('</div>',context)[0]
    context = re.sub('&nbsp;|\r|\n','',context)
    textList = re.split('<br />',context)
    textList.insert(0,title)
    for item in textList :
        writeTxt(item)
    print('%s--写入成功'%(title))

再写入文件

def writeTxt(txt):
    if txt :
        f = open("nr.txt",'a',encoding="utf-8")
        f.write(txt+'\n')

最后当然是串联起来啦

def getTxt():
    # 默认参数配置
    startNum = 1261 # 起始章节
    endNum = 1300 # 结束章节
    # 开始主程序
    f = open("nr.txt",'w',encoding='utf-8')
    f.write("")
    if endNum < startNum:
        print('结束条数必须大于开始条数')
        return
    allList = getList()
    needList = allList[startNum-1:endNum]
    for item in needList:
        getcontext(item)
        time.sleep(0.2)
    print("全部爬取完成")

完整代码

getList.py

import requests
import re

# 请求书签地址
def req():
    url = "https://www.24kwx.com/book/4/4020/"
    strHtml = requests.get(url)
    return strHtml.text

# 定义一个章节对象
class Xs(object):
    def __init__(self,id,key,name):
        self._id = id
        self._key = key
        self._name = name

    @property
    def id(self):
        self._id
    @property
    def key(self):
        self._key
    @property
    def name(self):
        self._name

    def getString(self):
        return 'id:%s,name:%s,key:%s' %(self._id,self._name,self._key)

# 转换成书列表
def tranceList():
    key = 0
    name = ""
    xsList = []
    idrule = r'/4020/(.+?).html'
    keyrule = r'第(.+?)章'
    html = req()
    html = re.split("</dt>",html)[2]
    html = re.split("</dl>",html)[0]
    htmlList = re.split("</dd>",html)
    for i in htmlList:
        i = i.strip()
        if(i):
            # 获取id
            id = re.findall(idrule,i)[0]
            lsKeyList = re.findall(keyrule,i)
            # 如果有章节
            if len(lsKeyList) > 0 :
                key = int(lsKeyList[0])
                lsname = re.findall(r'章(.+?)</a>',i)
            else :
                key = key + 1
            # 获取名字
            # lsname = re.findall(r'.html">(.+?)</a>',i)[0]
            # name = re.sub(',',' ', lsname, flags=re.IGNORECASE)
            name = re.findall(r'.html">(.+?)</a>',i)[0]
            xsobj = Xs(id,key,name)
            xsList.append(xsobj.getString())
    writeList(xsList)

# 写入到文本
def writeList(list):
    f = open("xsList.txt",'w',encoding='utf-8')
    # 这里不能写list,要先转字符串 TypeError: write() argument must be str, not list
    f.write('\n'.join(list))
    print('写入成功')


def main():
    tranceList()

if __name__ == '__main__':
    main() 

writeTxt.py

import requests
import re
import time


# 请求内容地址
def req(id):
    url = "https://www.24kwx.com/book/4/4020/"+id+".html"
    strHtml = requests.get(url)
    return strHtml.text

def getList():
    f = open("xsList.txt",'r', encoding='utf-8')
    # 这里按行读取
    line = f.readlines()
    f.close()
    return line

contextRule = r'<div class="content">(.+?)<script>downByJs();</script>'
titleRule = r'<h1>(.+?)</h1>'
def getcontext(objstr):
    xsobj = re.split(",",objstr)
    id = re.split("id:",xsobj[0])[1]
    name = re.split("name:",xsobj[1])[1]
    html = req(id)
    lstitle = re.findall(titleRule,html)
    title = lstitle[0] if len(lstitle) > 0 else name
    context = re.split('<div id="content" class="showtxt">',html)[1]
    context = re.split('</div>',context)[0]
    context = re.sub('&nbsp;|\r|\n','',context)
    textList = re.split('<br />',context)
    textList.insert(0,title)
    for item in textList :
        writeTxt(item)
    print('%s--写入成功'%(title))

def writeTxt(txt):
    if txt :
        f = open("nr.txt",'a',encoding="utf-8")
        f.write(txt+'\n')

def getTxt():
    # 默认参数配置
    startNum = 1261 # 起始章节
    endNum = 1300 # 结束章节
    # 开始主程序
    f = open("nr.txt",'w',encoding='utf-8')
    f.write("")
    if endNum < startNum:
        print('结束条数必须大于开始条数')
        return
    allList = getList()
    needList = allList[startNum-1:endNum]
    for item in needList:
        getcontext(item)
        time.sleep(0.2)
    print("全部爬取完成")

    
def main():
    getTxt()

if __name__ == "__main__":
    main()

以上就是python 爬取国内小说网站的详细内容,更多关于python 爬取小说网站的资料请关注脚本之家其它相关文章!

相关文章

  • Python全栈之列表数据类型详解

    Python全栈之列表数据类型详解

    这篇文章主要给大家介绍了关于Python全栈之列表数据类型的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Python具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-10-10
  • OpenCV连通域数量统计学习示例

    OpenCV连通域数量统计学习示例

    这篇文章主要为大家介绍了OpenCV连通域数量统计示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • PyCharm搭建一劳永逸的开发环境

    PyCharm搭建一劳永逸的开发环境

    这篇文章主要介绍了PyCharm搭建一劳永逸的开发环境,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 教你使用Python 的 Template 类生成文件报告

    教你使用Python 的 Template 类生成文件报告

    这篇文章主要介绍了用 Python 的 Template 类生成文件报告,在阅读本文时,您不仅学习了Python字符串的基本知识,Template类以及使用它的原因,而且还实现了第一个文件报告脚本,需要的朋友可以参考下
    2022-08-08
  • Python基于随机采样一至性实现拟合椭圆(优化版)

    Python基于随机采样一至性实现拟合椭圆(优化版)

    这篇文章主要对上一版的Python基于随机采样一至性实现拟合椭圆的优化,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的可以了解一下
    2022-11-11
  • PyCharm提示No Python Interpreter的正确解决办法

    PyCharm提示No Python Interpreter的正确解决办法

    刚学Python时,拿到一个Python项目,想用pycharm打开运行却报错了,这篇文章主要给大家介绍了关于PyCharm提示No Python Interpreter的正确解决办法,需要的朋友可以参考下
    2023-10-10
  • 用ReactJS和Python的Flask框架编写留言板的代码示例

    用ReactJS和Python的Flask框架编写留言板的代码示例

    这篇文章主要介绍了用ReactJS和Python的Flask框架编写留言板的代码示例,其他的话用到了MongoDB这个方便使用JavaScript来操作的数据库,需要的朋友可以参考下
    2015-12-12
  • python常用的魔法方法(双下划线)

    python常用的魔法方法(双下划线)

    本文介绍一下python中常用的魔法方法以及面向对象中非常重要的单例模式。具有一定的参考价值,感兴趣的可以了解一下
    2021-09-09
  • Python 从列表中取值和取索引的方法

    Python 从列表中取值和取索引的方法

    今天小编就为大家分享一篇Python 从列表中取值和取索引的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Python PyQt5模块实现窗口GUI界面代码实例

    Python PyQt5模块实现窗口GUI界面代码实例

    这篇文章主要介绍了Python PyQt5模块实现窗口GUI界面代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05

最新评论