Python基础之爬取小说

近些年里,网络小说盛行,但是小说网站为了增加收益,在小说中增加了很多广告弹窗,令人烦不胜烦,那如何安静观看小说而不看广告呢?答案就是爬虫。本文主要以一个简单的小例子,简述如何通过爬虫来爬取小说,仅供学习分享使用,如有不足之处,还请指正。

目标页面

本文爬取的为【某横中文网】的一部小说【妙手小医仙】,已完结,共187章,信息如下:

网址:http://book.abcde.com/showchapter/1102448.html

本次主要爬取小说章节信息,及每一章对应的正文信息。章节信息如下所示:

目标分析

1. 章节目录分析

通过浏览器自带的开发人员工具【快捷键F12或Ctrl+Shift+I】进行分析,发现所有的章节都包含在ul【无序列表标签】中,每一个章节链接对应于li【列表项目标签】标签中的a【超链接标签】标签,其中a标签的href属性就是具体章节网址,a标签的文本就是章节标题,如下所示:

 

 2. 章节正文分析

通过分析,发现章节全部内容,均在div【class=reader_box】中,其中包括标题div【class=title_txtbox】,章节信息div【class=bookinfo】,及正文信息div【class=content】,所有正文包含在p【段落标签】中。如下所示:

 

 爬虫设计思路

  1.  获取章节页面内容,并进行解析,得到章节列表
  2. 循环章节列表:
    1. 获取每一章节内容,并进行解析,得到正文内容,
    2. 保存到文本文档。每一个章节,一个文档。

示例源码

