前言:
眼前小伙伴们对“html小说”大致比较看重,你们都想要分析一些“html小说”的相关内容。那么小编同时在网上网罗了一些关于“html小说””的相关文章,希望兄弟们能喜欢,各位老铁们一起来学习一下吧!声明:本文只做学习使用,禁止用作非法途径,一切因为爬虫技术使用不当造成的不良后果皆与本人无关
需要用到的库和模块requests库lxml库下的etree模块requests库下的RequestException类私信小编01即可获取大量Python学习资料要获取的信息
网站
首先我们要确定要得到什么数据
小说的名字、作者名、小说分类第几章每章节的内容主要步骤
(一)构建请求头
headers = { 'User-Agent': '****************',#可填入自己的}base_url = ';
(二)分析URL参数规律
随便打开一个小说的章节,由此可见这个url参数是递增的是吧。
但是最开始的时候我观察到在这里的url是有递增规律的,就没有多看几眼,然后使用了遍历就发生了Error。
最终我测试发现部分章节不符合规律,所以不能使用这个方法来遍历url。
这样怎么办呢?
在目录页面拥有所有章节的url链接
可以抓取章节页面的url使之形成一个列表,然后遍历该列表,即可获取每个章节的链接
目录页面分析
根据章节的数量判断,<dd>标签一个是最合适的选择标签,所以我们使用<dd>标签来做获取章节链接的顶级索引
代码如下:
def analysis_catalogue(catalogue_html: "目录HTML文档"): ''' 解析目录HTMl文档 获取小说章节链接 对章节链接排序 ''' html = etree.HTML(catalogue_html) contentds = html.xpath('//dd[position()>9]/a/@href') for contentd in contentds: yield contentd contentus = html.xpath('//dd[position()<10]/a/@href') for contentu in contentus: yield contentu
收集小说的其他信息则比较简单,我们可直接通过属性索引
代码如下:
def analysis_get_file_name(catalogue_data: "目录HTML文档"): ''' 获取信息: 书名 作者名 类型 整理文件名:file_name ''' html = etree.HTML(catalogue_data) name_rules = [ '//meta[@property="og:novel:category"]/@content', '//meta[@property="og:novel:author"]/@content', '//meta[@property="og:novel:book_name"]/@content', ] file_name = '' for name_rule in name_rules: content = html.xpath(name_rule) print(content) file_name = file_name + '#' + ''.join(content) file_name = file_name + '.txt' return file_name章节页面分析
分析完目录,获取到所有章节的url链接,这时我们要去获取所有章节中的内容,这时我们可随意选择一章进行分析
经过分析,<h1>标签可以索引获取到章节名,而div的属性和属性值id="content"可以索引到文章的正文内容
代码如下:
def get_one_section(end_url: '每个章节的url'): '''对单元章节进行请求''' url = '; + end_url try: response = requests.get(url, headers=headers) if response.status_code == 200: return response.content.decode('utf8') else: print(response.status_code) return None except RequestException: return Nonedef analysis_one_section(one_section_data: "一个章节的HTML数据"): '''解析每个章节的数据''' html = etree.HTML(one_section_data) contents = html.xpath('//div[@id="content"]//text()') chapter_data = html.xpath('//h1/text()') print(chapter_data) yield ''.join(chapter_data) for content in contents: if content != '\n': yield content.strip()
这里的章节获取到是一个列表,写入会很不方便,所以先使用join()方法给其字符串。除此之外文章的正文部分会有部分空字符串,这时候使用strip()进行删减。yield后面是一个生成器,这样爬取不会给内存造成很大的负担
(三)写入数据
由于是要进行阅读,所以我们使用txt写入数据
def analysis_write(file_name: '写入的文件名', write_one_section_data: '要写入的单个章节的数据'): '''写入数据''' with open(file_name + '.txt', 'a+', encoding='utf-8') as file: file.write(write_one_section_data + '\n')
(四)主函数调整
主体函数进行子函数的安排调整
def main(): base_url = get_base_url() # 对章节url进行获取 catalogue_html = get_catalogue(base_url) # 请求章节页面 file_name = analysis_get_file_name(catalogue_html) # 获取小说各部分信息,构建文件名 end_urls = analysis_catalogue(catalogue_html) # 获取每个章节的url for end_url in end_urls: one_section_data = get_one_section(end_url) # 对每个url发送请求 write_one_section_datas = analysis_one_section(one_section_data) # 解析每个章节的数据 for write_one_section_data in write_one_section_datas:最终结果代码
import requestsfrom lxml import etreefrom requests import RequestExceptionheaders = { 'User-Agent': '*********************',#写自己的}base_url = ';def get_base_url(): '''获取目录链接''' print('请输入小说的base_url:') base_url = input() return base_urldef get_catalogue(base_url: "目录链接"): ''' 对目录链接的请求访问 ''' try: response = requests.get(base_url, headers=headers) print(response.status_code) if response.status_code == 200: return response.content.decode('utf-8') return None except RequestException: return Nonedef analysis_catalogue(catalogue_html: "目录HTML文档"): ''' 解析目录HTMl文档 获取小说章节链接 对章节链接排序 ''' html = etree.HTML(catalogue_html) contentds = html.xpath('//dd[position()>9]/a/@href') for contentd in contentds: yield contentd contentus = html.xpath('//dd[position()<10]/a/@href') for contentu in contentus: yield contentudef analysis_get_file_name(catalogue_data: "目录HTML文档"): ''' 获取信息: 书名 作者名 类型 整理文件名:file_name ''' html = etree.HTML(catalogue_data) name_rules = [ '//meta[@property="og:novel:category"]/@content', '//meta[@property="og:novel:author"]/@content', '//meta[@property="og:novel:book_name"]/@content', ] file_name = '' for name_rule in name_rules: content = html.xpath(name_rule) print(content) file_name = file_name + '#' + ''.join(content) file_name = file_name + '.txt' return file_namedef get_one_section(end_url: '每个章节的url'): '''对单元章节进行请求''' url = '; + end_url try: response = requests.get(url, headers=headers) if response.status_code == 200: return response.content.decode('utf8') else: print(response.status_code) return None except RequestException: return Nonedef analysis_one_section(one_section_data: "一个章节的HTML数据"): '''解析每个章节的数据''' html = etree.HTML(one_section_data) contents = html.xpath('//div[@id="content"]//text()') chapter_data = html.xpath('//h1/text()') print(chapter_data) yield ''.join(chapter_data) for content in contents: if content != '\n': yield content.strip()def analysis_write(file_name: '写入的文件名', write_one_section_data: '要写入的单个章节的数据'): '''写入数据''' with open(file_name, 'a+', encoding='utf-8') as file: file.write(write_one_section_data + '\n')def main(): base_url = get_base_url() # 对章节url进行获取 catalogue_html = get_catalogue(base_url) # 请求章节页面 file_name = analysis_get_file_name(catalogue_html) # 获取小说各部分信息,构建文件名 end_urls = analysis_catalogue(catalogue_html) # 获取每个章节的url for end_url in end_urls: one_section_data = get_one_section(end_url) # 对每个url发送请求 write_one_section_datas = analysis_one_section(one_section_data) # 解析每个章节的数据 for write_one_section_data in write_one_section_datas: analysis_write(file_name, write_one_section_data) # 向文件中写入数据if __name__ == '__main__': print('开始抓取!') main() print('结束!')效果
如有手机阅读器,支持txt文件导入的会自动编排目录,效果更好,建议导入手机阅读
如果觉得有用的话,求个点赞收藏,谢谢!
标签: #html小说 #python爬小说代码