Python爬虫第一战 爬取小说

182 篇文章 2 订阅
39 篇文章 3 订阅

前言

本文章将通过分析爬虫的思想,再加以利用两个 Python 库,即 requests 库和 re 库,让你顺利入门爬虫,通过本篇文章,你将学会:

  • 独立做出爬取小说的爬虫
  • 利用Python取得所要信息
  • 利用Python筛选出特定信息

如果你毫无 Python 基础,可以看看我亲自写的关于 Python 的基础专栏,这样子理解本文会更加轻松,当然你要是只想了解爬虫的过程,不关注具体的代码实现,那可以不用具备 Python 基础知识。

当今互联网实在是丰富多彩,网络上的Python教程更是数不胜数,我承认自己比不过那些大V,但是我认为自己的教程的优势是:通俗易懂,贴近初学者的水平。

背景:看小说的时候虽然能免费阅读小说内容,但是因为弹窗广告的存在,阅读体验不佳。

作为一个资深小说控,我学会 Python
爬虫之前每天必做的事便是打开手机或者电脑,进入小说网站,然后再打开我喜欢看的小说,小说是免费的,但是俗话说便宜没好货,我们在享受便宜的同时,也在牺牲一部分。
比如说我看小说的时候会被广告弹框所干扰,这让我的阅读体验不佳,既然有了问题,那我们便想着去解决,所以我一开始的解决方式是给浏览器安装去广告插件,这么一做之后体验的确好了不少,但是如果是手机端,我则无法使用这个方法,并且去广告插件也不是万能的。
那么,还有什么解决方式吗?

答案是肯定的!

解决方式

现在有请我们今天的主角登场,它就是大名鼎鼎的 Python!

你一定很好奇,Python 是怎么解决这个问题的吧?

且听我慢慢道来…

思路分析: 对症下药

症:看小说的时候会被弹框广告干扰

找到了症,那接下来自然是对症下药了,且再听我慢慢道来。既然广告对阅读有干扰,那么我们自然想
到把广告去除,关键是不能用广告去除插件,那怎么办呢? 这个问题问的好,其实我们可以换个角度思考问题
你看我们的目的是获得没有广告的阅读界面,这时候很多人想到的是直接把广告去除 的确如此,但是现在无法使用去广告插件,所以此路不通。
这时候不要轻言放弃,要记住条条大路通罗马。我们可以换个角度思考 既然你广告不走,那我小说文字就走呗,这不就实现广告与纯文字分离了吗?
通过以上分析,我们找到了药!

药:把小说文字内容从小说所在地方提取出来

所以

是时候对症下药了,那么这个药是怎么制成的呢?且再听我慢慢道来!

预备知识

说明:不了解没关系,本文附有相关链接供你学习,代码实战部分也会讲解基本用法

  • requests 库

如果把requests 库比作一个人,那么它的主要工作便是取货

库的安装方法:打开命令行(cmd、terminal),运行下面的代码

pip install requests 

然后等待安装完成,出现 successfully 说明安装成功。

  • re 库

如果把re库比作一个人,那么它的主要工作便是从给定信息中提取出特定信息

实战部分

爬虫,说白了就是利用技术去获取位于网络上的信息,就像你要找一本书一样,你若想找到书,就得知道它的位置,在网络中,信息的位置被称为 URL

URL 标记着信息的位置,故此,我们要想获得想要的信息们需要知道信息的 URL,那么我们怎么获得 URL 的呢?凭空臆想自然是不行的咯!虽然可能成功,但成功概率非常低!

说到获取 URL 就不得不谈到 ’归纳推理‘这一方法,它与人类的发展息息相关,因为人类可以通过归纳,在大量的基本数据支持下,合理地归纳出某个事物的特点。

例如

通过观察人类的行走方式,可以归纳出人类具有直立行走的特点

那归纳推理在爬虫中是怎么应用的呢?

我们不妨回忆以下看小说的部分流程

  1. 打开小说网站
  2. 点击要看的书籍并进入章节目录
  3. 点开具体章节开始小说正文的阅读

