Python爬取小说
需要准备的东西:
- 用到的网站:http://www.pgyzw.com/
- 用到的环境:python3.7
- 用到的ide:pycharm
- 用到的第三方库:BeautifulSoup、requests 可以在pycharm一键安装
首先看一下requests的使用方法
import requests #导入requests库
url = 'http://www.pgyzw.com/html/61/61945/24421276.html' #需要访问的url
html = requests.get(url=url) #以get方式访问这个url,并且把返回的数据保存到html变量
print(html.text) #输出这个变量
运行结果:

突然发现是乱码,这也就是所谓的编码错误,打开网页,按f12,发现什么都没有

点一下刷新就有数据了

很明显这个是gbk编码,我们需要修改一下上面代码的编码再跑一遍
import requests #导入requests库
url = 'http://www.pgyzw.com/html/61/61945/24421276.html' #需要访问的url
html = requests.get(url=url) #以get方式访问这个url,并且把返回的数据保存到html变量
html.encoding = 'gbk' #修改编码为gbk
print(html.text) #输出这个变量
运行结果:

很明显变成中文了,人性化了不少,但是这样依然还是有不少各种奇奇怪怪的(html)代码,现在就用到神奇的BeautifulSoup库了
先来分析一下:

通过这个图我们可以发现,我们要爬取的内容都包括在这个div中,而且这个div有唯一值,那就是id=content
代码:
import requests #导入requests库
from bs4 import BeautifulSoup
url = 'http://www.pgyzw.com/html/61/61945/24421276.html' #需要访问的url
req = requests.get(url=url) #以get方式访问这个url,并且把返回的数据保存到html变量
req.encoding = 'gbk' #修改编码为gbk
html = req.text #将req的text内容赋值给html
bf = BeautifulSoup(html) #调用BeautifulSoup处理html的内容,并赋值给bf
div = bf.find_all('div',id='content') #只留下标签为div id=content的数据
print(div)
运行结果:

发现把那些内容取出来了,但是还有一些html标记,下面我们来除去这些标记
import requests #导入requests库
from bs4 import BeautifulSoup
url = 'http://www.pgyzw.com/html/61/61945/24421276.html' #需要访问的url
req = requests.get(url=url) #以get方式访问这个url,并且把返回的数据保存到html变量
req.encoding = 'gbk' #修改编码为gbk
html = req.text #将req的text内容赋值给html
bf = BeautifulSoup(html) #调用BeautifulSoup处理html的内容,并赋值给bf
div = bf.find_all('div',id='content') #只留下标签为div id=content的数据
texts = div[0].text.replace('','') #把第一个内容换成第二个内容,并自动过滤大部分html标记,我们本次只需要过滤标记
#div[0]是一个数组的概念,因为本次div的数据只有一条,所以用div[0]
print(texts)
运行结果:

本章不必要的因素已全部过滤完毕,但是我们肯定是不止下载一章,下面来把所有的章节名以及链接爬取出来
import requests
from bs4 import BeautifulSoup
url='http://www.pgyzw.com/html/61/61945/index.html'
req = requests.get(url=url)
req.encoding = 'gbk'
html = req.text
print(html)
因为是和上面一样的东西,所以不添加注释也不再解释
运行结果:

是的,爬取出来了,但是肯定还需要使用BeautifulSoup库处理一下:
import requests #导入requests库
from bs4 import BeautifulSoup
server='http://www.pgyzw.com/html/61/61945/'
url='http://www.pgyzw.com/html/61/61945/index.html'
req = requests.get(url=url)
req.encoding = 'gbk'
html = req.text
bf = BeautifulSoup(html)
table=bf.find_all('table', class_='acss') #本次内容包含在table标记里面,唯一值是class=acss
#这里class使用class_的目的是为了不和类冲突,因为python里面本来就有名为class的类
a_bf = BeautifulSoup(str(table[0])) #依然是赋值str是文本型的意思,也就是转为文本型
a = a_bf.find_all('a') #不难发现,<a>标签里面的是小说的链接所以说我们要把a标签匹配出来
for each in a: #for循环打印章节
print(each.string,server + each.get('href')) #使用a.get(‘href’)方法就能获取href的属性值,使用a.string就能获取章节名
运行结果:

至此,我们把章节和内容都爬取下来了,下面就要整合一下,真正的爬取一本小说
完整代码:
# coding=utf-8
import requests,sys #调库操作
from bs4 import BeautifulSoup
class downloader(object): #downloader类
def __init__(self): #__init__函数,可以理解为java方法
self.server = 'http://www.pgyzw.com/html/61/61945/'
self.target = 'http://www.pgyzw.com/html/61/61945/index.html'
self.names = [] #存放章节名
self.urls = [] #存放章节链接
self.nums = 0 #章节数
def get_download_url(self):
req = requests.get(url=self.target)
req.encoding='gbk'
html = req.text
bf = BeautifulSoup(html)
table=bf.find_all('table', class_='acss')
a_bf = BeautifulSoup(str(table[0]))
a = a_bf.find_all('a')
self.nums = len(a[0:]) #从下标为0开始
for each in a[0:]:
self.names.append(each.string) #章节名
self.urls.append(self.server+each.get('href')) #章节链接
#http://www.pgyzw.com/html/61/61945/ + 24421276.html = www.pgyzw.com/html/61/61945/24421276.html
def get_contents(self,target):
req = requests.get(url=target)
req.encoding='gbk'
html = req.text
bf = BeautifulSoup(html)
div = bf.find_all('div',id='content')
texts = div[0].text.replace('','')
return texts #返回获取的内容
def writer(self,name,path,text): #写文件操作
write_flag = True
with open(path, 'a', encoding='utf-8') as f: #以当前目录新建文本文档,编码格式为utf-8
f.write(name+'\n') #写章节名+换行
f.writelines(text) #写本章节内容
f.write('\n\n')
if __name__ == '__main__':
dl = downloader() #调用downloader类
dl.get_download_url() #获取章节url
print('《一念永恒》开始下载:')
for i in range(dl.nums):
dl.writer(dl.names[i], '一念永恒.txt', dl.get_contents(dl.urls[i]))#写第i章节名加第i章的内容
sys.stdout.write(" 已下载:%.3f%%" % float(i / dl.nums) + '\r')
sys.stdout.flush() #刷新缓冲区
print('《一念永恒》下载完成')
注意:
此程序需要在cmd命令行窗口运行
cmd运行参考:https://zhidao.baidu.com/question/1510889184474081700.html
运行结果:

因未使用多线程,下载速度非常非常慢,您可以来杯java放松一下
至此,教程完毕
苟利国家生死以,岂因祸福避趋之

浙公网安备 33010602011771号