小说有广告?我用50行Python爬虫做了一个无广在线小说阅读器

小说有广告?我用50行Python爬虫做了一个无广在线小说阅读器


前言

还在为看小说受到广告影响而烦恼吗?不如利用起时间,跟着本文一起入门python爬虫,实现小说自由!


介绍

本项目的全部内容包括:

1.搜索功能实现
2.根据所选小说爬取全部章节列表
3.在线阅读所选章节


正文

预配置

在一般的无反爬虫情形下,python请求网页信息的请求头较为简单,只写User-Agent项即可,可在检查中任意请求的请求头中查看在这里插入图片描述
配置代码如下:

    def __init__(self):
        self._headers={
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.55"
        }
        self._search_url = 'https://www.xbiquwx.la/modules/article/search.php?searchkey='
        self._book_url = 'https://www.xbiquwx.la'
        self.session = requests.session()

上段代码中使用了session会话机制,可有效提升python的requests访问网站速度


搜索

小说网站搜索万相之王,检查网络元素
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发现其请求的url如上图中所示,其中的searchkey即为搜索文字的url编码
在这里插入图片描述
分析网页源码可知,我们所需的书名和链接均位于class属性值为gridtable标签中,使用xpath语法即可提取标签内容和标签属性
综上,这一部分输入书名搜索返回结果的代码如下:

    def search(self, name:str):
        if name:
            response = self.session.get(
                url = self._search_url + name, 
                headers = self._headers
            )
            html = etree.HTML(response.content.decode())
            self.bookID = html.xpath('//table[@class="grid"]/tr/td[@class="odd"]/a/@href')
            bookNameTag = html.xpath('//table[@class="grid"]/tr/td[@class="odd"]/a')
            self.bookName = [item.text for item in bookNameTag]
            return self.bookName

获取章节列表

打开任意一本书籍,检查加载书籍章节时的网络访问情况
在这里插入图片描述
可以发现请求的地址就是我们上一步中得到的书籍url,进一步证实了想法
在这里插入图片描述
在这里我们发现所有章节名称和url信息全部位于网页源码的dd标签中,同上,利用xpath语法提取
这一部分获取章节名字的代码如下:

    def chapLists(self, index:int):
        response = self.session.get(
            url = self._book_url + self.bookID[index], 
            headers = self._headers
        )
        self.index = index
        html = etree.HTML(response.content.decode())
        self.chapUrls = html.xpath('//div[@class="box_con"]/div[@id="list"]//a/@href')
        self.chapTitles = html.xpath('//div[@class="box_con"]/div[@id="list"]//a/@title')
        self.chapUrls.reverse()
        self.chapTitles.reverse()
        return self.chapTitles

在线阅读

我们打开任意一章小说,审查网络元素
在这里插入图片描述
同样可以发现所请求的网站就是上一步中得到的章节地址
在这里插入图片描述
在网页源码中我们发现小说正文部分位于id属性为contentdiv标签中,编写代码提取正文内容:

    def read(self, index:int):
        response = self.session.get(
            url = self._book_url + self.bookID[self.index] + self.chapUrls[index], 
            headers = self._headers
        )
        code = response.apparent_encoding
        html = etree.HTML(response.content.decode())
        articleRaw = html.xpath('//div[@class="content_read"]//div[@id="content"]')
        a0 = etree.tostring(articleRaw[0],encoding=code).decode(code)
        a2 = a0[32:-29]
        article = "<h1>"+self.chapTitles[index]+"</h1>"+'<font size="5"><br />'+a2+"</font>"
        return article

到此,我们已经掌握了整个小说阅读的来龙去脉


总结

整个网络小说在线阅读类封装如下:

import requests
from lxml import etree


class bqCrawler():
    def __init__(self):
        self._headers={
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.55"
        }
        self._search_url = 'https://www.xbiquwx.la/modules/article/search.php?searchkey='
        self._book_url = 'https://www.xbiquwx.la'
        self.session = requests.session()

    def search(self, name:str):
        if name:
            response = self.session.get(
                url = self._search_url + name, 
                headers = self._headers
            )
            html = etree.HTML(response.content.decode())
            self.bookID = html.xpath('//table[@class="grid"]/tr/td[@class="odd"]/a/@href')
            bookNameTag = html.xpath('//table[@class="grid"]/tr/td[@class="odd"]/a')
            self.bookName = [item.text for item in bookNameTag]
            return self.bookName

    def chapLists(self, index:int):
        response = self.session.get(
            url = self._book_url + self.bookID[index], 
            headers = self._headers
        )
        self.index = index
        html = etree.HTML(response.content.decode())
        self.chapUrls = html.xpath('//div[@class="box_con"]/div[@id="list"]//a/@href')
        self.chapTitles = html.xpath('//div[@class="box_con"]/div[@id="list"]//a/@title')
        self.chapUrls.reverse()
        self.chapTitles.reverse()
        return self.chapTitles

    def read(self, index:int):
        response = self.session.get(
            url = self._book_url + self.bookID[self.index] + self.chapUrls[index], 
            headers = self._headers
        )
        code = response.apparent_encoding
        html = etree.HTML(response.content.decode())
        articleRaw = html.xpath('//div[@class="content_read"]//div[@id="content"]')
        a0 = etree.tostring(articleRaw[0],encoding=code).decode(code)
        a2 = a0[32:-29]
        article = "<h1>"+self.chapTitles[index]+"</h1>"+'<font size="5"><br />'+a2+"</font>"
        return article

在此基础上我们稍作修饰,用PyQt5为其开发一个可视化面板,最终效果如图:
在这里插入图片描述

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 36
    评论
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值