python爬取小说实例

Python爬取《遮天》小说

上学期某门课程大作业需要用到爬取网站相关的技术对某网站进行爬取,自己也试着在网上学习了一些爬取网站相关的浅显内容,最后实现了爬取。今天,就再以一个小型的项目来练手,目标是爬取《遮天》这部小说。
ps : 本实例仅作为练习使用,推荐支持正版小说

爬虫

什么是爬虫?

爬虫是一段自动抓取互联网信息的程序,从互联网上抓取对于我们有价值的信息。通俗的讲,就是一只爬虫或者蜘蛛,在互联网这张大网中,可以按照我们的心意,爬到对应的地方,并将网页中的信息反馈给我们。

爬虫协议?

robots协议也称爬虫协议、爬虫规则等,是指网站可建立一个robots.txt文件来告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取,而搜索引擎则通过读取robots.txt文件来识别这个页面是否允许被抓取。但是,这个robots协议不是防火墙,也没有强制执行力,搜索引擎完全可以忽视robots.txt文件去抓取网页的快照。(来源于百度百科词条——robots协议)
我们可以通过在网站url的结尾添加/robots.txt查看

如何爬虫?

现如今常见的爬虫工具有很多,如requests、XPath、lxml、BeautifulSoup4、Seleninum等。一个简单的爬虫,通常只需要获取网页url,解析网页内容,得到需要爬取的内容,本次爬虫所使用的是urllib库中的request以及BeautifulSoup4。

开发环境

你可以使用PyCharm,好处是简单易上手,如今PyCharm甚至可以一键自动为你下载python(不过好像不会自动添加到环境变量中),许多视频教程也以PyCharm作为开发主力。
当然,你也有其他的选择,比如vscode+python,如果有需要的话,这里我或许也会写一个教程。
本次开发较为小型,就使用vscode吧。
进行代码的编写前,请确保你的python解释器中已经下载好了bs4,urllib应该已经在python3中存在了,无需手动下载。你可以通过命令行终端输入pip list看是否bs4包已下载。如未包含,可以通过pip install bs4进行下载。

正片开始

先查看一下爬虫协议

在这里插入图片描述
可以看出,网站对于爬虫爬取内容并没有加以限制

获取每一章节的url和标题

在这里插入图片描述
开发者模式查看导航页网页源码,发现每一章节的url和标题都在类名为"box_con",id=“list”,标签名自上而下为dl dd,故可通过BeautifulSoup 使用select方法获取每一章节的url。

# 可以看到每一章的url以及标题位置相似
    pattern = soup.select('.box_con #list dl dd')

对之前select下来的内容进行分解,这里可以用到正则表达式来帮助我们处理。可以发现url的处于a href=" 和"之间,而标题处于html">和</a之间,所以可以用如下正则表达式提取。

import re
findLink = re.compile(r'<a href="(.*?)"')
findTitle = re.compile(r'.html">(.*?)</a>')

为了不轻易被识别为爬虫,我们可以传入一个head参数,伪装成浏览器正常访问。

    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36"
    }
获取每一章节的文本内容

在这里插入图片描述
先前已经获得了每一章节的url,获取网页内容的操作与先前对导航页进行的操作类似,不加以赘述。查看网页源码,如上图,所有小说文本内容均在id="content"中,用BeautifulSoup的find操作(只有一个,不要用findall)
在这里插入图片描述
效果图如上,可以看到已经将文本内容提取出来了,但是发现有许多无关数据,故还需对数据进行清洗。这里不一样的地方每一章节都一样,就直接替换吧。

 # 清洗文本,去除无关内容
        text = str(pattern1).replace("<br/><br/>", "\n")
        text = text.replace('<div id="content">', '')
        text = text.replace(
            '<script>chaptererror();</script><br/>请记住本书首发域名:booktxt.net。顶点小说手机版阅读网址:m.booktxt.net</div>', '')

看看清洗后的文本,就没有那些奇奇怪怪的东西啦。
在这里插入图片描述

存储文本

看小说肯定得一章一章的看啊,所以不如就用.txt文件存储吧,先前存储的标题也就可以发挥作用了。设置好路径,文件以w方式写入。

        # 以.txt文件形式存储
        file = open(r'F:\遮天\{}.txt'.format(
            title[i]), mode='w', encoding='utf-8')
        file.write(text)
        file.close

来看看效果在这里插入图片描述
在这里插入图片描述
如此我们本次爬取小说的任务就完成啦。我本次作为演示只爬取了前面20章左右内容,你当然可以将整本小说都爬取下来。

完整代码
import re
from bs4 import BeautifulSoup
import urllib.request


findLink = re.compile(r'<a href="(.*?)"')
findTitle = re.compile(r'.html">(.*?)</a>')


def main():
    # 标题页的url
    url = "https://www.booktxt.net/1_1213/"
    # 头部伪装
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36"
    }
    # 获取网页信息
    request = urllib.request.Request(url, headers=head)
    response = urllib.request.urlopen(request)
    html = response.read().decode('gbk')
    soup = BeautifulSoup(html, 'html.parser')
    # 可以看到每一章的url位置相似
    pattern = soup.select('.box_con #list dl dd')
    # 存储标题
    title = []
    for item in range(20):
        # 每一章节的url
        pattern[item] = 'https://www.booktxt.net' + \
            re.findall(findLink, str(pattern[item]))[0]
        # 添加每一章的标题
        title.append(re.findall(findTitle, str(
            soup.select('.box_con #list dl dd')[item]))[0])
    for i in range(6, 20):
        url1 = pattern[i]
        request1 = urllib.request.Request(url1, headers=head)
        response1 = urllib.request.urlopen(request1)
        html1 = response1.read().decode('gbk')
        soup1 = BeautifulSoup(html1, 'html.parser')
        # 发现文本内容在id="content"下
        pattern1 = soup1.find(id="content")
        # 清洗文本,去除无关内容
        text = str(pattern1).replace("<br/><br/>", "\n")
        text = text.replace('<div id="content">', '')
        text = text.replace(
            '<script>chaptererror();</script><br/>请记住本书首发域名:booktxt.net。顶点小说手机版阅读网址:m.booktxt.net</div>', '')
        # 以.txt文件形式存储
        file = open(r'F:\遮天\{}.txt'.format(
            title[i]), mode='w', encoding='utf-8')
        file.write(text)
        file.close


if __name__ == '__main__':
    main()

结语:相信看完后你也可以自己写出一个爬虫啦,如有不当之处,还请批评指正。

  • 10
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值