Python简单爬取起点中文网小说(仅学习)


前言

实习期间自学了vba,现在开始捡回以前上课学过的python,在此记录学习进程


本文内容仅用于学习,请勿商用

一、爬虫思路

无需登录的页面只需要用到简单爬虫,获取小说目录、通过目录获取小说正文即可。

二、使用步骤

1.引入库

代码如下(示例):

import requests,sys
from bs4 import BeautifulSoup

2.读取页面

代码如下(示例):

target = 'https://book.qidian.com/info/1024995653#Catalog'
req = requests.get(url=target)

为防止页面出错、页面乱码问题,分别加入:

req.raise_for_status()
req.encoding = req.apparent_encoding

此时即可看到网页HTML:

html = req.text

3.分析HTML

在HTML代码中,我们要找到对应目录的文字和链接,以及承载这两个信息的标签:
利用审查元素查看HTML标签信息
在小说目录页面按下F12,观察页面的HTML,可以发现目录是在一个class=‘catalog-content-wrap’、id=‘j-catalogWrap’的div标签下的。继续分析,发现还有volume-wrap,volume等子标签作为目录的容器:
查看标签名
一直向下延伸到带有链接的a标签,定位到目标,分析完毕。
最小单位标签

bf = BeautifulSoup(html,"html.parser")
catalogDiv = bf.find('div',class_='catalog-content-wrap',id='j-catalogWrap')
volumeWrapDiv = catalogDiv.find('div',class_='volume-wrap')
volumeDivs = volumeWrapDiv.find_all('div',class_='volume')

3.从标签中取出信息

仍然是利用BS直接取出volume中所有的a标签,并且把其中的文本和对应的href存起来。

aList = volumeDiv.find_all('a')
for a in aList:
	chapterName = a.string
	chapterHref = a.get('href')

这样整个目录就检索完成了,开始利用Href爬取正文。


4.爬取正文

先随便选择一个链接打开,观察正文的HTML:
情况1
情况2
发现格式会有两种情况,一种直接用p标签装起来,一种是p中带有span,用class=content-wrap的span装起来。
但是首先他们都一定是在class=‘read-content j_readContent’的div下,因此直接定位:

req = requests.get(url=chapterHref)
req.raise_for_status()
req.encoding = req.apparent_encoding
html = req.text
bf = BeautifulSoup(html,"html.parser")
mainTextWrapDiv = bf.find('div',class_='main-text-wrap')
readContentDiv = mainTextWrapDiv.find('div',class_='read-content j_readContent')
readContent = readContentDiv.find_all('span',class_='content-wrap')

这时已经可以拿到带有标签的正文部分了,由于链接不同,会导致标签格式不同,因此用判断区分:

if readContent == []:
     textContent = readContentDiv.text.replace('<p>','\r\n')
     textContent = textContent.replace('</p>','')
else:
     for content in readContent:
          if content.string == '':
               print('error format')
          else:
               textContent += content.string + '\r\n'

正文内容获取完毕。

现在只需遍历就能获取整部小说啦!

总结

以下为完整代码:

#!/usr/bin/env python3
# coding=utf-8
# author:sakuyo
#----------------------------------
import requests,sys
from bs4 import BeautifulSoup

