使用python爬取小说

部署运行你感兴趣的模型镜像

使用python爬虫爬取小说

喜欢看网络小说的朋友们,经常需要从网上下载小说。有些人不想向正版网页交钱,也不想注册其他网站的账号,那么对于某些比较冷门的小说或者是正在更新的小说来说,就很难下载到txt或者其他格式的小说。我就是不想花太多时间找冷门小说的下载资源,因此稍微学习了python的爬虫知识。

新建scrapy爬虫项目

scrapy是python的爬虫框架。使用以下语句安装scrapy。

pip install scrapy

安装完成后,打开命令行窗口,转到你想建立project的目录下,使用下面这句话新建scrapy项目。

scrapy startproject ebook

新建后就会出现一些基础代码框架。然后,

cd ebook
scrapy genspider example example.com

使用genspider根据模板创建一个爬虫,在项目的spider目录下就会多一个example.py文件

实例一

第一个例子,我选取了起点中文网。在起点上随便选择了一本小说。

权限之主.png

scrapy genspider qxzz qidian.com

使用这句话创建了qxzz.py文件。打开后,如下图。

qxzz.png

将start_urls中的内容改为这本小说的地址。然后,打开浏览器右上角“更多工具”——>“开发者工具”(chrome)就可以看到下图的样子。

爬取章节地址

打开浏览器右上角“更多工具”——>“开发者工具”(chrome)就可以看到下图的样子。gdgj.png

在右边的窗口中找到目录所在的标签。就在下图的第一个方框中,每一章节的内容在第二个方框中。

content.png

# -*- coding: utf-8 -*-
import scrapy

class QxzzSpider(scrapy.Spider):
    name = 'qxzz'
    allowed_domains = ['qidian.com']
    start_urls = ['https://book.qidian.com/info/1011146676/']

    def parse(self, response):
        # 获取目录列表
        pages = response.xpath('//div[@id="j-catalogWrap"]//ul[@class="cf"]/li')
        for page in pages:  # 遍历子节点,查询li标签内a子节点的href属性
            url = page.xpath('./child::a/attribute::href').extract_first()
            print url

程序编写完之后,在命令行运行下面语句查看结果

scrapy crawl qxzz

输出结果如下

Scrapy_content.png

如果你碰到“No module named win32api”的错误,pip install pypiwin32 即可。

爬取每章内容

text.png

从图中我们可以看出,整个章节在main-text-wrap标签(即第一个框)中,章节名在第二个框中,正文在第三个框中。修改后的代码如下。

# -*- coding: utf-8 -*-
import scrapy

class QxzzSpider(scrapy.Spider):
    name = 'qxzz'
    allowed_domains = ['qidian.com']
    start_urls = ['https://book.qidian.com/info/1011146676/']

    def parse(self, response):
        pages = response.xpath('//div[@id="j-catalogWrap"]//ul[@class="cf"]/li')
        for page in pages:
            url = page.xpath('./child::a/attribute::href').extract_first()
            req = response.follow(url, callback=self.parse_chapter)
            yield req

    def parse_chapter(self, response):
        title = response.xpath('//div[@class="main-text-wrap"]'
                               '//h3[@class="j_chapterName"]/text()')\
            .extract_first().strip()
        content = response.xpath('//div[@class="main-text-wrap"]'
                                 '//div[@class="read-content j_readContent"]')\
            .extract_first().strip()

内容的保存

在爬取内容后,可以以html的形式保存。而为了排序的方便,需要给文件名加一个序号。在起点网上,刚好在li标签内有“data-rid”可以作为序号。修改后代码如下。

# -*- coding: utf-8 -*-
import scrapy

class QxzzSpider(scrapy.Spider):
    name = 'qxzz'
    allowed_domains = ['qidian.com']
    start_urls = ['https://book.qidian.com/info/1011146676/']

    def parse(self, response):
        pages = response.xpath('//div[@id="j-catalogWrap"]//ul[@class="cf"]/li')
        for page in pages:
            url = page.xpath('./child::a/attribute::href').extract_first()
            idx = page.xpath('./attribute::data-rid').extract_first()
            req = response.follow(url, callback=self.parse_chapter)
            req.meta['idx'] = idx
            yield req

    def parse_chapter(self, response):
        idx = response.meta['idx']
        title = response.xpath('//div[@class="main-text-wrap"]'
                               '//h3[@class="j_chapterName"]/text()')\
            .extract_first().strip()
        content = response.xpath('//div[@class="main-text-wrap"]'
                                 '//div[@class="read-content j_readContent"]')\
            .extract_first().strip()
        filename = './down/%s_%s.html' % (idx, title)
        cnt = '<h1>%s</h1> %s' % (title, content)
        with open(filename, 'wb') as f:
            f.write(cnt.encode('utf-8'))

