python 爬虫 爬取并下载小说

参考:Python3 网络爬虫(二):下载小说的正确姿势

1、目标:

使用python语言,爬取笔趣阁_书友最值得收藏的免费小说阅读网的数据,并实现电子书下载。

2、前置知识与要求:

要使用爬虫从目标网站爬取所需数据,需要对前端有基本的认识,可以简单看看B站课程:【Python+爬虫】爆肝两个月!拜托三连了!这绝对是全B站最用心(没有之一)的Python+爬虫公开课程,从入门到(不)入狱 !_哔哩哔哩_bilibili

要实现爬取需要下载安装几个第三方库:requests、bs4、lxml、tqdm。

①requests第三方库的使用范例

requests库用来发送http请求,可以用来模仿浏览器向服务器发送请求,并处理响应。

import requests
# 向服务器发送get请求
reponse=requests.get("https://www.bilibili.com/video/BV1A8411r7Zy/")

if reponse.ok:
    print(reponse)
    print(reponse.text)
else:
    print("请求失败")

请求成功,响应<Response [200]>,结果如下:

 这样的请求方式,可能会被拒绝,像我们要爬取豆瓣网的数据时就会出现请求失败,或者响应<Response [418]>等,可以通过418 I'm a teapot - HTTP | MDN来查看响应的具体含义。

在这种情况下,可以通过设定请求头,来模仿浏览器访问,像下面这样:

import requests
header={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
}
reponse=requests.get("https://www.douban.com/",headers=header)
if reponse.ok:
    print(reponse)
    print(reponse.text)
else:
    print("请求失败")

请求头的内容具体填什么,可以打开任意一个网站,右键点击检查

 得到下面界面,点击上方Network,刷新界面,点击左侧任意项目,可以在右侧Headers栏的Request Headers中看到划出的User-Agent,此项即为我们需要的请求头信息,可以直接复制粘贴到程序中。

 ②bs4与lxml第三方库

这两个第三方库,用来对请求获取的html文件进行处理,bs4即BeautifulSoup可以从html或xml文件中提取数据,lxml用于处理 XML 和 HTML 文档。

③tqdm第三方库

 tqdm第三方库可以在循环中显示进度,提供可视化的进度跟踪和估计。我们可以使用这个第三库来实时显示下载进度。

3、程序实现

①爬虫获取目标信息

通过requests的get方法,我们能够得到目标网站的html文件,接下来就是要从中提取信息,其实就是通过BeautifulSoup和lxml两个第三方库,对获得到的html文件中的信息进行筛选提取实现的。

在写爬取程序前要观察目标信息在html文件的哪个部分,这个部分有哪些特征。

可以在目标网站,右键点击检查,然后在这样的界面点击红圈部分。

再将鼠标移到左侧需要的信息上,右侧会同步显示其在html文件中的位置,如红圈位置,可以看到我们关心的小说信息都在一个div id="content"之内,这就是我们要找的特征了。

 

找到特征就可以写爬取程序了,我们以下载某小说为例,在这里我们要实现爬取并下载小说的功能,可以拆分为②和③两部分,再结合获得最终的程序④部分。下面是实现小说爬取下载的具体实现:

②获取小说信息

使用下面的程序段就可以实现小说信息的爬取,在此程序中我将获取到的html文件先写入txt再提取,这是没有必要的。但由于我是用的是pycharm环境,不先写再读,无法在运行结果中查看html文件的全部信息。


# 实现小说信息的爬取
import requests
from bs4 import BeautifulSoup
# 请求头
header={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
}
# 发送get请求
reponse=requests.get("http://www.ibiquge.cc/24/107340.html",headers=header)
# 主程序
if __name__ == '__main__':
    # 如果响应成功
    if reponse.ok:
        # 打印响应
        print(reponse)
        # 下面先写再读的程序可以注释掉,直接使用div=reponse.text
        # 先将html文件写入txt
        with open("reponse.txt","w+") as f:
            f.write(reponse.text)
            f.seek(0)
            # 读取写入的信息
            div=f.read()
        #div=reponse.text
        # 使用BeautifulSoup来解析html格式信息,指定解析器为lxml
        div_text=BeautifulSoup(div,"lxml")
        # 通过特征找到所需信息
        text=div_text.find('div',id='content')
        # 将找到的信息提取并清洗最后打印出来
        print(text.text.strip().split('\xa0'*4))
    else:
        print("请求失败")

运行结果如下:

③获取章节信息

我们能够获取一个章节的小说信息还不够,要下载全本,还要获取所有的章节信息,我们可以通过在圣墟的目录网页按照特征提取信息,实现章节信息的获取。如下面程序:


# 实现章节信息爬取
import requests
from bs4 import BeautifulSoup

header={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
}
reponse=requests.get("http://www.ibiquge.cc/24/",headers=header)

if __name__ == '__main__':
    if reponse.ok:
        # 目标网站
        server='http://www.ibiquge.cc'
        print(reponse)
        # 下面先写再读的程序可以注释掉,直接使用div=reponse.text
        with open("reponse.txt","w+",encoding='utf-8') as f:
            f.write(reponse.text)
            f.seek(0)
            div=f.read()
        # div=reponse.text
        div_text=BeautifulSoup(div,"lxml")
        # 通过特征获取章节名与链接
        chapters=div_text.find('div','listmain')
        chapters=chapters.find_all('a')
        # 循环打印章节名与章节链接
        for chapter in chapters:
            # 提取章节链接并与目标网址结合得到具体网址
            chapter_url=server+chapter.get('href')
            # 提取章节名称
            chapter_name=chapter.string
            # 打印
            print(chapter_name)
            print(chapter_url)
    else:
        print("请求失败")

运行结果如下:

④完整程序 

 结合前面两个部分的内容,循环获取章节链接chapter_url,再将链接传入get_content函数来执行小说内容抓取,最后写入文件。


# 完整程序
import requests
from bs4 import BeautifulSoup
from tqdm import tqdm
# 请求头
header={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
}
# 通过输入的网址抓取小说内容
def get_content(target):
    req=requests.get(url=target)
    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='http://www.ibiquge.cc'
    target='http://www.ibiquge.cc/24/'
    reponse = requests.get(url=target,headers=header)
    if reponse.ok:
        # 下面先写再读的程序可以注释掉,直接使用div=reponse.text
        with open("reponse.txt","w+",encoding='utf-8') as f:
            f.write(reponse.text)
            f.seek(0)
            div=f.read()
        # div=reponse.text
        div_text=BeautifulSoup(div,"lxml")
        book_info=div_text.find('div',id='info').find('h1')
        # 获取书籍名字
        book_name=book_info.text.strip()+'.txt'
        # 获取章节名与链接
        chapters=div_text.find('div','listmain')
        chapters=chapters.find_all('a')
        for chapter in tqdm(chapters):
            chapter_url=server+chapter.get('href')
            chapter_name=chapter.string
            content=get_content(chapter_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')
    else:
        print("请求失败")

运行结果如下:

 4、程序优化

以上的实现程序比较简单,还存在不少可以优化的内容:

①由于这样的网站本身并不稳定,获取小说内容时,有时会有响应超时导致的错误,可以增加等待时间或者错误处理程序。

②出现错误跳出程序,再下载时会重新来过,可以添加断点重连,继续下载的功能,避免重复。

③可以添加搜索功能,实现在命令行输入想下的电子书,自动过滤信息,实现下载。

这些功能我会在后边的学习中逐一完善,欢迎各位大佬批评指正。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值