这是一个通用流程,下面我们来具体化流程

1.打开笔趣阁( http://www.xbiquge.la)
2.点击小说《三寸人间》( http://www.xbiquge.la/10/10489/)并看到章节目录
3.点击第一章 “我要减肥”( http://www.xbiquge.la/10/10489/4535761.html )开始阅读

你一定会想,这哪有体现归纳推理呢?

别急,且再听我慢慢道来,归纳推理是建立在样本足够多的基础上,上面我给的小说章节 URL 还不够多,所以我再给几个:

  第一章小说地址:http://www.xbiquge.la/10/10489/4535761.html
    第二章小说地址:http://www.xbiquge.la/10/10489/9683462.html
    第三章小说地址:http://www.xbiquge.la/10/10489/9687224.html

3 个或许不算多,但我相信以你的冰雪聪明,一定已经发现这 3 个 地址的共性了吧? 好,接下来让我们 求同存异

同:
http://www.xbiquge.la/10/10489/
异:
4535761.html
9683462.html
9687224.html

所以如果我们用 x 来代表小说章节 URL 的共性,y 代表不同点,z 代表小说章节完整 URL 那么应该有:

z=x+y

x 我们已经知道了,所以要求 z,当然是要去求 y,那么 y 是怎么求的呢? 这就用到我们的 requests 库了,它在本文的爬虫中的作用是向某个地址发送请求(就像你用浏览器打开网页那样,只不过没有图形界面和一些动态元素),然后获得相关信息。

打个比方

requests是一个人,它具有取货的能力,如果你告诉它货物所在地址,它可以帮你去把货物取回来,取货物用到 的方法是 get 或许你还不理解,没关系,下面有相应的解释
回到求解 y 的问题,求解 y 得知道它在哪里对吧?

那么 y 在哪里呢?

我们回忆一下看小说的第 2 步,即

点击要看的书籍并进入章节目录

这一步骤中,如果我们点击章节目录中的任意章节,我们很快就能看到小说内容

做出猜想

小说章节这一货物的地址存放在小说目录这个仓库中

那怎么验证猜想的正确性呢?

当然是使用我们的 requests 库咯!

获取章节地址的思路

通过requests这个人访问小说总目录这一大仓库,然后从仓库中取货,这样便得到小说章节地址这些货物

请看代码

#导入requests这个人,让他帮我们取货
import requests 
#这是书籍的地址
book_url='http://www.xbiquge.la/10/10489/'

#通过requests库的get方法向小说目录地址发送请求,即让requests这个人去book_url这个地址取货
response_1=requests.get(book_url)

#设定编码,因为网址用 utf-8 编码,不然会导致中文显示乱码
#通俗地说那就是requests这个人与仓库语言不同,沟通有障碍,所以通过 encoding这个方法来同化沟通语言
response_1.encoding='utf-8'

#输出货物部分信息
print(response_1.text)
#部分结果
'''
<dd><a href='/10/10489/4534454.html' >写在连载前</a></dd>
                <dd><a href='/10/10489/4535761.html' >第一章 我要减肥!</a></dd>
                <dd><a href='/10/10489/9683462.html' >第二章 王宝乐,你干了什么!</a></dd>
                <dd><a href='/10/10489/9687224.html' >第三章 好同学,一切有我!</a></dd>
'''

仔细看我们便发现 y 隐藏在形如下面的文本中

<dd><a href='/10/10489/4535761.html' >

所以我们找到了y所在位置,验证前面的猜想的正确性!

接下来要做的便是把它揪出来,那怎么把它揪出来呢?这就轮到我们的re库登场了!

re库的简略介绍

re也是一个人。它的工作是审阅信息,而如果你要叫它帮你办事,你需要知道怎么和它沟通,它有 自己的语言,明白它的语言之后才能给它分配任务
下面简略介绍它的语言: 符号 . 对于我们而言是一个单纯的英文句号,但在re这个人的认知里,它代表着任意符号(除了换行符) 符号 *
对于我们而言是一个单纯的星号,但在re这个人的认知里,它代表着任意多个字符 例如 : 你好* 上面的三个字符对于re这个人而言,它的理解有:
你 你好 你好好 你好好好 … 这下子你明白了吧? 符号 () 对于我们而言是单纯的括号,而在re这个人的认知里,它的作用是吧
()里面的内容包围起来, 下面会有实例介绍 注: (.*?) 这个表达式可以匹配任意文本,后面会多次涉及

请看编写正则表达式的代码:

#匹配形如 /10/10489/9683462.html 的内容的正则表达式
regx="<dd><a href='(.*)' >"

chapter_href_list=re.findall(regx,response_1.text)
'''
函数使用说明,re是个人,通过 .这个符号可以找到它具有的能力,.后面的findall表示筛选信息这个能力
要使用findall这个能力,我们需要在括号里面的第一个参数位置填写筛选的方法,即正则表达式,第二个参数
是筛选的信息来源,这里的信息来源 response_1.text是requests这个人去小说章节总目录这个仓库中提取到
的货物
'''
print(chapter_href_list)
#部分结果
'''
['/10/10489/4535761.html',
'/10/10489/9683462.html',
'/10/10489/9687224.html']
'''
#可以看到,匹配结果是列表类型

接下来是求解z的方法,即拼接小说具体章节URL

您瞧

#定义一个列表来存储小说章节地址
chapter_url_list=[]

#用于后面拼接小说章节地址
base_url='http://www.xbiquge.la

#遍历 chapter)href)list 中的所有元素并与 base_url 一起拼接成小说地址
for i in chapter_href_list:
#这一部分即 z=x+y
    url=base_url+i
    '''
    print(url)
    下面是 print 之后的一个结果
    http://www.xbiquge.la/10/10489/4535761.html
    '''
    chapter_url_list.appeend(url)
    #就这样,我们把所有章节的地址存进了 chapter_url_list 这个列表里面

下面是时候通过编写正则表达式来获取小说的内容和标题了,代码如下:

#以下是提取正文内容的正则表达式,是通过分析小说内容特点的源码来写的
content_regx='<br />&nbsp;&nbsp;&nbsp;&nbsp;(.*?)<br />'

'''
小说部分内容如下,
<br />&nbsp;&nbsp;&nbsp;&nbsp;好在随着他的苏醒,名叫周小雅的小白兔对他照顾无微不至,杜敏也罕见的没有与他针锋相对,这就让
<br />&nbsp;&nbsp;&nbsp;&nbsp;他唯独郁闷的,就是在之后的几天里,团队众人穿梭丛林,寻找其他同学的路上,柳道斌也不知道吃错了什么药,也许是因为之前的事情愧疚,所以一路上遇到一些小危机,总是抢着带人出手,迅速化解,使得本就虚弱的王宝乐,没有丝毫
<br />&nbsp;&nbsp;&nbsp;&nbsp;偏偏又没有出现如蛇群那般大的事件,这就让王宝乐觉得自己一身通天的本领,却没有用武之地,满是
<br />&nbsp;&nbsp;&nbsp;&nbsp;“这柳道斌再这么下去,说不定隐藏的考核分,就比我高了!”到了最后,王宝乐都焦急了,不过这种
'''

#内容特点分析
'''
    我们很容易观察到文字都包含在 <br />&nbsp;&nbsp;&nbsp;&nbsp;和<br />之间,故可以用 (.*?)
    来代表文字内容,其中 . 代表任意字符(除了换行), * 代表任意多个字符, ?代表非贪婪匹配, ()是为了将内容包含
    内容起来,使匹配结果仅包含括号里面的内容,而不包含 <br />&nbsp;&nbsp;&nbsp;&nbsp这类符号 ,
    你可以试着把()去掉,进行匹配结果对比
'''

'''
    这是小说章节名称所在位置
    <h1>正文卷 第三章 好同学,一切有我!</h1>
'''
#所以匹配出小说章节标题的正则表达式如下
title_regx='<h1>(.*?)</h1>'
#括号里面表示小说的章节标题,匹配到的结果是只含有一个元素的列表

最后,通过 requests

这个人拿着货物(小说章节)地址去提货,然后叫re这个审阅筛选人员从提取到的货物中筛选出所要信息并写入文件。

写入文件的方法

# 文件存储路径
save_path = '名称.txt'
# 打开文件
with open(save_path, 'a+') as f:
    # 写入文件
    f.write('测试')
    # 关闭文件
    f.close()
'''
通过以上代码,你将在代码文件运行目录创建一个叫做 名称.txt 的文件并把 测试 这两个字写入文件中,其中 'a+'
代表写入模式,即如果文件不存在则创建,并且内容一律添加到文件结尾,不覆盖已有内容。
'''

上面是一个代码片段,如需详细了解怎么使用 Python 操作文件,可以参考我写的教程

以下是爬取小说的完整代码(会出现漏爬的情况,再下面还有一份不会漏的)

import requests    #导入用于发送请求的库
import re    #导入筛选出小说内容的库
#小说地址,包含章节目录的信息
book_url = 'http://www.xbiquge.la/10/10489/'

#用于后面拼接小说章节地址
base_url='http://www.xbiquge.la'

'''
    第一章小说地址:http://www.xbiquge.la/10/10489/4535761.html
    第二章小说地址:http://www.xbiquge.la/10/10489/9683462.html
    第三章小说地址:http://www.xbiquge.la/10/10489/9687224.html
'''

#response_1 是通过 requests 库 get 方法向小说网址发出请求之后得到的响应,而 response_1.text 表示纯文本
response_1=requests.get(book_url)

#下面一步骤是设置编码格式,因为小说采用 utf-8 编码,一般遇到乱码可以用下面一句代码来解决
response_1.encoding='utf-8'
#小说章节目录相关信息所在的文本
chapter=response_1.text
#下面的一段注释是 response_1.text 的部分内容
'''
<dd><a href='/10/10489/4534454.html' >写在连载前</a></dd>
                <dd><a href='/10/10489/4535761.html' >第一章 我要减肥!</a></dd>
                <dd><a href='/10/10489/9683462.html' >第二章 王宝乐,你干了什么!</a></dd>
                <dd><a href='/10/10489/9687224.html' >第三章 好同学,一切有我!</a></dd>
'''

regx="<dd><a href='(.*)' >"
#该正则表达是获取形如 /10/10489/9683462.html 格式的文本,用于后期拼接成小说具体章节地址
chapter_href_list=re.findall(regx, response_1.text)

#定义一个列表来存储小说章节地址
chapter_url_list=[]
#遍历 chapter)href)list 中的所有元素并与 base_url 一起拼接成小说地址
for i in chapter_href_list:
    url=base_url+i
    chapter_url_list.append(url)

#以下是提取正文内容的正则表达式,是通过分析小说内容特点的源码来写的
content_regx='<br />&nbsp;&nbsp;&nbsp;&nbsp;(.*?)<br />'

'''小说部分内容如下,
<br />&nbsp;&nbsp;&nbsp;&nbsp;好在随着他的苏醒,名叫周小雅的小白兔对他照顾无微不至,杜敏也罕见的没有与他针锋相对,这就让
<br />&nbsp;&nbsp;&nbsp;&nbsp;他唯独郁闷的,就是在之后的几天里,团队众人穿梭丛林,寻找其他同学的路上,柳道斌也不知道吃错了什么药,也许是因为之前的事情愧疚,所以一路上遇到一些小危机,总是抢着带人出手,迅速化解,使得本就虚弱的王宝乐,没有丝毫
<br />&nbsp;&nbsp;&nbsp;&nbsp;偏偏又没有出现如蛇群那般大的事件,这就让王宝乐觉得自己一身通天的本领,却没有用武之地,满是
<br />&nbsp;&nbsp;&nbsp;&nbsp;“这柳道斌再这么下去,说不定隐藏的考核分,就比我高了!”到了最后,王宝乐都焦急了,不过这种
'''
#内容特点分析
'''
    我们很容易观察到文字都包含在 <br />&nbsp;&nbsp;&nbsp;&nbsp;和<br />之间,故可以用 (.*?)
    来代表文字内容,其中 . 代表任意字符(除了换行), * 代表任意多个字符, ?代表非贪婪匹配, ()是为了将内容包含
    起来,使匹配结果仅包含括号里面的内容
'''


'''
    这是小说章节名称所在位置
    <h1>正文卷 第三章 好同学,一切有我!</h1>
'''
#所以匹配出小说章节标题的正则表达式如下
title_regx='<h1>(.*?)</h1>'

#设置小说保存路径
##如果爬取的时候出现permission deny,请修改下面的sava_path,例如可以直接修改为 save_path="三寸人间.txt"
#这样以后爬取的小说会与Python文件保存在同一个路径
save_path='三寸人间.txt'

#定义一个变量来计数已经爬取的小说的数目
count=0
##如果爬取的时候出现permission deny,请修改上面的sava_path,例如可以直接修改为 save_path="三寸人间.txt"
#这样以后爬取的小说会与Python文件保存在同一个路径
#with open 语句的作用是在 C 盘创建一个叫做三寸人间.txt 的文件,'a+'表示文件以追加的形式写入,
#encoding="utf-8"是为了防止写入错误
with open (save_path,'a+',encoding="utf-8") as f:
#从存放小说章节地址的列表中依次去除小说地址,让requests通过get方法去取货
    for x in chapter_url_list:
        #向小说章节所在地址发送请求并获得响应
        response_2=requests.get(x)

        #设定编码,解决乱码
        response_2.encoding='utf-8'

        #小说标题,匹配到的是列表
        title=re.findall(title_regx, response_2.text)

        #正文内容,匹配到的是列表
        content=re.findall(content_regx, response_2.text)

        #写入小说标题
        f.write('--------'+title[0]+'--------'+'\n')

        #将小说内容这个列表中的所有元素写入文件,每写入一个就换一次行
        for e in content:
            f.write(e+'\n')
        #每成功写入一章 count 就加 1
        count+=1
        # format函数用于格式化输出
        print('第{}章爬取完毕!'.format(count))

最后

另外怕大家不会使用,直接给大家准备了写好的,直接下载打开即可使用!
源码放在百度云盘上了需要可以微信扫描下方CSDN官方认证二维码免费领取

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python爬虫可以用来抓取网页数据,包括西藏地区的天气情况。不过请注意,直接爬取网站的数据可能涉及到隐私和版权问题,最好先确认目标网站的Robots协议,以及是否允许爬虫访问。以下是一个基本的步骤来使用Python(比如使用`requests`和`BeautifulSoup`库)来获取天气信息: 1. 寻找API或提供数据的稳定源:有些天气预报网站可能提供了API服务,可以直接调用获取数据,例如中国气象局的API(http://data.cma.cn/)或者第三方天气服务提供商。 2. 如果没有API,可能需要解析HTML:使用`requests`库获取网页内容,然后使用`BeautifulSoup`或`lxml`等库解析HTML,找到包含天气信息的部分。 3. 数据提取:定位到天气预报、温度、日期等关键信息元素,并提取出来。 4. 存储或处理数据:将提取的数据存储到本地文件或者数据库中,也可以进一步分析和可视化。 以下是一个简单的示例代码片段(假设使用了第三方API): ```python import requests # 假设使用了requests_weather库,实际使用请根据实际情况替换 response = requests.get("https://api.weather.com/v3/wx/forecast/daily/point/TIBA:0,91.12") data = response.json() # 提取天气数据 temperature = data['forecasts']['temperature'] description = data['forecasts']['text'] print(f"西藏拉萨的天气情况:{description}, 温度:{temperature}") # 注意:以上代码是假设的,实际操作请根据API文档进行 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值