class downloader(object):
    def __init__(self,target):#初始化
        self.target = target
        self.chapterNames = []
        self.chapterHrefs = []
        self.chapterNum = 0
        self.session = requests.Session()
    def GetChapterInfo(self):#获取章节名称和链接
        req = self.session.get(url=self.target)
        req.raise_for_status()
        req.encoding = req.apparent_encoding
        html = req.text
        bf = BeautifulSoup(html,"html.parser")
        catalogDiv = bf.find('div',class_='catalog-content-wrap',id='j-catalogWrap')
        volumeWrapDiv = catalogDiv.find('div',class_='volume-wrap')
        volumeDivs = volumeWrapDiv.find_all('div',class_='volume')

        for volumeDiv in volumeDivs:
            aList = volumeDiv.find_all('a')
            for a in aList:
                chapterName = a.string
                chapterHref = a.get('href')
                self.chapterNames.append(chapterName)
                self.chapterHrefs.append('https:'+chapterHref)
            self.chapterNum += len(aList)
    def GetChapterContent(self,chapterHref):#获取章节内容
        req = self.session.get(url=chapterHref)
        req.raise_for_status()
        req.encoding = req.apparent_encoding
        html = req.text
        bf = BeautifulSoup(html,"html.parser")
        mainTextWrapDiv = bf.find('div',class_='main-text-wrap')
        readContentDiv = mainTextWrapDiv.find('div',class_='read-content j_readContent')
        readContent = readContentDiv.find_all('span',class_='content-wrap')
        if readContent == []:
            textContent = readContentDiv.text.replace('<p>','\r\n')
            textContent = textContent.replace('</p>','')
        else:
            for content in readContent:
                if content.string == '':
                    print('error format')
                else:
                    textContent += content.string + '\r\n'
        return textContent
    def writer(self, path, name='', content=''):
        write_flag = True
        with open(path, 'a', encoding='utf-8') as f: #a模式意为向同名文件尾增加文本
            if name == None:
                name=''
            if content == None:
                content = ''
            f.write(name + '\r\n')
            f.writelines(content)
            f.write('\r\n')

if __name__ == '__main__':#执行层
    target = 'https://book.qidian.com/info/1024995653#Catalog'
    dlObj = downloader(target)
    dlObj.GetChapterInfo()
    print('开始下载:')
    for i in range(dlObj.chapterNum):
        try:
            dlObj.writer( 'test.txt',dlObj.chapterNames[i], dlObj.GetChapterContent(dlObj.chapterHrefs[i]))
        except Exception:
            print('下载出错,已跳过')
            pass
        sys.stdout.write("  已下载:%.3f%%" %  float(i/dlObj.chapterNum) + '\r')
        sys.stdout.flush()
    print('下载完成')
  • 10
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
好的,这里提供一个简单Python爬取起点中文网月票榜数据并生成可视化图的示例代码,需要使用到requests、beautifulsoup4和matplotlib库。 首先,我们需要发送HTTP请求获取月票榜页面的HTML源码,然后使用beautifulsoup4库解析HTML源码,提取有用的数据。代码如下: ```python import requests from bs4 import BeautifulSoup import matplotlib.pyplot as plt # 发送HTTP请求,获取月票榜页面的HTML源码 url = 'https://www.qidian.com/rank/yuepiao' response = requests.get(url) html = response.text # 使用beautifulsoup4库解析HTML源码,提取有用的数据 soup = BeautifulSoup(html, 'html.parser') book_list = soup.select('.book-mid-info') titles = [] month_tickets = [] for book in book_list: title = book.select_one('.title').text.strip() titles.append(title) month_ticket = int(book.select_one('.month-ticket').text.strip()) month_tickets.append(month_ticket) ``` 接下来,我们可以使用matplotlib库将月票榜数据可视化,绘制条形图或饼图等不同类型的图表。代码如下: ```python # 使用matplotlib库将月票榜数据可视化,绘制条形图 plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文显示 plt.bar(range(len(titles)), month_tickets) plt.xticks(range(len(titles)), titles, rotation=90) plt.title('起点中文网月票榜') plt.xlabel('小说名称') plt.ylabel('月票数') plt.show() # 使用matplotlib库将月票榜数据可视化,绘制饼图 plt.pie(month_tickets, labels=titles, autopct='%1.1f%%') plt.title('起点中文网月票榜') plt.show() ``` 通过这段代码,我们可以爬取起点中文网月票榜数据,并将数据可视化为条形图或饼图,更加直观地了解小说的排名情况和月票数。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sakuyooo

给住在深圳河里的水吗喽赏点零食

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值