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

梦想的初衷 提交于 2019-11-25 20:07:32

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

思路:

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

主要模块

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

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

由笔趣阁的搜索页面可以分析出,我们输入的书名被转换为URL编码的格式。其实是按照标准, URL 只允许一部分 ASCII 字符(数字字母和部分符号),其他的字符(如汉字)是不符合 URL 标准的。所以 URL 中使用其他字符就需要进行 URL 编码。


那我们根据要求,将其转换一下格式
PS:此处,笔者为大家踩个坑,这个网页是将我们输入的书名先转换为了gbk编码,所以我们也先要转换过来
 book_name = parse.quote(book_name.encode('gbk')) 

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

下只有一个li,显然我们可以通过判断li里的相关值或属性的有无进而判断书的有无

    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


下面是通过Xpath解析得出的小说主页的URL代码
root.xpath('//div[@class="search-list"]/ul/li/span/a/@href')[0] 

接下来就是收集目录的url的列表了
在笔趣阁网站中,通过观察多数的小说在目录页都有十二章的最新章节提示


而我们所求是从第一章按顺序爬取,很简单,我们爬取时就略过前面十二个<dd>标签


通过切片的方式,略过前面十二章
    s_list = root.xpath('//div[@class="listmain"]/dl/dd/a/@href')     for dd_url in s_list[12:]: 

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

有小说章节的目录了,那么接下来我们就完成一下最后一步,下载小说内容


通过网页源码的分析,我们知道小说的内容都在<div id="content" class="showtxt">中,我们只需要将其中的内容保存到文本中就大功告成
    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.分布式爬虫

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!