获取请求页面内容,因为本例需要多次获取页面内容,所以封装为一个单独的函数,如下所示:

 1 def get_data(url: str = None):
 2     """
 3     获取数据
 4     :param url: 请求网址
 5     :return:返回请求的页面内容
 6      7     # 请求头,模拟浏览器,否则请求会返回418
 8     header = {
 9         'User-Agent': Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) '
10                       Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'}
11     resp = requests.get(url=url,headers=header)   发送请求
12 
13     if resp.status_code == 200:
14         if resp.encoding != resp.apparent_encoding:
15              如果返回的编码和页面显示编码不一致,直接获取text会出现乱码,需要转码
16             return resp.content.decode(encoding=resp.apparent_encoding)
17         else18              如果返回成功,则返回内容
19             return resp.text
20     21          否则,打印错误状态码,并返回空
22         print(返回状态码:,resp.status_code)
23         return

注意:有可能不同网站,返回内容的编码和页面显示的编码不一致,可能会出现中文乱码的情况,所以本例进行编码设置。

1. 解析章节列表

要获取整本小说内容,首先就要获取章节列表,然后保存到内存数组中,以便于获取具体正文。如下所示:

def parse_chapters(html: str =    爬取章节列表
    :param html:
    :return:
if html is None:
 8         return
 9     10         chapters = []
11         bs = BeautifulSoup(html,features=html.parser)
12         ul_chapters = bs.find(ul',class_=chapter-list clearfix13          print(ul_chapters)
14         li_chapters = ul_chapters.find_all(licol-4')   此处需要注意,页面源码查看是有空格,但是BeautifulSoup转换后空格消失
15         for li_chapter in li_chapters:
16             a_tag = li_chapter.find(a17              print(a_tag)
18             a_href = a_tag.get(href 此处也可以用a_tag['href']
19             a_text = a_tag.get_text()   获取内容:章节标题
20             chapters.append({title': a_text,: a_href})
21 
return chapters

2. 解析单个章节

当得到单个章节的链接时,就可以获取单个章节的内容,并进行解析,如下所示:

def parse_single_chapter(html: str =    解析单个章节内容
 7     bs = BeautifulSoup(html,1)"> 8     div_reader_box = bs.find(divreader_box 9     div_title = div_reader_box.find(title_txtbox10     title = div_title.get_text()   获取标题
11     div_book_info = div_reader_box.find(bookinfo12     book_info = div_book_info.get_text()
13     div_content = div_reader_box.find(content14     content = ''
15     p_tags = div_content.find_all(p16     for p_tag  p_tags:
17         content =content + p_tag.get_text() + \r\n18      content = div_content.get_text()
19     return title + \n' + book_info + ' + content

3. 循环解析并保存

循环获取单个章节正文页面,并进行解析,然后保存。如下所示:

def get_and_parser_single_chapter(chapters: list = []):
    获取单个章节
    :param chapters: 章节列表
for (index,chapter) in enumerate(chapters,1):
 8         title = chapter.get( 9         href = chapter.get(10         while True:
11             开始第%d章爬取' % index)
12             html = get_data(href)
13             is not14                 content = parse_single_chapter(html)
15                 save_data(title,content)   保存数据
16                 第%d章爬取成功17                 break
19                 第%d章爬取失败20                 time.sleep(2)

4. 整体调用逻辑

当写好单个功能函数时,顺序调用就是完整的爬虫,如下所示:

1 url = http://book.abcde.com/showchapter/1102448.html2 开始时间>>>>>"%Y-%m-%d %H:%M:%S"3 html_chapters = get_data(url)
4 chapters = parse_chapters(html_chapters)
5 get_and_parser_single_chapter(chapters)
6 结束时间>>>>>7 done')

示例截图

爬取到的小说列表,如下所示:

 

 

 每一个章节内容,如下所示:

 

 示例完整代码,如下所示:

  1 import requests   请求包  用于发起网络请求
  2 from bs4 import BeautifulSoup   解析页面内容帮助包
  3 import time
  4 
  5   6 说明:爬取小说
  7 步骤:1. 先爬取所有章节,及章节明细对应的URL
  8 2. 解析单个章节的内容
  9 3. 保存
 10  11 
 12 
 13  14      15  16  17  18      19      20     header = 21          22                        23     resp = requests.get(url=url,1)"> 24 
 25      26          27              28              29          30              31              32      33          34          35          36 
 37 
 38  39      40  41  42  43      44      45          46      47         chapters = 48         bs = BeautifulSoup(html,1)"> 49         ul_chapters = bs.find( 50          51         li_chapters = ul_chapters.find_all( 52          53             a_tag = li_chapter.find( 54              55             a_href = a_tag.get( 56             a_text = a_tag.get_text()   57             chapters.append({ 58 
 59          chapters
 60 
 61 
 62  63      64  65  66  67      68      69         title = chapter.get( 70         href = chapter.get( 71          72              73             html = 74              75                 content = 76                 save_data(title,1)"> 77                  78                  79              80                  81                 time.sleep(2 82 
 83 
 84  85      86  87  88  89      90     bs = BeautifulSoup(html,1)"> 91     div_reader_box = bs.find( 92     div_title = div_reader_box.find( 93     title = div_title.get_text()   94     div_book_info = div_reader_box.find( 95     book_info = 96     div_content = div_reader_box.find( 97     content =  98     p_tags = div_content.find_all( 99     100         content =content + p_tag.get_text() + 101     102     ' + content
103 
104 
105 def save_data(name,content):
106     107     保存数据
108     :param name: 文件名
109     :param content: 文件内容
110 111     112     with open(妙手小医仙\\' + name + .txtwutf-8) as f:
113         f.write(content)
114 
115 
116 url = http://book.zongheng.com/showchapter/1102448.html117 118 html_chapters =119 chapters =120 121 122 ')
View Code

备注

我从来不认为半小时是我微不足道的很小的一段时间。真正的强者,不是没有眼泪的人,而是含着眼泪奔跑的人。但行前路,无问西东 。

长相思·山一程

纳兰性德 【朝代】清

山一程,水一程,身向榆关那畔行,夜深千帐灯。

风一更,雪一更,聒碎乡心梦不成,故园无此声。

原文地址:https://www.cnblogs.com/hsiang

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Python中的函数(二) 在上一篇文章中提到了Python中函数的定义和使用,在这篇文章里我们来讨论下关于函数的一些更深的话题。在学习C语言函数的时候,遇到的问题主要有形参实参的区别、参数的传递和改变、变量的作用域。同样在Python中,关于对函数的理解和使用也存在这些问题。下面来逐一讲解。一.函
Python中的字符串 可能大多数人在学习C语言的时候,最先接触的数据类型就是字符串,因为大多教程都是以"Hello world"这个程序作为入门程序,这个程序中要打印的"Hello world"就是字符串。如果你做过自然语言处理方面的研究,并且用Python
Python 面向对象编程(一) 虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程。下面就来了解一下如何在Python中进行对象编程。一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法。 类是对现实世界中一些事物的封装,
Python面向对象编程(二) 在前面一篇文章中谈到了类的基本定义和使用方法,这只体现了面向对象编程的三大特点之一:封装。下面就来了解一下另外两大特征:继承和多态。 在Python中,如果需要的话,可以让一个类去继承一个类,被继承的类称为父类或者超类、也可以称作基类,继承的类称为子类。并且Pytho
Python中的函数(一) 接触过C语言的朋友对函数这个词肯定非常熟悉,无论在哪门编程语言当中,函数(当然在某些语言里称作方法,意义是相同的)都扮演着至关重要的角色。今天就来了解一下Python中的函数用法。一.函数的定义 在某些编程语言当中,函数声明和函数定义是区分开的(在这些编程语言当中函数声明
在windows下如何快速搭建web.py开发框架 用Python进行web开发的话有很多框架供选择,比如最出名的Django,tornado等,除了这些框架之外,有一个轻量级的框架使用起来也是非常方便和顺手,就是web.py。它由一名黑客所创建,但是不幸的是这位创建者于2013年自杀了。据说现在由
将Sublime Text 2搭建成一个好用的IDE 说起编辑器,可能大部分人要推荐的是Vim和Emacs,本人用过Vim,功能确实强大,但是不是很习惯,之前一直有朋友推荐SUblime Text 2这款编辑器,然后这段时间就试了一下,就深深地喜欢上这款编辑器了...
Python中的模块 有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt这个函数,必须用语句"#include<math.h>"引入math.h这个头文件,否则是无法正常进行调用的。那么在Python中,如果要引用一些内置的函数,该怎么处理呢?在Python中
Python的基础语法 在对Python有了基础的认识之后,下面来了解一下Python的基础语法,看看它和C语言、java之间的基础语法差异。一.变量、表达式和语句 Python中的语句也称作命令,比如print "hello python"这就是一条语句。 表达式,顾名思义,是
Eclipse+PyDevʽjango+Mysql搭建Python web开发环境 Python的web框架有很多,目前主流的有Django、Tornado、Web.py等,最流行的要属Django了,也是被大家最看好的框架之一。下面就来讲讲如何搭建Django的开发环境。一.准备工作 需要下载的
在windows下安装配置Ulipad 今天推荐一款轻便的文本编辑器Ulipad,用来写一些小的Python脚本非常方便。 Ulipad下载地址: https://github.com/limodou/ulipad http://files.cnblogs.com/dolphin0520/u...
Python中的函数(三) 在前面两篇文章中已经探讨了函数的一些相关用法,下面一起来了解一下函数参数类型的问题。在C语言中,调用函数时必须依照函数定义时的参数个数以及类型来传递参数,否则将会发生错误,这个是严格进行规定的。然而在Python中函数参数定义和传递的方式相比而言就灵活多了。一.函数参数的
在Notepad++中搭配Python开发环境 Python在最近几年一度成为最流行的语言之一,不仅仅是因为它简洁明了,更在于它的功能之强大。它不仅能够完成一般脚本语言所能做的事情,还能很方便快捷地进行大规模的项目开发。在学习Python之前我们来看一下Python的历史由来,"Pytho
Python中的条件选择和循环语句 同C语言、Java一样,Python中也存在条件选择和循环语句,其风格和C语言、java的很类似,但是在写法和用法上还是有一些区别。今天就让我们一起来了解一下。一.条件选择语句 Python中条件选择语句的关键字为:if 、elif 、else这三个。其基本形式如
关于raw_input( )和sys.stdin.readline( )的区别 之前一直认为用raw_input( )和sys.stdin.readline( )来获取输入的效果完全相同,但是最近在写程序时有类似这样一段代码:import sysline = sys.stdin.readline()
初识Python 跟学习所有的编程语言一样,首先得了解这门语言的编程风格和最基础的语法。下面就让我们一起来了解一下Python的编程风格。1.逻辑行与物理行 在Python中有逻辑行和物理行这个概念,物理行是指在编辑器中实际看到的一行,逻辑行是指一条Python语句。在Python中提倡一个物理行只
当我们的代码是有访问网络相关的操作时,比如http请求或者访问远程数据库,经常可能会发生一些错误,有些错误可能重新去发送请求就会成功,本文分析常见可能需要重试的场景,并最后给出python代码实现。
1.经典迭代器 2.将Sentence中的__iter__改成生成器函数 改成生成器后用法不变,但更加简洁。 3.惰性实现 当列表比较大,占内存较大时,我们可以采用惰性实现,每次只读取一个元素到内存。 或者使用更简洁的生成器表达式 4.yield from itertools模块含有大量生成器函数可
本文介绍简单介绍socket的常用函数,并以python-kafka中的源码socketpair为例,来讲解python socket的运用
python实践中经常出现编码相关的异常,大多网上找资料而没有理解原理,导致一次次重复错误。本文对常用Unicode、UTF-8、GB2312编码的原理进行介绍,接着介绍了python字符类型unicode和str以及常见编解码错误UnicodeEncodeError和UnicodeDEcodeEr