战恋雪网站的爬取实战

因为要释放掉那些干扰我理智思考的东西,所以一直在苦苦找寻刘备(皇叔)(づ ̄ 3 ̄)づ网站,直到一次我搜索《战恋雪》时我发现了这个网站战恋雪

因为要释放掉那些干扰我理智思考的东西,所以一直在苦苦找寻刘备(皇叔)(づ ̄ 3 ̄)づ网站,直到一次我搜索《战恋雪》时我发现了这个网站战恋雪

tgUv5D.jpg

tgtcGj.png

它网罗了网络上很优秀的xhs,以我多年习书所养成的挑剔眼光来看,我也该大大赞叹此站主深得老夫脾胃。看小说我更喜欢用手机进行阅读,不仅屏幕小不易被人发现,而且可以躺在床上看,更是体位可以保证最大舒适度进行原地起飞。结果恰恰是这个移动端超多广告,adblock插件完全对付不了,换页时频繁的强制跳转广告让我性致乏乏,一而再再而三的这样,怎么办?忍?鸡儿他可首先不同意,这谁忍得了!办他!
那就把网站内容全部爬取下来吧

抓取所有书籍链接

先是用chrome控制台分析首页,很容易发现首页上就有网站所有书籍的链接地址,而且全部保存到了一个html页面上了,只要提取这个html页面的书籍信息既可以了。分析页面可以看到书籍地址保存在 menu标签的li标签的a标签中,用bs4可以提取

tgtgRs.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def get_book():     #战恋雪网站所有书籍链接
try:
re=requests.get('https://www.zhanlianxue.net/')
html=re.text
soup=BeautifulSoup(html,'html.parser')
haha=soup('ul',attrs={'class':'menu'})

for book in haha[0]('a'):
title=book.text
url=book.attrs['href']
if title=='首页': #有一个首页,不是一本书,需去掉
continue
yield{
'title':title,
'url':url
}
except:
print('获得所有书本信息错误')

抓取书籍章节

再我们打开一个书籍地址,可以看到有很多章节,控制台分析,章节地址保存在ul标签的li标签的a标签中,用bs4可以提取

tgtrdS.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def get_bookcapital(url):    #获得一本书的所有章节名称与章节链接

try:
re=requests.get(url,timeout=60)
html=re.text
soup=BeautifulSoup(html,'html.parser')
haha=soup('ul')[1]

for chapter in haha('li'):

title=chapter('a')[0].text

url=chapter('a')[0].attrs['href']
yield{
'ctitle':title,
'curl':url
}
except:
print('获取书的章节链接错误')

抓取书籍内容

然后我们打开一个章节定位到内容中,经过多个页面的比对可以发现所有内容都存储在最上面箭头的那个标签中,直接获取标签范围所有内容就可(要是范围太大,可能内容会提取到代码,可以用正则表达式清除)。最后就是把内容保存到文档中

tgtsIg.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def savechapter(bookname,url):   #根据章节连接,保存章节里面的文本

try:
re1=requests.get(url,timeout=60)
html=re1.text
html=re.sub('<br.*?>','\n',html)
soup=BeautifulSoup(html,'html.parser')
content=soup('div',attrs={'class':'single-box clearfix entry-content'})[0]
a=content('script') #清除文本中的干扰代码(美观)
for i in a:
i.clear()
makebook(bookname,content.text)
except:
print('存入文本错误')


def makebook(bookname,text): #保存文本
path='F:\战恋雪\{}.txt'.format(bookname) #这里F盘需要先创建战恋雪这个文件夹
with open(path,'a',encoding='utf-8')as haha:
haha.write('\n'+text)

多进程下载书籍

因为书籍太多,再加上章节一章一章获取实在是太慢,开启多进程同时下载多本书会快很多

1
2
3
4
5
if __name__=='__main__':
pool=Pool(processes=20) #20个进程调用获得所有书
group=a #a列表是网站所有书的链接地址
print(group)
pool.map(main,group)

所有代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from bs4 import BeautifulSoup
import re
import requests
from multiprocessing import Pool
def get_book(): #战恋雪网站所有书籍链接
try:
re=requests.get('https://www.zhanlianxue.net/')
html=re.text
soup=BeautifulSoup(html,'html.parser')
haha=soup('ul',attrs={'class':'menu'}) #ul标签可能很多,直接搜索标签会返回列表,自己找到所需内容的ul标签下标,其他的都是同理

for book in haha[0]('a'):
title=book.text
url=book.attrs['href']
if title=='首页': #有一个首页,不是一本书,需去掉
continue
yield{
'title':title,
'url':url
}
except:
print('获得所有书本信息错误')



def get_bookcapital(url): #获得一本书的所有章节名称与章节链接

try:
re=requests.get(url,timeout=60)
html=re.text
soup=BeautifulSoup(html,'html.parser')
haha=soup('ul')[1]

for chapter in haha('li'):

title=chapter('a')[0].text

url=chapter('a')[0].attrs['href']
yield{
'ctitle':title,
'curl':url
}
except:
print('获取书的章节链接错误')



def savechapter(bookname,url): #根据章节连接,保存章节里面的文本

try:
re1=requests.get(url,timeout=60)
html=re1.text
html=re.sub('<br.*?>','\n',html)
soup=BeautifulSoup(html,'html.parser')
content=soup('div',attrs={'class':'single-box clearfix entry-content'})[0]
a=content('script') #清除文本中的干扰代码(美观)
for i in a:
i.clear()
makebook(bookname,content.text)
except:
print('存入文本错误')


def makebook(bookname,text): #保存文本
path='F:\战恋雪\{}.txt'.format(bookname) #这里F盘需要先创建战恋雪这个文件夹
with open(path,'a',encoding='utf-8')as haha:
haha.write('\n'+text)

def makebook_chapter(bookname,cname): #在文本中还要保存章节名称
path='F:\战恋雪\{}.txt'.format(bookname) #这里F盘需要先创建战恋雪这个文件夹
with open(path,'a',encoding='utf-8')as haha:
haha.write(cname+'\n')

def main(haha): #获得一本书的所有步骤
book=haha
print(book)
print('正在获取 {} {}'.format(book.get('title'),book.get('url')))
for chapter in get_bookcapital(book.get('url')):
print('当前《{}》--获取章节 {} {} '.format(book.get('title'),chapter.get('ctitle'),chapter.get('curl')))
makebook_chapter(book.get('title'),chapter.get('ctitle'))
savechapter(book.get('title'),chapter.get('curl'))

#把所有书籍连接放入一个列表中,方便多进程取值
a=[]
for i in get_book():
a.append(i)
print(a)

if __name__=='__main__':
pool=Pool(processes=20) #20个进程调用获得所有书
group=a #a列表是网站所有书的链接地址
print(group)
pool.map(main,group)

运行结果

tgBqA0.png

tgBLNV.png

反思

  1. 自己是不是太猥琐了,学这个鬼东西专门干这些事?
  2. 下次要写写读书笔记了
  3. 这些都还是皮毛,很纠结自己到底主Java呢,还是python呢?python是用来玩的,但是我投入的时间对他太多了。

战恋雪网站的爬取实战
https://lililib.github.io/战恋雪/
作者
煨酒小童
发布于
2019年6月7日
许可协议