平时有没有和我一样喜欢看小说的小伙伴,在用网页看小说的时候经常会忘了小说的地址,或者是被网页上的垃圾广告所干扰误触点了进去。今天我们来抓取一整部小说文本
1.对页面进行分析,构思思路
1.首先找到我们要的小说网站,打开页面
#https://wujixsw.com/2_2166/,通过开发者模式可以找到小说内容那就说明在元源码中,这样一般就比较容易获得可以抓取这一页的全部内容,可是我们要抓的是一整部小说
2.对每一章的小说页面发起请求,然后分别抓取内容
理论成立,实践开始
本教程所有配套资料索取方式如下:点赞三连后Q裙搜索:652892456找管理员获取(或直接加小助理微信:python5180 ){备注:UR的出不克}
学习或其他资料也可+Q群:652892456,告别孤单,共同进步!
2.抓取一章小说
打开任意一章小说,查看我们要抓取的文本所在位置f12打开开发者模式,通过元素查找找到了小说文本所在的位置【id="content"】
可以看到小说内容都在这个属性下 ,所以我们可以通过这个属性来定位
使用requests对网站进行请求
import requests # 导入模块
url = 'https://wujixsw.com/2_2166/1772366.html'
head = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'
}
res = requests.get(url,headers=head)
print(res.text)
会发现请求到了网页,我们来看一下,出现的是一堆我们看不懂的东西,没有我们想要的文章
这是因为网页有编码,不同的编码器只能识别自己的编码 #就好像我看英语似的
<a href="/137_137824/">太å¤ç¬¬ä¸åä»</a>ã
<a href="/137_137732/">éé¥ä»å»äººé´é</a>ã
<a href="/137_137847/">ä¸å¿µåè±å¼</a>ã
<a href="/137_137844/">æç´æé®ç社æ»äºè¯¸å¤©ç¾¤è±ª</a>ã
<a href="/137_137863/">å¹³Aæ³å¸</a>ã
<a href="/137_137843/">é天ä¸å</a>ã
<a href="/137_137799/">é诡å¼ä¸ï¼ææ»åå为éç¥</a>ã
<a href="/137_137738/">å°ä¸ä¹ä¸</a>ã
<a href="/137_137761/">æ´åç»å¾¡æ ä¸ç¥æ</a>ã
</div>
<div class="footer_cont">
<p>æ¬ç«ææå°è¯´ä¸ºè½¬è½½ä½åï¼ææç« èåç±ç½åä¸ä¼ ï¼è½¬è½½è³æ¬ç«åªæ¯ä¸ºäºå®£ä¼ æ¬ä¹¦è®©æ´å¤è¯»è欣èµã</p>
<p>Copyright © 2017 æ æå°è¯´ All Rights Reserved. </p>
<script>tj();</script>
</div>
我们只需要加一个编码就行了,这样我们输出出来的就是正常的文字了
常见的编码方式有两种,一是“utf-8”
量一种是“gbk”格式,这两种格式都是国标
url = 'https://wujixsw.com/2_2166/1772366.html'
head = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'
}
res = requests.get(url,headers=head)
res.encoding='utf-8'
print(res.text)
我获取到了网页源码,也看到了想要的文字在源码中,下一步就是用正则表达式来筛选我们想要的文字了
我们使用findall方法来筛选数据关于正则的使用方法下一期会专门讲一期的
ree = re.findall(r'<div id="content" deep="3">(.*?)<div align="center">',res.text,re.S)
这里我们把文本上下的范围规定一下,然后把我们想要的数据用(。*?)来代替,这样我们输出的时候输出的就是括号内的内容了
我们来查看一下结果,可以看到有很多的杂乱信息,再次进行筛选
#注意:输出出来的是list,而正则筛选要的是str,所以要先进行一个转换成str
><br /> 校门外,挤满了撑着雨伞的家长,他们被雨水淋湿的脸上满是期望。<br /><br /> 今天可是他们孩子的升学大事啊,能不能上天澜魔法高中,能不能将来考上一个好大学就看孩子今日的表现了!<br /><br /> 你没看错。<br /><br /> 就是魔法高中!<br /><br /> 这个社会,魔法为尊!<br /><br /> 所有的孩子都需要接受九年义务魔法教育,学完九年魔法基础理论与魔法生活技能之后,都将接受和中考一样的考试,考试过的人,才能够进入魔法高中,成为一名真正的魔法师!<br /><br /> ……<br /><br /> 桂花被雨水打落在校园笔直的道路上,铃声响起之后,学生们蜂拥而出,要么独行,要么寻找着自己的小伙伴,讨论着今日的考试内容。<br /><br /> “喂,慕白,元素魔法的七系,冰系火系土系水系风系光系雷系,这道题你们做出来了吗?”一名戴着小领结的白脸男生问道。<br /><br /> “完美解答!”那个无论是发型身高长相都堪称男神的慕白说道。<br /><br /> “不愧是我们的尖子生,这么难的混系问题都能够做出来……咦,那不是模拟考上只靠了个6分的莫凡吗?”满脸麻子的赵坤三说道。<br /><br /> 男神慕白眼睛马上不屑的瞥了一眼那个独自一人打伞的少年,道:“这家伙马上要跟他老爸一样,当一个破皮卡车采购员了。”<br /><br /> “那不就是你们穆家的仆人了吗,哈哈哈!”<br /><br /> 这三人说话很放肆,根本就不怕旁边的那个叫做莫凡的少年听见。<br /><br /> 嘲笑完之后,这三人自顾大摇大摆的离开了,显然他们有足够的信心能够考上魔法高中。<br /><br /> ……<br />
我们只需要其中的汉字部分,所以把汉字部分用(。*?)来代替
ree1 = re.findall(r'<br /> (.*?)<br />',aa,re.S)
再次输出ree1,果然没有了那些烦人的无用信息
3.对整部小说进行抓取
先看一眼每一章小说的URL变化,这是123章的链接,并没有什么规律可以用
所以我们对小说首页来抓取源码,提取每一章的链接再进行请求
打开开发者模式,查看元素
在这里没有唯一且确定的位置,但是我们可以用它本身来定位,找到第一章和最后一章中间用(。*?)来代替在输出就行了
接下来再次发送请求,看看小说首页的源码
url1 = 'https://wujixsw.com/2_2166/'
head = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'
}
res1 = requests.get(url1,headers=head)
res1.encoding='utf-8'
print(res1.text)
我们可以看到每一章节的链接和标题了,看到了这样的排列就容易提取了不用上面的那么复杂了
直接提取href属性,拼接到链接上,再把小说标题写到文件内
使用正则表达式来提取href和标题是这样的
ree = re.findall(r'<dd> <a style="" href="(?P<lianjie>.*?)">(?P<title>.*?)</a></dd>',res1.text,re.S)
输出一下,完美得到了每一章的链接和内容
2.代码整合并将小说内容以小说章节为标题分别储存
import requests # 导入模块
import re
url1 = 'https://wujixsw.com/2_2166/'
head = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'
}
res1 = requests.get(url1,headers=head)
res1.encoding='utf-8'
#print(res1.text)
ree = re.findall(r'<dd> <a style="" href="(?P<lianjie>.*?)">(?P<title>.*?)</a></dd>',res1.text,re.S)
for aa,bb in ree[13:]:
url = 'https://wujixsw.com'+aa
res = requests.get(url,headers=head)
res.encoding='utf-8'
#print(res.text)
ree = re.findall(r'<div id="content" deep="3">(.*?)<div align="center">',res.text,re.S)
aa = str(ree)
ree1 = re.findall(r'<br /> (.*?)<br />',aa,re.S)
ree1 = str(ree1)
#print(ree1,bb)
with open('D:\python\爬虫练习库\下载小说文件\下载小说文件\小说'+str(bb)+".txt","a+")as f:
f.write(ree1)
print(bb,"下载完成")
print('全部小说下载完成')
#注意更改自己的储存位置