爬虫练习-爬取笔趣阁小说

练习一下爬虫,将笔趣阁的小说根据需求目标再爬取下来,本文仅仅学习爬虫技术,大家还是要支持一下正版网站的

思路:

Created with Raphaël 2.2.0 开始 输入书名 查询小说是否存在 跳转页面至小说主页 获取小说目录URL 解析小说内容并保存至word 结束 yes no

主要模块

Xpath(lxml)
requests
docx(Document)
parse(urllib)

第一步、输入所要爬取的书名,并判断其是否存在

由笔趣阁的搜索页面可以分析出,我们输入的书名被转换为URL编码的格式。其实是按照标准, URL 只允许一部分 ASCII 字符(数字字母和部分符号),其他的字符(如汉字)是不符合 URL 标准的。所以 URL 中使用其他字符就需要进行 URL 编码。
爬虫练习-爬取笔趣阁小说_第1张图片
那我们根据要求,将其转换一下格式
PS:此处,笔者为大家踩个坑,这个网页是将我们输入的书名先转换为了gbk编码,所以我们也先要转换过来

 book_name = parse.quote(book_name.encode('gbk'))

下面是笔者乱搜了一个书名,与此前搜索的‘《圣墟》’时有明显区别,此处的

下只有一个 li,显然我们可以通过判断 li里的相关值或属性的有无进而判断书的有无
爬虫练习-爬取笔趣阁小说_第2张图片

    if(root.xpath('//div[@class="search-list"]/ul/li/span/a/@href[1]') == []):
        print('搜索的书不存在,请正确输入书名')
    else:
        print('找到了作者为', root.xpath('//div[@class="search-list"]/ul/li/span[@class="s4"]/text()')[0],
              ',书名为《', root.xpath('//div[@class="search-list"]/ul/li/span/a/text()')[0], '》,请问是否下载[Y][N]'
              , end='')

这里,加入了人为的判断,通过反馈搜索出的第一本的作者及书名,询问是否下载,以确保爬取的书籍的正确性

第二步、跳转至小说主页,并收集目录的url

爬虫练习-爬取笔趣阁小说_第3张图片
下面是通过Xpath解析得出的小说主页的URL代码

root.xpath('//div[@class="search-list"]/ul/li/span/a/@href')[0]

接下来就是收集目录的url的列表了
在笔趣阁网站中,通过观察多数的小说在目录页都有十二章的最新章节提示
爬虫练习-爬取笔趣阁小说_第4张图片
而我们所求是从第一章按顺序爬取,很简单,我们爬取时就略过前面十二个

标签

爬虫练习-爬取笔趣阁小说_第5张图片
通过切片的方式,略过前面十二章

    s_list = root.xpath('//div[@class="listmain"]/dl/dd/a/@href')
    for dd_url in s_list[12:]:

第三步、下载小说章节内容

有小说章节的目录了,那么接下来我们就完成一下最后一步,下载小说内容
爬虫练习-爬取笔趣阁小说_第6张图片
通过网页源码的分析,我们知道小说的内容都在

中,我们只需要将其中的内容保存到文本中就大功告成

    html = requests.get(url, headers)
    root = etree.HTML(html.content)
    text_name = root.xpath('//div[@class="content"]/h1/text()')[0]
    texts = root.xpath('//div[@class="showtxt"]/text()')
    document = Document()
    for text in texts:
        document.add_paragraph(text)
    print('《' + text_name + '》已下载完成', end='')

补充(完整代码)

import os
import requests
from lxml import etree
from docx import Document
from urllib import parse

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'}


# 查询小说
def search_book():
    url = 'https://so.biqusoso.com/s.php?ie=gbk&siteid=biqugex.com&s=9157106854577873494&q='

    book_name = input('请输入你想要爬取的小说:')

    # 对输入的字符进行编码转换为gbk编码,再对其进行url编码操作
    book_name = parse.quote(book_name.encode('gbk'))

    book_url = url + book_name
    return book_url


# 判断是否有书,并提示是否下载
def find_book(book_url):
    # 调用查找search_book()函数 查找跳转至相应界面
    url = book_url

    # 请求页面
    html = requests.get(url, headers)
    root = etree.HTML(html.content.decode('utf-8'))

    # 处理异常 未找到书籍时返回提示
    if(root.xpath('//div[@class="search-list"]/ul/li/span/a/@href[1]') == []):
        print('搜索的书不存在,请正确输入书名')
    else:
        print('找到了作者为', root.xpath('//div[@class="search-list"]/ul/li/span[@class="s4"]/text()')[0],
              ',书名为《', root.xpath('//div[@class="search-list"]/ul/li/span/a/text()')[0], '》,请问是否下载[Y][N]'
              , end='')
        In = input()
        if In == 'Y' or In == 'y':

            # 创建以书名命名的文件夹
            path = '《' + str(root.xpath('//div[@class="search-list"]/ul/li/span/a/text()')[0]) + '》'
            if not os.path.exists(path):
                os.mkdir(path)

            book_content_list(root.xpath('//div[@class="search-list"]/ul/li/span/a/@href')[0])


# 获取目录的URL 并调用download_book()函数下载内容
def book_content_list(url):
    html = requests.get(url, headers)
    root = etree.HTML(html.content)

    # 获取目录的URL 并传入download_book()函数
    s_list = root.xpath('//div[@class="listmain"]/dl/dd/a/@href')
    for dd_url in s_list[12:]:
        download_book('https://www.biqugex.com' + str(dd_url))
        print('  content_url:'+ 'https://www.biqugex.com' + str(dd_url))


def download_book(url):
    html = requests.get(url, headers)
    root = etree.HTML(html.content)
    text_name = root.xpath('//div[@class="content"]/h1/text()')[0]
    texts = root.xpath('//div[@class="showtxt"]/text()')
    document = Document()
    for text in texts:
        document.add_paragraph(text)
    print('《' + text_name + '》已下载完成', end='')
    file_name = root.xpath('//div[@class="footer"]/p/a/text()')[0]
    document.save("{}/《{}》.docx".format(file_name, text_name))


def main():
    print("----笔趣阁小说爬虫----")
    print("1-------------搜索小说")
    print("2----------------退出")
    flag = int(input("请输入数字选择相应功能:"))
    while 1:
        if flag == 1:
            book_url = search_book()
            find_book(book_url)
        elif flag == 2:
            exit(1)
        else:
            input("请输入正确的命令:")
        flag = int(input("请重新输入数字选择相应功能:"))


if __name__ == '__main__':
    main()

思考总结

小爬虫的结构,感觉都差不了太多,获取网页、解析网页、下载三部曲,三个步骤完成,差不多任务就结束了。笔者自身的缺点:代码结构有待优化
继续学习的知识点:
1.了解反爬虫机制,并应对
2.破解一些网页常用的加密格式
3.ajax
4.分布式爬虫

你可能感兴趣的:(python,爬虫,笔趣阁爬虫,python爬虫学习)