记住,需要现在目录下新建down文件夹,否则可能会出错。

同一个网站,电子书网页的源代码架构都应该是一样的,因此,只需改变一条网址的语句,就可以爬取该网站的其他电子书。

在爬取结束并且保存后,可以通过Sigil来制作epub电子书,也可以转换成其他格式。

实例二

第二个例子没有新的知识,只是为了更加熟悉这些内容。

第二个例子选择的是下面这本小说。

content.png

目录和正文内容所在的标签都在下面的图中框出。

chapter.png

text.png

# -*- coding: utf-8 -*-
import scrapy
from numpy import *

class DmhsSpider(scrapy.Spider):
    name = 'dmhs'
    allowed_domains = ['m.x23us.com']
    start_urls = ['https://m.x23us.com/html/51/51940/']

    def parse(self, response):
        pages = response.xpath('//div[@class="cover"]//ul[@class="chapter"]/li')
        # pages = response.xpath('//ul[@class="chapter"]/li')
        for page in pages:
            url = page.xpath('./child::a/attribute::href').extract_first()
            idx = str(url[0:8])
            req = response.follow(url, callback=self.parse_chapter)
            req.meta['idx'] = idx
            yield req

    def parse_chapter(self, response):
        idx = response.meta['idx']
        title = response.xpath('//div[@class="content"]//h1[@id="nr_title"]/text()')\
            .extract_first().strip()
        content = response.xpath('//div[@class="content"]//div[@class = "txt"]')\
            .extract_first().strip()
        filename = './down/%s_%s.html' % (idx, title)
        cnt = '<h1>%s</h1> %s' % (title, content)
        with open(filename, 'wb') as f:
            f.write(cnt.encode('utf-8'))

在这个网站中,没有类似“data-rid”的东西,但又发现每章节的网页地址的数字是随章节号而递增的,因此截取网页地址中的数字来排序保存后的html文件。其他都与例子一相同。

结语

需求才是学习的动力啊。

版本信息

1.0 20180209

知识共享许可协议
本作品采用知识共享署名-相同方式共享 3.0 未本地化版本许可协议进行许可。

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

以下是两段不同的使用 Python 爬取小说的源代码示例: ### 第一段代码 该代码使用 `urllib` 库和 `re` 正则表达式实现小说爬取的功能,获取小说信息和各章节链接并打印章节页面的 HTML 内容: ```python from urllib import request import re first_url = "http://www.freexs.org/novel/0/896/" html = request.urlopen(first_url).read().decode('gbk') novel_info = {} novel_info['title'] = re.findall(r'<meta name="keywords" content=(.*?)>', html) # print(novel_info['title'][0]) div_info = re.findall(r'<table width="100%"><tr><td><dl>(.*?)</div>', html) tag_a = re.findall(r'<dd><a(.*?)</a></dd>', div_info[0]) for i in range(0, len(tag_a)): second_url = re.findall(r'href="(.*?)">', tag_a[i])[0] # print(second_url) url = "%s%s" % (first_url, second_url) # print(url) html2 = request.urlopen(url).read().decode('gbk') print(html2) ``` 此代码的主要逻辑是先打开小说的主页面,获取小说信息和章节链接,然后遍历每个章节链接,打开章节页面并打印其 HTML 内容 [^2]。 ### 第二段代码思路(未完整实现) 该代码思路是使用 `requests` 库和正则表达式爬取小说各章节内容,以下是部分实现思路代码示例: ```python import requests import re # 假设这是获取到的所有章节链接列表 chapter_links = [] # 这里需要根据实际情况填充章节链接 # 匹配文章内容的正则表达式 content_pattern = r'.*?id="content">(.*?)</div>' for link in chapter_links: full_url = "http://www.paoshu8.com" + link # 拼接完整的 URL response = requests.get(full_url) if response.status_code == 200: html = response.text content_match = re.search(content_pattern, html) if content_match: content = content_match.group(1) print(content) ``` 此代码思路是循环遍历所有章节链接,请求每个章节页面,然后使用正则表达式提取章节内容并打印 [^4]。
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值