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放松一下

至此,教程完毕

posted @ 2020-02-29 20:42  无心吖  阅读(657)  评论(0)    收藏  举报