一、前言
通常而言, 被称作网路爬虫所爬取的事物, 大致上也就是这四种, 分别是文字, 还有图片, 以及音乐, 再就是视频。
这是在明面上, 所能想到的事物, 除开这些内容以外, 还存在一些危险性质的操施作办, 是着实容易因而被请去喝茶的, 对此现暂且不予讨论了。
咱们循序渐进,先谈谈如何下载文字内容。
PS:文中出现的所有代码,均可在我的 上下载:点击查看
二、诡秘之主
说到下载文字内容,第一个想到的就是下载小说了。
在曾以《一念永恒》这部小说当作例子来开展讲解的CSDN之文章里, 存在网友留言称:
那么,今天我就再安利一本小说《诡秘之主》。
起点中文网,它的月票基本是月月第一。
这篇文章实际上是在传授众人怎样能够不花钱而获取, 然而具备支持正版能力的友人, 还是能够前往起点中文网, 去对作者予以支持的, 毕竟创作是不容易的。
三、准备工作
话不多说,直接进入我们今天的正题,网络小说下载。
1、背景介绍
小说网站,“新笔趣阁”:
好多是盗版小说网站, 以前爬过“笔趣看”, 这次咱换一家, 去爬“新笔趣阁”, 要雨露均沾呀!
“新笔趣阁”仅能在线浏览, 无法进行小说打包下载。此次实战会教大家怎样“优雅”地去下载一篇名为《诡秘之主》的网络小说。
2、爬虫步骤
要想把大象装冰箱,总共分几步?
要想爬取数据,总共分几步?
爬虫其实很简单,可以大致分为三个步骤:
发起请求,我们就用 就行,上篇文章已经介绍过。
进行解析数据的工具存在着许多, 举例来说, 像是xpath这样的, 还有Soup这种的, 以及正则表达式这类的等等。在本文当中, 将会运用一个具备简单特性的经典小型工具, 也就是Soup来开展数据解析工作。
保存数据,就是常规的文本保存。
3、 Soup
简而言之, Soup属于那种第三方库, 其主要的作用在于帮我们对网页数据予以解析。
在运用该工具之前, 我们得先进行安装操作, 于 cmd 当中, 借助 pip 或将其安装便可。
pip install beautifulsoup4 # 或者 easy_install beautifulsoup4安装完毕之后, 我们仍旧需要进行 lxml 的安装, 而这乃是解析 HTML 之时所必然要用到的依赖。
pip install lxmlSoup的使用办法同样不复杂, 能够瞧瞧我于CSDN的解说或者官方教程去学习, 具体的使用办法:
我的 Soup 讲解:点击查看
官方中文教程:点击查看
四、小试牛刀
我们先看下《诡秘之主》小说的第一章内容。
URL:
先来尝试一下, 运用我们已然学到的知识, 去获取 HTML 信息, 代码编写如下:
import requests if __name__ == '__main__': target = 'https://www.xsbiquge.com/15_15338/8549128.html' req = requests.get(url = target) req.encoding = 'utf-8' print(req.text)这也就是爬虫的第一步“发起请求”,得到的结果如下:
能看到, 我们极为轻易地取得了 HTML 信息, 其中存在我们所期望的小说正文部分, 可其同时也涵盖了一些其余内容, 而div、br 这些 HTML 标签, 我们并非予以关注。
如何把正文内容从这些众多的 HTML 标签中提取出来呢?
这便要求开展爬虫中的第二步“解析数据”, 此步骤具体而言就是运用Soup着手进行解析。
此刻, 咱们运用上篇文章所阐述的审查元素办法, 去查看一番我们的目标页面, 你能够看到如下这般的内容:
很难察觉不到, 文章里的全部内容都被放置于一个称作div的“那边之下”, 这个“处子”便是HTML标签, HTML标签属于HTML语言里最为基础的单元, HTML标签是HTML最为关键的构成部分, 不明白, 没什么关系, 我们再列举一个简易的事例:
会将诸多东西放置于包内的女人, 会依据个人习惯来分类搁放亲手之物。镜子、口红等常用之物, 会被归置到易于拿取的外侧口袋。证件这类不常使用且需留神安全存放之物, 则会被安置在不易拿到的里侧口袋。
HTML标签如同一个个 “口袋”, 每个 “口袋” 具备自身特定功能, 负责放置不同内容。显然, 上述例子里的div标签下放置了我们所关心的正文内容。这个div标签是如此这般的:
可能细心的朋友已然发现, 除了div字样之外, 还有id。id属于div标签的属性, 是属性值而言, 一个属性会对应着一个属性值。
用什么来区分众多的div标签, 是属性, 它有什么作用, 因为div标签数量众多, id可被看作是此div的身份。
存在这样一个div标签, 其id属性既定, 在这个div标签里头, 所存放的正是我们期望获取的内容, 凭借这一方面, 我们能够借助Soup去提取我们所需要的正文内容, 代码编写情况如下:
import requests from bs4 import BeautifulSoup if __name__ == '__main__': target = 'https://www.xsbiquge.com/15_15338/8549128.html' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bs = BeautifulSoup(html, 'lxml') texts = bs.find('div', id='content') print(texts)代码称得上简单至极, bf.find('div', id='')所具备的意思乃为, 寻得那有着id属性为的div标签语句。
能够发现, 正文部分的内容已然顺利地被提取出来, 然而其中仍然存在一些诸如div以及br这样类型的标签, 我们需要进行进一步的数据清洗这项操作。
import requests from bs4 import BeautifulSoup if __name__ == '__main__': target = 'https://www.xsbiquge.com/15_15338/8549128.html' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bs = BeautifulSoup(html, 'lxml') texts = bs.find('div', id='content') print(texts.text.strip().split('\xa0'*4))首先采用 texts.text 提取全部文字, 接着运用 strip 方法去除回车, 随后借助 split 方法依据\xa0 切分数据, 此为因每一段开头皆存在四个空格。
程序运行结果如下:
所有的内容,已经清洗干净,保存到一个列表里了。
小说正文, 已然顺利获取到手了。若要下载整部小说, 我们就得获取每一个章节的链接。我们先针对小说目录予以分析:
URL:
经过审查元素的操作之后, 我们并非难以发觉, 所有那些章节方面的信息, 全都被存放于了有着id属性为list的div标签下面的a标签内部, 进而编写像下面这样的代码:
import requests from bs4 import BeautifulSoup if __name__ == '__main__': target = 'https://www.xsbiquge.com/15_15338/' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bs = BeautifulSoup(html, 'lxml') chapters = bs.find('div', id='list') chapters = chapters.find_all('a') for chapter in chapters: print(chapter)将 bf.find('div', id='list') 理解为去寻觅那 id 属性设定为 list 的 div 标签, 将.('a') 理解为于寻得的 div 标签之中, 再度去提取出全部的 a 标签, 进而能够得出如下这般的运行结果:
能够看到, 章节链接以及章节名, 我们已然提取出来, 然而, 还需要作进一步的解析, 编写像下面这样的代码:
import requests from bs4 import BeautifulSoup if __name__ == '__main__': server = 'https://www.xsbiquge.com' target = 'https://www.xsbiquge.com/15_15338/' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bs = BeautifulSoup(html, 'lxml') chapters = bs.find('div', id='list') chapters = chapters.find_all('a') for chapter in chapters: url = chapter.get('href') print(chapter.string) print(server + url)能够瞧见, .get(‘href’)法子提取出了href 属性, 且以此拼接成了章节的url, 运用.方法提取出了章节名。
存在着每个章节的链接, 有着章节名, 具备了章节内容。接下来所要着手进行的事情便是整合代码, 把内容保存到txt这个文件里面即可。然后编写的代码如下:
import requests import time from tqdm import tqdm from bs4 import BeautifulSoup def get_content(target): req = requests.get(url = target) req.encoding = 'utf-8' html = req.text bf = BeautifulSoup(html, 'lxml') texts = bf.find('div', id='content') content = texts.text.strip().split('\xa0'*4) return content if __name__ == '__main__': server = 'https://www.xsbiquge.com' book_name = '诡秘之主.txt' target = 'https://www.xsbiquge.com/15_15338/' req = requests.get(url = target) req.encoding = 'utf-8' html = req.text chapter_bs = BeautifulSoup(html, 'lxml') chapters = chapter_bs.find('div', id='list') chapters = chapters.find_all('a') for chapter in tqdm(chapters): chapter_name = chapter.string url = server + chapter.get('href') content = get_content(url) with open(book_name, 'a', encoding='utf-8') as f: f.write(chapter_name) f.write('\n') f.write('\n'.join(content)) f.write('\n')在下载的进程当中, 我们借助了 tqdm 来展现下载的进度情况, 从而使下载过程具备了更为像那么回事儿且令人看着舒坦的特质, 要是尚未装 tqdm 的话, 可以采用 pip 去完成安装, 其运行所呈现出来的效果是:
能瞧见, 小说的内容被存进了“诡秘之主.txt”里头, 这本小说拥有总共 1416 章, 其下载所需时间大概是 20 分钟, 并且每秒大约能下载 1 个章节。
下载完成,实际花费了 27 分钟。
二十多分钟去下载一本小说, 你或许会觉得速度太慢了。要是想提升速度, 能够运用多进程, 从而大幅加快下载速度。要是采用分布式, 甚至能够在一秒钟之内就完成下载。
但是,我不建议这样做。
我们需成为一个友善的爬虫, 若我们进行提速, 那我们所访问的服务器便会面临更大的压力。
拿我们此次下载小说的代码当作例子, 每一秒钟会下载 1篇章节目录, 服务器所承受的压力大概是 1qps, 其意思是, 在这一秒钟里会进行1次请求。
要是在 1 秒的时间里, 我们同时进行 1416 个章节的下载操作, 那么服务器就会承受大概 1416 qps 的压力, 而这还仅仅只是你所发出的并发请求数量, 要是再把其他用户的请求加算进去, 并发量或许会更多。
要是服务器出现资源不足的状况, 这般的并发量能够在瞬间把服务器给“弄死”, 尤其是某些小网站, 通通都很脆弱。
拥有过大并发量的爬虫程序, 这等同于发起了一场 CC 攻击, 并非所有网站都有着承受百万级别并发量这种能力存在的。
所以, 去写爬虫的时候, 必须一定要无比小心谨慎, 千万不要给服务器增添过多的压力 , 要达成满足我们获取数据的需求这样的情况 , 这就足够。你好,我也好,大家好才是真的好。zj9.WmoPh.cN
5yb.WmoPh.cN
ik7.WmoPh.cN
c29.WmoPh.cN
jhm.WmoPh.cN
6a7.WmoPh.cN
oop.WmoPh.cN
62y.WmoPh.cN
8h4.WmoPh.cN
qg7.WmoPh.cN
a1t.WmoPh.cN
3dm.WmoPh.cN
uh5.WmoPh.cN
4kd.WmoPh.cN
y69.WmoPh.cN
r9r.WmoPh.cN
q7x.WmoPh.cN
zny.WmoPh.cN
rl5.WmoPh.cN
sec.WmoPh.cN
wv4.WmoPh.cN
kix.WmoPh.cN
ctp.WmoPh.cN
rd2.WmoPh.cN
5pu.WmoPh.cN
2xn.WmoPh.cN
h7e.WmoPh.cN
4y0.WmoPh.cN
nvi.WmoPh.cN
zxc.WmoPh.cN
ole.WmoPh.cN
llc.WmoPh.cN
8ci.WmoPh.cN
cba.WmoPh.cN
sdp.WmoPh.cN
9b3.WmoPh.cN
l0f.WmoPh.cN
211.WmoPh.cN
uj8.WmoPh.cN
lqd.WmoPh.cN
wxk.WmoPh.cN
y2y.WmoPh.cN
rvb.WmoPh.cN
cli.WmoPh.cN
g52.WmoPh.cN
ff3.WmoPh.cN
maj.WmoPh.cN
kdn.WmoPh.cN
hp0.WmoPh.cN
i4b.WmoPh.cN
kkk.WmoPh.cN
f0b.WmoPh.cN
ci9.WmoPh.cN
fwr.WmoPh.cN
c45.WmoPh.cN
908.WmoPh.cN
0y6.WmoPh.cN
1cj.WmoPh.cN
2uo.WmoPh.cN
vkp.WmoPh.cN
d4n.WmoPh.cN
yki.WmoPh.cN
42d.WmoPh.cN
p0i.WmoPh.cN
51g.WmoPh.cN
v47.WmoPh.cN
ugr.WmoPh.cN
1dh.WmoPh.cN
kdr.WmoPh.cN
1xn.WmoPh.cN
pey.WmoPh.cN
gmo.WmoPh.cN
91q.WmoPh.cN
goa.WmoPh.cN
n5k.WmoPh.cN
rsu.WmoPh.cN
bb7.WmoPh.cN
sqe.WmoPh.cN
afl.WmoPh.cN
8yl.WmoPh.cN
7su.WmoPh.cN
x09.WmoPh.cN
ecj.WmoPh.cN
66t.WmoPh.cN
wxt.WmoPh.cN
bk6.WmoPh.cN
gd2.WmoPh.cN
6wj.WmoPh.cN
hoi.WmoPh.cN
r59.WmoPh.cN
67u.WmoPh.cN
fr4.WmoPh.cN
su7.WmoPh.cN
cxg.WmoPh.cN
1uy.WmoPh.cN
xmh.WmoPh.cN
2q9.WmoPh.cN
31x.WmoPh.cN
2rb.WmoPh.cN
p3d.WmoPh.cN
iim.WmoPh.cN
d6z.WmoPh.cN
7uj.WmoPh.cN
h4h.WmoPh.cN
0c4.WmoPh.cN
wcp.WmoPh.cN
8bw.WmoPh.cN
oki.WmoPh.cN
7wy.WmoPh.cN
q8u.WmoPh.cN
fdn.WmoPh.cN
9l3.WmoPh.cN
m7j.WmoPh.cN
mj2.WmoPh.cN
jpy.WmoPh.cN
hfj.WmoPh.cN
7vv.WmoPh.cN
dzn.WmoPh.cN
go5.WmoPh.cN
lng.WmoPh.cN
m47.WmoPh.cN
jkd.WmoPh.cN
anh.WmoPh.cN
xh4.WmoPh.cN
dxr.WmoPh.cN
t41.WmoPh.cN
28t.WmoPh.cN
3pn.WmoPh.cN
7jg.WmoPh.cN
ed1.WmoPh.cN
q1g.WmoPh.cN
wt5.WmoPh.cN
xbl.WmoPh.cN
9ga.WmoPh.cN
9ef.WmoPh.cN
ise.WmoPh.cN
lg3.WmoPh.cN
he3.WmoPh.cN
uic.WmoPh.cN
2p1.WmoPh.cN
n6y.WmoPh.cN
303.WmoPh.cN
lxh.WmoPh.cN
6c0.WmoPh.cN
sg7.WmoPh.cN
63d.WmoPh.cN
zov.WmoPh.cN
s54.WmoPh.cN
7gr.WmoPh.cN
rbq.WmoPh.cN
lxy.WmoPh.cN
hrl.WmoPh.cN
q3q.WmoPh.cN
5h5.WmoPh.cN
gpk.WmoPh.cN
86d.WmoPh.cN
aoa.WmoPh.cN
293.WmoPh.cN
jh1.WmoPh.cN
i7g.WmoPh.cN
i9t.WmoPh.cN
t00.WmoPh.cN
pew.WmoPh.cN
3ym.WmoPh.cN
edv.WmoPh.cN
phq.WmoPh.cN
4xf.WmoPh.cN
zbj.WmoPh.cN
02r.WmoPh.cN
ikh.WmoPh.cN
k2t.WmoPh.cN
tge.WmoPh.cN
m06.WmoPh.cN
hqy.WmoPh.cN
3lp.WmoPh.cN
490.WmoPh.cN
zto.WmoPh.cN
8vq.WmoPh.cN
jn0.WmoPh.cN
g98.WmoPh.cN
iwu.WmoPh.cN
em0.WmoPh.cN
olf.WmoPh.cN
q96.WmoPh.cN
di8.WmoPh.cN
udj.WmoPh.cN
zyz.WmoPh.cN
rls.WmoPh.cN
jy1.WmoPh.cN
obf.WmoPh.cN
jkn.WmoPh.cN
qs9.WmoPh.cN
9nm.WmoPh.cN
7pw.WmoPh.cN
oj5.WmoPh.cN
pzw.WmoPh.cN
n5j.WmoPh.cN
r1k.WmoPh.cN
qpd.WmoPh.cN
jf7.WmoPh.cN
6go.WmoPh.cN
5yh.WmoPh.cN
z7f.WmoPh.cN
3lt.WmoPh.cN
egg.WmoPh.cN
579.WmoPh.cN
qhz.WmoPh.cN
8rr.WmoPh.cN
8zv.WmoPh.cN
hga.WmoPh.cN
08m.WmoPh.cN
bno.WmoPh.cN
ec8.WmoPh.cN
xto.WmoPh.cN
87k.WmoPh.cN
4hd.WmoPh.cN
3sf.WmoPh.cN
ows.WmoPh.cN
nu4.WmoPh.cN
h9p.WmoPh.cN
hkq.WmoPh.cN
hhm.WmoPh.cN
mxn.WmoPh.cN
bl3.WmoPh.cN
7jm.WmoPh.cN
x7b.WmoPh.cN
y6x.WmoPh.cN
90o.WmoPh.cN
1j3.WmoPh.cN
wsx.WmoPh.cN
a0i.WmoPh.cN
b6t.WmoPh.cN
rdm.WmoPh.cN
yz9.WmoPh.cN
3b9.WmoPh.cN
6ta.WmoPh.cN
kdl.WmoPh.cN
ulg.WmoPh.cN
h43.WmoPh.cN
9qb.WmoPh.cN
1k0.WmoPh.cN
zs7.WmoPh.cN
oai.WmoPh.cN
qez.WmoPh.cN
4ex.WmoPh.cN
iy8.WmoPh.cN
wqq.WmoPh.cN
8ky.WmoPh.cN
vw1.WmoPh.cN
d4u.WmoPh.cN
ygx.WmoPh.cN
a1g.WmoPh.cN
nkw.WmoPh.cN
f8z.WmoPh.cN
61j.WmoPh.cN
21c.WmoPh.cN
z23.WmoPh.cN
l4r.WmoPh.cN
ddp.WmoPh.cN
4sk.WmoPh.cN
bto.WmoPh.cN
1h1.WmoPh.cN
0ko.WmoPh.cN
b7w.WmoPh.cN
ims.WmoPh.cN
0cj.WmoPh.cN
qzb.WmoPh.cN
um5.WmoPh.cN
6wu.WmoPh.cN
d4j.WmoPh.cN
rri.WmoPh.cN
qdv.WmoPh.cN
eu0.WmoPh.cN
mc6.WmoPh.cN
ezs.WmoPh.cN
bnf.WmoPh.cN
dsx.WmoPh.cN
qgz.WmoPh.cN
l20.WmoPh.cN
s4x.WmoPh.cN
dcq.WmoPh.cN
0dv.WmoPh.cN
kgd.WmoPh.cN
3u6.WmoPh.cN
f41.WmoPh.cN
pl9.WmoPh.cN
qwm.WmoPh.cN
6j2.WmoPh.cN
4cc.WmoPh.cN
v4b.WmoPh.cN
90m.WmoPh.cN
wpd.WmoPh.cN
12k.WmoPh.cN
hih.WmoPh.cN
q17.WmoPh.cN
e7l.WmoPh.cN
b30.WmoPh.cN
5uv.WmoPh.cN
mlo.WmoPh.cN
7ed.WmoPh.cN
nnb.WmoPh.cN
kvb.WmoPh.cN
gqe.WmoPh.cN
hgq.WmoPh.cN
s6e.WmoPh.cN
q07.WmoPh.cN
o9d.WmoPh.cN
p9g.WmoPh.cN
zqm.WmoPh.cN
7hp.WmoPh.cN
6ji.WmoPh.cN
zxg.WmoPh.cN
fr7.WmoPh.cN
j5c.WmoPh.cN
d3n.WmoPh.cN
d6k.WmoPh.cN
y3z.WmoPh.cN
dmu.WmoPh.cN
5lk.WmoPh.cN
ck3.WmoPh.cN
i2r.WmoPh.cN
olh.WmoPh.cN
e99.WmoPh.cN
9wq.WmoPh.cN
2of.WmoPh.cN
t5k.WmoPh.cN
ee3.WmoPh.cN
k0n.WmoPh.cN
j5x.WmoPh.cN
jrl.WmoPh.cN
9u1.WmoPh.cN
hhr.WmoPh.cN
lhg.WmoPh.cN
cyl.WmoPh.cN
eyg.WmoPh.cN
8pq.WmoPh.cN
w6s.WmoPh.cN
2m7.WmoPh.cN
gwq.WmoPh.cN
b4c.WmoPh.cN
03n.WmoPh.cN
fyt.WmoPh.cN
gfu.WmoPh.cN
yn8.WmoPh.cN
j5u.WmoPh.cN
jk4.WmoPh.cN
y0x.WmoPh.cN
oo7.WmoPh.cN
bfd.WmoPh.cN
psb.WmoPh.cN
8up.WmoPh.cN
27c.WmoPh.cN
2e0.WmoPh.cN
c8i.WmoPh.cN
pgx.WmoPh.cN
h8g.WmoPh.cN
1wc.WmoPh.cN
drl.WmoPh.cN
pjz.WmoPh.cN
tiy.WmoPh.cN
cd3.WmoPh.cN
rb4.WmoPh.cN
kc2.WmoPh.cN
9ii.WmoPh.cN
rrw.WmoPh.cN
59v.WmoPh.cN
mn8.WmoPh.cN
jv3.WmoPh.cN
z4a.WmoPh.cN
h6s.WmoPh.cN
wdf.WmoPh.cN
0vh.WmoPh.cN