练习一下爬虫,将笔趣阁的小说根据需求目标再爬取下来,本文仅仅学习爬虫技术,大家还是要支持一下正版网站的
思路:
主要模块
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.分布式爬虫
来源:CSDN
作者:莫莫先生
链接:https://blog.csdn.net/weixin_44835732/article/details/103051567