本篇文章主要用于记录爬虫练习,所以具体网址将不显示(如果真的出现没有完全打码的情况请联系我,谢谢!),希望大家支持正版!

大纲

  • 需求描述
  • 最终效果展示
  • 步骤拆解
    • 1. 获取章节信息(URL及名称)
      • 1.1 采用requests模块获取html返回内容
      • 1.2 采用bs4中BeautifulSoup模块解析返回文本
      • 1.3. 对list进行解析,转化为目录的字典列表
    • 2. 获取每章节文本内容
      • 2.1 循环获取指定章节文本内容,加入整个list中
      • 2.2 利用time.sleep,增加请求失败重试功能
    • 3. 生成txt文本
    • 4. 重复工作模块化
  • 代码展示
  • 后续进阶(进行中)

需求描述

通过爬取盗版小说网站数据,获取某本书的章节目录信息及指定章节的文本内容,生成.txt文件。


最终效果展示

选择指定章节生成txt文本,可以在手机阅读器查看。

步骤拆解

1. 获取章节信息(URL及名称)

1.1 采用requests模块获取html返回内容

# -*- coding: utf-8 -*-
import requests
import random
url = "http://********/"#说好的不给你们看哦
headers1 = [{'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"},{'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36 "}]
headers=random.choice(headers1)#随机选择某一headers,减少反爬虫可能
r = requests.get(url, headers=headers)
r.encoding = "utf-8" #解决乱码问题
r.text

输出结果:

1.2 采用bs4中BeautifulSoup模块解析返回文本

from bs4 import BeautifulSoup
soup = BeautifulSoup(r.text, 'html.parser')
soup

输出结果:

通过Chrome检查功能,我们可以确认目录菜单在该网页body id='list" 的布局处。

list12 = soup.body.find_all("div", id="list")
list12


输出为list格式,只有一个元素。

1.3. 对list进行解析,转化为目录的字典列表

import re
#转化为str格式,并删除无效内容
list13 = str(list12[0]).replace('<div id="list">', '').replace('<dl>', '').replace('</dl>', '').replace('</div>', '')
#以 <dd><a href=" 作为每个章节的间隔,形成新的list
list1 = list13.split('<dd><a href="')
lenth = len(list1)
title_list=[]
nn = 1
for n in range(1, lenth):dict1 = {}place= list1[n].find('">')url1 = list1[n][0:place]#有些章节以"正文 "开头,需要去掉,方便下一步排除非正文部分title = list1[n][place+2:-10].replace("正文 ","") #排除非正文的部分,re.S:"."代表全部if re.match("^第.{0,6}(章|张|篇)", title, re.S) is not None:dict1["charid"] = nndict1["charurl"] = url+url1dict1["chartitle"] = titletitle_list.append(dict1)nn += 1
print(title_list)

输出结果

2. 获取每章节文本内容

2.1 循环获取指定章节文本内容,加入整个list中

章节内部格式如下,需要获取的内容在id="content"的模块中

minchar = 1
maxchar = 2
#nchar = maxchar - minchar+1
total_list = []
for n in range(minchar-1,maxchar):char_dict = title_list[n]url_n = char_dict["charurl"]headers=random.choice(headers1)r_n = requests.get(url_n, headers=headers)r_n.encoding = "utf-8"soup_n = BeautifulSoup(r_n.text, 'html.parser')text_n1= soup_n.body.find_all("div", id="content")#这里可能会因为网络或反爬虫机制原因,len(text_n1)=0,需要重试#用"<br/><br/>"转换为换行的标记,text12 = str(text_n1[0]).replace("<br/><br/>", "\n").replace('<div id="content">', '').replace('</div>', '')title_list[n]["text"] = text12print("第%d章复制完成!" % (n+1))title_list[n]["ifget"] = 1total_list.append(title_list[n])
print(total_list)

结果如下:

2.2 利用time.sleep,增加请求失败重试功能

请求失败很可能是因为请求频繁,导致请求失败,需要降低频率。
同时请求失败常常体现 在 len(text_n1)==0,在这里建立for循环重试。

import time
minchar = 1
maxchar = 200
#nchar = maxchar - minchar+1
total_list = []
for n in range(minchar-1,maxchar):char_dict = title_list[n]url_n = char_dict["charurl"]headers=random.choice(headers1)r_n = requests.get(url_n, headers=headers)r_n.encoding = "utf-8"soup_n = BeautifulSoup(r_n.text, 'html.parser')text_n1= soup_n.body.find_all("div", id="content")for nn in range(1, 3):#增加最大重试2次机制if nn == 3:print("第%d章复制失败" % (n + 1))elif len(text_n1) == 0:print("第%d章复制失败,重试第%d次......" % ((n + 1), nn))time.sleep(3)#等待三秒继续循环r_n = requests.get(url_n, headers=headers)r_n.encoding = "utf-8"soup_n = BeautifulSoup(r_n.text, 'html.parser')text_n1= soup_n.body.find_all("div", id="content")          else:text12 = str(text_n1[0]).replace("<br/><br/>", "\n").replace('<div id="content">', '').replace('</div>', '')title_list[n]["text"] = text12print("第%d章复制完成!" % (n+1))title_list[n]["ifget"] = 1total_list.append(title_list[n])time.sleep(0.5)break

效果展示:

3. 生成txt文本

拼接text内容,生成txt文本

bookname = "123"
text_final = "《"+bookname+"》第%d~%d章" % (minchar,maxchar)
path = text_final+".txt"
lenth = len(total_list)
nfailed = 0
for nnn in range(lenth):dict_n1 = total_list[nnn]if  dict_n1["ifget"] == 0:#失败部分文本用url地址代替text_final = text_final+"\n"+dict_n1["chartitle"]+"  生成失败\n链接如下:"+dict_n1["charurl"]nfailed += 1else:text_final = text_final+"\n"+dict_n1["chartitle"]+"\n"+dict_n1["text"]+"\n\n"
print(text_final)
with open(path, 'w', encoding='utf-8') as filetext:#用with方法来生成文本文件filetext.write(text_final)print("小说"+path+"已经生成,成功%d章,失败%d章" % ((lenth-nfailed),nfailed))

执行结果:

4. 重复工作模块化

将获取request请求的text内容等重复功能模块化

代码展示

# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import time
import random
import sys
import redef kanshu(url):#调用requests模块 返回html解析文本headers1 = [{'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"},{'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36 "}]headers=random.choice(headers1)r = requests.get(url, headers=headers)r.encoding = "utf-8"return r.textdef getlist(bookUrl): #获取url列表,一般只有一次total_list = []r = kanshu(bookUrl)soup = BeautifulSoup(r, 'html.parser')head_tag = soup.bodylist12 = head_tag.find_all("div", id="list")list13 = str(list12[0]).replace('<div id="list">', '').replace('<dl>', '').replace('</dl>', '').replace('</div>', '')list1 = list13.split('<dd><a href="')lenth = len(list1)nn = 1for n in range(1, lenth):dict1 = {}place= list1[n].find('">')url = list1[n][0:place]title = list1[n][place+2:-10].replace("正文 ","") #有些章节以"正文 "开头,需要去掉if re.match("^第.{0,6}(章|张|篇)", title, re.S) is not None:#排除非正文的部分,re.S:支持"."代表全部dict1["charid"] = nndict1["charurl"] = urldict1["chartitle"] = titledict1["ifget"] = 0total_list.append(dict1)nn += 1return total_listdef gettxt(bookUrl,dict12):#获取url列表r = kanshu(bookUrl=bookUrl, url1=dict12["charurl"])soup = BeautifulSoup(r, 'html.parser')text111 = soup.body.find_all("div", id="content")return text111def gettxtlist(total_list,bookUrl,minchar,nchar):for n in range(minchar,minchar+nchar):if total_list[n]["ifget"] == 0:text111 = gettxt(bookUrl, total_list[n])for nn in range(1, 3):if len(text111) == 0:#重试print("第%d章复制失败,重试第%d次......" % ((n + 1), nn))time.sleep(3)text111 = gettxt(bookUrl,total_list[n])nn += 1if nn >= 3:print("第%d章复制失败" % (n + 1))else:text12 = str(text111[0]).replace("<br/><br/>", "\n"+"").replace('<div id="content">', '').replace('</div>', '')total_list[n]["text"] = text12print("第%d章复制完成!" % (n+1))total_list[n]["ifget"] = 1time.sleep(0.5)breakreturn total_listdef getfile(bookUrl,bookname,minchar,nchar):total_list = getlist(bookUrl)print(total_list)lenth12 = len(total_list)print("本书共有%d章" % lenth12)if minchar > lenth12:print("输入的'minchar'超过最大值%d章" % lenth12)sys.exit(0)if minchar+nchar > lenth12+1:print("输入的'nchar'超过最大值,只能输出%d章" % (lenth12+1-minchar))nchar = lenth12+1-mincharminchar -= 1total_list2 = gettxtlist(total_list,bookUrl,minchar,nchar)text_final = "《"+bookname+"》第%d~%d章" % (minchar+1,minchar+nchar)path = text_final+".txt"nfailed=0for n in range(minchar,minchar+nchar):if  total_list2[n]["ifget"] == 0:text_final = text_final+"\n"+total_list2[n]["chartitle"]+"  生成失败\n链接如下:"+["charurl"]nfailed += 1else:text_final = text_final+"\n"+total_list2[n]["chartitle"]+"\n"+total_list2[n]["text"]+"\n\n"with open(path, 'w', encoding='utf-8') as filetext:filetext.write(text_final)print("小说"+path+"已经生成,成功%d章,失败%d章" % ((nchar-nfailed),nfailed))

main函数就是调用一下getfile函数

后续进阶(进行中)

  1. 优化代码,优化重试等机制。
  2. 熟悉html格式,利用bs4模块更快调用所需信息,目前用str.replace()的方法确实太low了
  3. 增加mysql对接功能,将数据存入mysql中,并自动更新指定书籍并邮件提醒更新。

python小说爬虫练习相关推荐

  1. 简单 python 小说爬虫 ultimate

    简单 python 小说爬虫 想爬就爬 带txt配置文件 day01(半成品) 划掉 - day02(成品) 书名 史上第一剑修 笔趣阁 url代码里找 ####################### ...

  2. python 小说爬虫_Python实现的爬取小说爬虫功能示例

    本文实例讲述了Python实现的爬取小说爬虫功能.分享给大家供大家参考,具体如下: 想把顶点小说网上的一篇持续更新的小说下下来,就写了一个简单的爬虫,可以爬取爬取各个章节的内容,保存到txt文档中,支 ...

  3. 小说网站竟然没有下载功能?跟小姐姐学会这个python小说爬虫,把全文小说带回家!

    hello大家好,我是你们的可爱丸,不知道你们有没有遇到过这种情况: 自己喜欢的小说竟然只能看不能下载??? 作为一个python学习者,这种情况当然不能忍,那么今天我就教大家用python写一个小说 ...

  4. python 小说爬虫_从零开始写Python爬虫 --- 1.7 爬虫实践: 排行榜小说批量下载

    从零开始写Python爬虫 --- 1.7 爬虫实践: 排行榜小说批量下载Ehco 5 个月前 本来只是准备做一个爬起点小说名字的爬虫,后来想了一下,为啥不顺便把小说的内容也爬下来呢?于是我就写了这个 ...

  5. python 小说爬虫_用Python爬虫下载整本小说

    1 / 写在前面的话 / 如今网络上很多小说网站都有免费的小说阅读,但是它不提供下载全本的服务,目的也是为了获得更多的流量,资源君就不服了,今天刚好看到一个小说网站,就想弄本小说来看看,于是拿起电脑, ...

  6. Python小说爬虫

    今天做的练习是在网站上爬虫某一部小说,并将其存入到文档中~~ 首先,按照上一次爬虫的步骤,获取到该小说目录页的url url="https://www.kanunu8.com/book2/1 ...

  7. python 小说爬虫_小说爬虫python

    在线观看多费劲呀,不如爬下来看 小说网站地址:http://www.quanshuwang.com/ 分析: 第一种方法: 首先随便打开一个小说章节详情页,比如莽荒记 发现这个详情页,居然包含了所有章 ...

  8. python小说爬虫实训报告_1.2Python网络爬虫实践(1)爬取89文学网小说

    import requests from bs4 import BeautifulSoup import time import os # 获取所有章节的链接 def get_novel_chapte ...

  9. python小说爬虫实训报告_python之新手一看就懂的小说爬虫

    晚上回来学学爬虫,记住,很多网站一般新手是爬不出来的,来个简单的,往下看: import urllib.request from bs4 import BeautifulSoup #我用的pychar ...

  10. python网络爬虫_Python爬虫实战之网络小说

    今天和大家分享的是python爬虫实战,由于本人最近迷上了看网络小说,学生党又穷,只能看看网络dao版小说,现在这类dao版小说网站可以说非常的多,但是所有的网站进去都可以看见一大把的广告信息,非常影 ...

最新文章

  1. mysql的表最多可设置多少字段?
  2. shell脚本不暂停进程,暂停几秒执行下一条shell命令
  3. OpenCASCADE:使用扩展数据交换 XDE之几何尺寸和公差 (GDT)
  4. Win7系统下共享文件夹后共享文件夹上的小锁图标取消方法
  5. 向量外积_解析几何 -向量
  6. Linux服务之nginx服务篇一(概念)
  7. python的高阶函数
  8. Python机器学习:KNN算法06网格搜索
  9. arctime工程文件怎么打开_怎么办?Vegas的项目工程文件打不开
  10. read while循环 tar脚本
  11. 理解Android的手势识别
  12. AGC020C Median Sum
  13. 加工中心宏程序c语言,加工中心最实用的宏程序
  14. PrepareStatement对象
  15. 鲁大师2022年Q1季度电动车报告:市场不断细分,产品白刃战开启
  16. PHP使用AES加密和解密
  17. 树莓派linux系统识别u盘启动,U盘安装树莓派系统,利用U盘启动Raspberry
  18. android 实现重力感应,Android重力感应实现方式是怎样实现的?
  19. C语言制作扫雷游戏(结合图形库)
  20. Matlab求一阶导数

热门文章

  1. spyder下载python3.5_ubuntu14.04 anaconda tensorflow spyder(python3.5) + opencv3
  2. bpsk调制rician_fading信道的simulink仿真
  3. k8s1.18-kubeadm安装手册
  4. 视频数据集UCF101的处理与加载(用PyTorch实现)
  5. 人体姿态识别-左肩和左肘的定位识别
  6. 机器视觉基础知识汇总
  7. python制作ppt_如何利用Excel与Python制作PPT
  8. 【经验总结—2】:深度学习数据集下载网站总结
  9. 你了解你的大脑吗?来看看脑科学如何诠释。
  10. RK系列SDK -- i2s mclk 无输出