完全小白篇-使用Python爬取网络小说

  • 一、找一个你要爬取的小说
  • 二、分析网页
    • 网页的展示方式
    • 需要用到的库文件
  • 三、向网站发送请求
  • 四、正则提取
  • 五、跳转的逻辑
  • 六、后续处理
  • 七、保存信息进入docx文件
  • 八、新的问题:超时重传

一、找一个你要爬取的小说

作为python小白,这篇博客仅作为我的一个学习记录。
本篇我就拿一个实际案例来做吧,短短50行代码调试了一晚上,爬虫还得继续好好学啊!拿最近很火的《元龙》举例。
(采用读书网的资源)

二、分析网页

网页的展示方式

打开最开始的那章,按F12看一下网页代码,首先需要注意的地方无外乎两点:

  1. 从目录的网址后面添加了一个什么编号
  2. 这个网站的网页编码格式是什么(在head标签里都能找到)
  3. 各个章节之间具有怎样的跳转关系
    跳转关系这一块,现在的小说网站已经不是按照章节+1编号也+1的方式了,所以我们可以考虑利用 a 标签里的 href="" 直接跳转
  4. 我们要提取的信息有着怎样的风格
    在下图中我们可以看到,每章标题、正文等我们要爬取的东西全部在p标签中


    非常简单的风格!(所以我才先选这个网站试手 /滑稽)

需要用到的库文件

在开始之前,先简单介绍一下这次使用到的库文件:

from bs4 import BeautifulSoup   #网页解析,数据获取
from docx import Document       #操作Word的.docx文档
import re                       #正则表达式,文字匹配
import requests                 #根据指定url获取网页数据
from requests.adapters import HTTPAdapter   #设置重传时有用
import os                       #最后用来暂停一下

emm,如果有的苦还没有安装,那就pip就好了。
在任何一处cmd窗口下输入:

pip3 install Beautifulsoup4
pip3 install docx
pip3 install re
pip3 install requests

三、向网站发送请求

接下来我们开始一步步完善我们的思路:

def main():#目录的网址baseurl = input("请输入目录列表的那个网址(例如https://www.dusuu.com/ml/1033/)\n")number = input("请打开该小说第一章,输入一下网址新增加的那个数字(例如2688178)\n")#试手,先开一下第一章试试url = baseurl+str(number)+".html"#模拟浏览器身份头向对方发送消息,不过一般的小说网站没什么反爬机制,头的话可有可无head = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"}print("已完成爬取的章节:")req = requests.get(url = url, headers = head)#上文我们已经看到是UTF-8的编码格式,这里照搬按此解析即可req.encoding = 'UTF-8'#解析得到网站的信息soup = BeautifulSoup(req.text, 'html.parser')print(soup)os.system("pause")if __name__ == "__main__":main()


很好,使我们想要的结果。soup就是一模一样的这个网站的信息

四、正则提取

  1. 标题
    提取方式:找到 div class=“bookname” 内部的 h1 标签内容
  2. 正文
    提取方式:所有的 div id=“content” style=“font-size: 24px;” 内部的所有 p 标签

这里就要使用bs4库中的搜索函数find_all(),以及re库中的提取函数.findall()
我们首先搜索所有必要的item:

for item in soup.find_all('div',class_="bookname"):item = str(item)title = re.findall(findTitle, item)[0]
for item in soup.find_all('div',id="content"):item = str(item)end = re.findall(findEnd, item)

我们定义一下提取的方式:

#创建正则表达式对象,r是为了避免对'/'的错误解析
findTitle = re.compile(r'<h1>(.*?)</h1>',re.S)
findEnd = re.compile(r'<p>(.*?)</p>',re.S)

这样,便可以将标题和正文的内容全部提取出来了

五、跳转的逻辑

现在我们完全可以处理一个网页的信息了,那么如何跳转到别的章节呢?
利用a标签“下一章”的跳转链接即可
同样,还是

for item in soup.find_all('a',id="pager_next"):item = str(item)link = re.findall(findLink, item)[0]url = "https://www.dusuu.com" + str(link)

正则对象(规则)为:

findLink = re.compile(r'<a class="next" href="(.*?)" id="pager_next" target="_top">下一章</a>')

六、后续处理

现在的代码段为:

