Python爬虫实战—笔趣看小说网

一、实战背景

笔趣看小说网站:https://www.biqukan.com/

本站所有小说为转载作品,所有章节均由网友上传,转载至本站只是为了宣传本书让更多读者欣赏。

工具:Python3.7,PyCharm

程序所需用到的模块:requests,fake_useragent,parsel,docx,time

所使用的解析器:xpath

二、明确目标

明确我们需要爬取哪部小说。这里我以《斗破苍穹》为例。

2.1 分析我们需要爬取的数据

image.png

作者、分类、状态、字数、更新时间和简介

文章从正文卷开始,获取每一章的章节名称和链接

2.2 分析节点,按F12打开浏览器的开发者工具

image.png

每一章的详情内容

image.png

2.3 使用xpath解析器审查元素

image.png

image.png

三、编写代码

"""
    Python爬取 https://www.biqukan.com/ 小说网的斗破苍穹小说
"""
import requests
from fake_useragent import UserAgent
import parsel
from docx import Document
import time


class BiQuKanDownloader(object):
    """
    类说明:下载《笔趣看》小说网小说《斗破苍穹》
    """

    def __init__(self):
        self.server = "https://www.biqukan.com/"
        self.target = "https://www.biqukan.com/3_3037/"
        self.file = "F:\Python\爬虫资源\斗破苍穹\斗破苍穹.docx"
        self.article_names = []  # 存放章节名称
        self.article_urls = []  # 存放章节链接
        self.article_nums = 0  # 章节数
        self.headers = {"User-Agent": UserAgent().random}  # 生成随机的请求头
        self.doc = Document()

    def article_introduction(self):
        """
        函数说明:文章简介
        :return:
        """
        """ 请求网页 """
        response = requests.get(url=self.target, headers=self.headers)
        response.encoding = 'gbk'
        html = response.text
        """ 解析网页 """
        selector = parsel.Selector(html)
        article_author = selector.xpath('.//div[@class="info"]/div[@class="small"]/span[1]/text()').get()      # 作者
        article_type = selector.xpath('.//div[@class="info"]/div[@class="small"]/span[2]/text()').get()        # 类型
        article_status = selector.xpath('.//div[@class="info"]/div[@class="small"]/span[3]/text()').get()      # 状态
        article_docs = selector.xpath('.//div[@class="info"]/div[@class="small"]/span[4]/text()').get()        # 字数
        article_updateTime = selector.xpath('.//div[@class="info"]/div[@class="small"]/span[5]/text()').get()  # 更新时间
        article_introduction = selector.xpath('.//div[@class="info"]/div[@class="intro"]/text()[1]').get()     # 简介
        """ 保存到文件 """
        self.doc.add_heading("小说简介", level=1)
        self.doc.add_paragraph(article_author)
        self.doc.add_paragraph(article_type)
        self.doc.add_paragraph(article_status)
        self.doc.add_paragraph(article_docs)
        self.doc.add_paragraph(article_updateTime)
        self.doc.add_paragraph(article_introduction)
        self.doc.save(self.file)

    def get_download_url(self):
        """
        函数说明:获取目标下载链接并解析章节名称和链接,再添加到列表中
        :return:
        """
        """ 请求网页 """
        response = requests.get(url=self.target, headers=self.headers)
        response.encoding = 'gbk'
        html = response.text

        """ 解析网页 """
        # 转化数据类型
        selector = parsel.Selector(html)
        # 提取所有的 <dd>标签
        article_list = selector.xpath('//div[@class="listmain"]/dl/dd')
        # 删除不必要的章节目录,并统计章节数[也就是从正文卷开始统计]
        self.article_nums = len(article_list[12:])

        for chapter in article_list[12:]:
            # 解析章节名称和链接
            article_name = chapter.xpath('.//a/text()').get()
            article_url = chapter.xpath('.//a/@href').get()
            # 将章节名称和链接添加到列表中
            self.article_names.append(article_name)
            self.article_urls.append(self.server + article_url)

    def get_article_content(self, target_url):
        """
        函数说明:获取章节正文内容
        :param target_url: 每章的 url地址
        :return:
        """
        """ 请求网页 """
        response = requests.get(url=target_url, headers=self.headers)
        response.encoding = 'gbk'
        html = response.text

        """ 解析网页 """
        # 转化数据类型
        selector = parsel.Selector(html)
        # 解析文章正文内容
        article_content_list = selector.xpath('.//div[@class="showtxt"]/text()').getall()
        article_content = "  "
        for text in article_content_list:
            if '\r' in article_content_list:
                article_content_list.remove(text)
            article_content += text.strip() + "\n"
        return article_content

    def writer(self, path, name, text):
        """
        将爬取的文章写入文件
        :param path: 保存文件的路径
        :param name: 文章的名称
        :param text: 文章的内容
        :return:
        """
        # with open(path, 'a', encoding='utf-8') as file:
        #     file.write(name)
        #     file.writelines(text)
        #     file.write('\n\n')

        self.doc.add_heading(name, level=1)
        self.doc.add_paragraph(text)
        self.doc.add_paragraph("\n")
        self.doc.save(path)
        print(name + "\t\t已下载", end=" ")


if __name__ == '__main__':
    print("<<<<<=====斗破苍穹开始下载=====>>>>>")
    dl = BiQuKanDownloader()
    dl.get_download_url()
    dl.article_introduction()
    print("小说章节数:" + str(dl.article_nums))

    for i in range(dl.article_nums):
        text = dl.get_article_content(dl.article_urls[i])
        dl.writer(dl.file, dl.article_names[i], text)
        print("\t\t总体下载进度: %.2f%%" % float(i / dl.article_nums))
        time.sleep(1)

    print("<<<<<=====斗破苍穹下载完成=====>>>>>")

这里使用的gbk编码格式,是因为小说网站文章内容为gbk编码的格式

在浏览器的开发者工具控制台中输入:doucument.charset 可查看编码格式

image.png

四、效果展示

image.png

image.png

做一个文明守法的好网民,不要爬取公民的隐私数据,不要给对方的系统带来不必要的麻烦

此篇博客仅作学习用途

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值