from bs4 import BeautifulSoup   #网页解析,数据获取
from docx import Document       #操作Word的.docx文档
import re                       #正则表达式,文字匹配
import requests                 #根据指定url获取网页数据
from requests.adapters import HTTPAdapter   #设置重传时有用
import os                       #最后用来暂停一下findTitle = re.compile(r'<h1>(.*?)</h1>',re.S)
findEnd = re.compile(r'<p>(.*?)</p>',re.S)
findLink = re.compile(r'<a class="next" href="(.*?)" id="pager_next" target="_top">下一章</a>')def main():baseurl = input("请输入目录列表的那个网址(例如https://www.dusuu.com/ml/1033/)\n")number = input("请打开该小说第一章,输入一下网址新增加的那个数字(例如2688178)\n")url = baseurl+str(number)+".html"link = ""head = {    #模拟浏览器身份头向对方发送消息"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"}print("已完成爬取的章节:")#最后一章中,点击“下一章”会回到目录那里while(link!="/ml/10942/"):req = requests.get(url = url, headers = head)req.encoding = 'UTF-8'soup = BeautifulSoup(req.text, 'html.parser')for item in soup.find_all('div',class_="bookname"):item = str(item)title = re.findall(findTitle, item)[0]print(title)for item in soup.find_all('div',id="content"):item = str(item)end = re.findall(findEnd, item)#每章最后一句正文都是网站的广告,我们不要那个for i in range(len(end)):if(i==(len(end)-1)):end[i]="\n"print(end)#跳转到下一页for item in soup.find_all('a',id="pager_next"):item = str(item)link = re.findall(findLink, item)[0]url = "https://www.dusuu.com" + str(link)os.system("pause")if __name__ == "__main__":main()


程序本身已经完全可以将各个章节打印了

七、保存信息进入docx文件

其实每获得一次title,每获得一次end,就完全可以对一个docx文档进行写标题、写段落操作了
这里提示几个操作的docx文档的必要语法:

  1. 库函数:from docx import Document
  2. 创建一个文档对象:Doc = Document()
  3. 写标题操作:Doc.add_heading(title, level = 0)
    注意,level从0到5是一级标题–>六级标题
  4. 写段落操作:Doc.add_paragraph()

八、新的问题:超时重传

在完成一系列操作后,我在运行时,前几章是完全没有问题的。然而,随着章节增加以及访问次数的增加,出现了一个新的问题:访问无限超时。可能是每个小说网站都存在这个问题,连续高频访问可能就会在某次访问突然“掉线”
查了很多方法,在这里总结一下各个比较通用的方法以及效果:

  1. 全局设置Socket超时时长:
    在全局设置:
import socket
socket.setdefaulttimeout(time_len)

但是确实,效果不明显,当章节多了仍然会无限超时

  1. 设置DNS
    比如,将本地的DNS优先设置为阿里的,或者腾讯、百度的公用DNS,效果是有的,但事实上是超时的出现减少了,当超时出现时仍然无法得到解决

  2. 超时重传
    有点综合以上两种方法。查了很多,但是可能是需要一定基础的,诸如retry()等。
    这里我采用了最基础的try:
    首先增加一个库:from requests.adapters import HTTPAdapter
    在我们的函数中,req这个变量进行一些新的设置:

req=requests.Session()
#访问https协议时,设置重传请求最多3次
req.mount('https://',HTTPAdapter(max_retries=3))

另外,对于req设置超时时长:

#5s的超时时长设置
req = requests.get(url = url, headers = head, timeout=5)

如果超时,打印错误:

except requests.exceptions.RequestException as e:print(e)

总代码如下:

from bs4 import BeautifulSoup   #网页解析,数据获取
from docx import Document
import os
import re                       #正则表达式,文字匹配
import requests
from requests.adapters import HTTPAdapterfindTitle = re.compile(r'<h1>(.*?)</h1>',re.S)
findEnd = re.compile(r'<p>(.*?)</p>',re.S)
findLink = re.compile(r'<a class="next" href="(.*?)" id="pager_next" target="_top">下一章</a>')def main():baseurl = input("请输入目录列表的那个网址(例如https://www.dusuu.com/ml/1033/)\n")# https://www.dusuu.com/ml/10942/Doc = Document()number = input("请打开该小说第一章,输入一下网址新增加的那个数字(例如2688178)\n")#2622647savepath = "./"+input("请为你的docx文档命名:")+".docx"url = baseurl+str(number)+".html"link = ""req=requests.Session()req.mount('https://',HTTPAdapter(max_retries=3))head = {    #模拟浏览器身份头向对方发送消息"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"}print("已完成爬取的章节:")while(link!="/ml/10942/"):try:req = requests.get(url = url, headers = head, timeout=5)req.encoding = 'UTF-8'soup = BeautifulSoup(req.text, 'html.parser')for item in soup.find_all('div',class_="bookname"):item = str(item)title = re.findall(findTitle, item)[0]print(title)Doc.add_heading(title, level = 0)for item in soup.find_all('div',id="content"):item = str(item)end = re.findall(findEnd, item)for i in range(len(end)):if(i==(len(end)-1)):end[i]="\n"Doc.add_paragraph(end[i])Doc.save(savepath)#跳转到下一页for item in soup.find_all('a',id="pager_next"):item = str(item)link = re.findall(findLink, item)[0]url = "https://www.dusuu.com" + str(link)except requests.exceptions.RequestException as e:print(e)os.system("pause")if __name__ == "__main__":main()

好吧,免费获得了一个4.5MB的.docx文档,以后不用再上网看这部小说了!
当然,针对这个程序的话,读书网的所有小说都可以爬了。
(其实我还是得上网看,800多章还是直接用目录跳转方便)
不过,学习为主,又获得一项用50行代码在别人面前秀一秀的技能。

完全小白篇-使用Python爬取网络小说相关推荐

  1. 完全小白篇-用python爬取豆瓣电影影评

    完全小白篇-用python爬取豆瓣影评 打开豆瓣电影 随机电影的所有影评网页 跳转逻辑 分析影评内容获取方法 逐一正则提取影评 针对标签格式过于多样的处理 针对提出请求的频率的限制 存储方式(本次sq ...

  2. python爬取小说写入txt_燎原博客—python爬取网络小说存储为TXT的网页爬虫源代码实例...

    python是一门优秀的计算机编程语言,两年前曾因为动过自动化交易的念头而关注过它.前几天在微信上点了个python教学的广告,听了两堂课,所以现在又热心了起来,照葫芦画瓢写了一段简单的网络爬虫代码, ...

  3. 【爬虫实战】手把手教你使用python爬取网络小说

    文章目录 写作缘起 上代码 思路分析 效果展示 写在最后 写作缘起 南墙最近发现自己常用的看小说网站多了许多广告,果然商业化的现今网上几无净土啊,便决定自己写个小说下载器,这样看小说贼爽 上代码 im ...

  4. python爬取网络小说_Python爬取起点中文网月票榜前500名网络小说介绍

    观察网页结构 进入起点原创风云榜:http://r.qidian.com/yuepiao?chn=-1 老套路,懂我的人都知道我要看看有多少内容和页数需要爬. https://ask.hellobi. ...

  5. Python爬虫之爬取网络小说并在本地保存为txt文件

    Python爬虫之爬取网络小说并在本地保存为txt文件 注:本文使用软件为Sublime Text,浏览器为谷歌浏览器 (新手小白第一次写,写得不好请见谅) **1.**首先找到想要爬取的小说章节目录 ...

  6. python爬虫下载小说_用PYTHON爬虫简单爬取网络小说

    用PYTHON爬虫简单爬取网络小说. 这里是17K小说网上,随便找了一本小说,名字是<千万大奖>. 里面主要是三个函数: 1.get_download_url() 用于获取该小说的所有章节 ...

  7. Python爬虫练习 爬取网络小说保存到txt

    原文链接:https://yetingyun.blog.csdn.net/article/details/107916769 创作不易,未经作者允许,禁止转载,更勿做其他用途,违者必究. 利用 Pyt ...

  8. 用PYTHON爬虫简单爬取网络小说

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取 python免费学习资 ...

  9. python爬取小说写入txt_Python爬虫练习 爬取网络小说保存到txt

    利用python爬虫爬取网络小说保存到txt,熟悉利用python抓取文本数据的方法. 选取其中某一章,检查网页,可以找到这本小说所有章节的链接和名称. 写出xpath表达式提取出href里的内容:/ ...

最新文章

  1. Apache Tomcat 文件包含漏洞(CVE-2020-1938)
  2. 2011年中国网络游戏市场实际销售收入达到428.5亿元
  3. BeautifulSoup库使用
  4. 面试无忧之Zookeeper总结心得
  5. SGU 117 Counting
  6. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 14丨重新格式化部门表【难度中等】
  7. java list 初始化_Java面试大全(十)
  8. 消息称小米之家全面取消员工销售提成 回应:内容严重偏颇失实
  9. Linux linux下的进程状态
  10. java打印unicode_java程序实现Unicode码和中文互相转换
  11. 完全关闭App的两种做法
  12. ASP.NET MVC Model验证
  13. 检测CCD Dead Pixel
  14. 计算机boot进入u盘启动,电脑boot设置U盘启动项具体方法
  15. 小程序自定义下拉刷新
  16. 后端返回文件流PDF文件前端如何实现下载/在线打开
  17. K - Tourists' Tour(图染色)
  18. vue 微信公众号获取定位经纬度 腾讯地图逆地址解析为具体地址
  19. 8g内存学习计算机专业够吗,现在电脑内存一般多大_现在电脑内存8个g够吗
  20. 解决Google Colab 读取Google Drive(云盘) 文件速度慢

热门文章

  1. 关于基金的各种名词含义及来源,小白如何入门基金
  2. PMP考后需要做什么?考生须知
  3. 机器学习面试150题(2020):不只是考SVM xgboost 特征工程
  4. 看懂了一点傅里叶变换的原理
  5. 6个方法,用博客建立你的个人“品牌”
  6. 短视频App对比分析报告
  7. JQUREY DOM 操作详解
  8. 云栖大会人脸识别闸机【技术亮点篇6】--人脸识别闸机采用活体检测技术
  9. 计算机配件对比,如何挑选配件,组装电脑?
  10. Python3.6新特性(部分)