爬虫/送给Gakki的睡前故事

去社区提问

简介:爬虫应用千千万,今天带你一起用爬虫自动爬取睡前小故事,自动发送给女朋友,想get新的恋爱小方法吗?快进入今天的课堂吧。

送给Gakki的睡前故事

爬取故事网页

我的一个程序员小伙伴阿亮前段时间刚刚告别母胎solo,拥有了甜甜的爱情,心想终于要过上迎娶白富美,走上人生巅峰的美好生活了。

然而这几天却遇到了一些‘甜蜜的负担’。

原来他的女朋友结衣(别问为什么叫结衣,是他强烈要求在这里用结衣这个名字的)要求阿亮每晚忙完后给她讲一个睡前故事。

想要每天都找到有趣的故事是一件耗费时间的事情,再加上阿亮同学这些天经常加班到头秃,回到家倒头就睡,忘记自己还有讲睡前故事的这项作业没完成。

接下来会发生什么相信你们都已经猜到了。

怎么面对发脾气的女朋友,这也是一门必修课,且挂科率极高。

女朋友纠结在‘你是不是不爱我,不然为什么记不住我说的话?’阿亮只能拼命讲道理,说来说去更是乱七八糟。

看到这里男生们是不是有这样的内心os:‘代入感很强,我已经开始跪搓衣板了’

这么一点小小的困难怎么可能难得住阿亮?他写了段代码每天爬取睡前故事,再发送到女朋友的邮箱,再也不用因为这件事情跟女朋友打辩论赛了。

现在我就偷偷把阿亮的独门绝技传授给你。为家庭和社会和谐贡献出自己的一份力量,请叫我红领巾。

什么?还没体会过爱情的苦?别着急,迟早的事儿,先学起来备用,到时候才不会手忙脚乱。

好了话不多说,马上跟我一起get恋爱小技能,哦不,是新的Python知识点~

首先来整理一下思路,完成这个任务需要以下步骤:

  1. 选择要爬取故事的网站
  2. 爬取网页内容
  3. 提取网页中故事主体内容
  4. 发送邮件

特别提示:如果暂时不理解代码的含义也没有关系~只通过这些案例了解Python用途就达到了目标。下节课开始将进入详细的Python语法学习,要继续加油呀。

爬取网页内容

首先来确定我们爬取素材的网站,从哪里能获取到大量的故事资源呢?转念一想,面向儿童的睡前故事可能比较适用,于是准备从儿童睡前故事中取材,搜索之后发现有一个适合提取睡前故事的网址:

一共有700则小故事,嗯,一天一则数量可以满足,格式也比较统一,那么就决定用它了~

首先来构建一个爬取函数,它的作用是爬取指定网页的内容。这个方法需要读入网页的统一资源定位符

爬虫爬取的对象是网络资源。如果把互联网比作一个城市,互联网中许许多多的网络资源就像是城市许许多多的住户。如果想要拜访某家住户,就必须知道这家的邮编街道门牌号。

类似的,想要访问某个网络资源,也必须知道它的在互联网上的地址——也就是咱们平时说的网址。

或许你有印象,当我们使用浏览器打开一个网页时,会发现网址栏是长这样的。

我们平时说的网址,一般是指www.xiaoxiangxueyuan.com 这一部分。

那么前面的http是干什么的呢?它是一种常见的协议类型——超文本传输协议(Hyper Text Transfer Protocol)的英文缩写。

协议对应网络资源的访问方法。如果依然使用城市和住户的例子,协议就规定着你拜访某家住户时,是要敲门还是要按门铃,是用钥匙还是输入密码。 协议加上网址,就是一个完整的统一资源定位符(Uniform Resource Locator),简称url。url是指每一网络资源在互联网上的唯一地址,有着统一的格式。

有时候,我们网址的开头并不是http,而是像上图中给出的https。https是超文本传输安全协议的缩写,其中的s代表安全(secure)。

下面的这段代码用来构建爬取函数,读入url,返回url中的内容。

  1. import requests
  2. def getHTMLText(url):
  3. headers = {'User-Agent':'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',}
  4. try:
  5. r=requests.get(url,headers=headers,timeout=30)
  6. r.raise_for_status()
  7. r.encoding=r.apparent_encoding
  8. return r.text
  9. except:
  10. return "爬取失败"

这里用到的requests模块,可以帮助我们通过网络连接获取网页内容,即以html语言写成的网页源代码。

什么?这句话好像有点儿没太看懂?没关系,这里先挖一个小坑,等下我再带你一起填平它。

从网站的睡前故事资源中随机抽取一个幸运小故事作为今天发送的内容。

利用下面这段代码取出一个30以内的随机数,决定幸运小故事从第几页产生,将得到的随机数结果存放在page_num这个变量中。

  1. import random
  2. page_num = random.randint(1,30)
  3. print('从第{}页取故事...'.format(page_num))

通过上面的代码随机挑选到了选择故事的页数:page_num,下面利用页码数拼接出对应的链接地址。

+加号在Python中不仅可以实现数字加法,还能完成字符串的拼接工作,这样一来就能轻松得到url了:

  1. if page_num==1:
  2. url='http://www.tom61.com/ertongwenxue/shuiqiangushi/index.html'
  3. else:
  4. url = 'http://www.tom61.com/ertongwenxue/shuiqiangushi/index_'+str(page_num)+'.html'
  5. print("将要爬取:", url)

还记得一开始我们定义的爬取函数吗?获取到url之后,就可以利用它来爬取链接的网页内容啦。

下面我们调用getHTMLText()方法,爬取网页内容,并将爬取到的内容打印出来查看:

代码练习:

编程区

  1. html=getHTMLText(url)
  2. print(html)

终端区

提取故事主体内容

这…这些看起来让人眼花缭乱的东西是什么?我的小故事在哪儿?

还记得前面没填上的小坑吗,刚才我们提到:requests模块,通过网络连接获取网页内容,也就是得到html语言写成的网页源代码。

虽然我们平时看到的网页的内容花花绿绿,可是创建者在编写它的时候其实是用html语言来组织的,而网络信息资源的本质也就是一个又一个的html文件。

所以现在你看到的这些‘眼花缭乱’的内容就是html语言写出的代码。

html文件本身是一长串字符串,使用一些尖括号包含的html标签<标签的名字>来表示特定的数据。例如,<title>xxx</title>意味着html在这里表示的是一个标题(title)内容(一个文本资源),这个内容是xxx。

爬虫或者浏览器对服务器发送的一次请求,会得到一个完整的html回复,是一个完整的html文件。这个html文件使用<html> 和 </html> 分别标志着开始和结束。

下面我们可以用html写一个简单的小例子。

html代码是下面这样子的,用一些尖括号包含的标签指定内容:

网页展示出的效果如下:

现在你应该大概明白,想要得到结果还需要我们对当前网页内容进行进一步处理。

对获得的网页内容进行处理,这里使用到BeatifulSoup4模块,它的主要的功能也是解析和提取html数据。

下面这段代码使用BeautifulSoup解析html内容,将链接放入列表urllist中。

代码练习:

编程区

  1. import bs4
  2. base_url='http://www.tom61.com/'
  3. soup=bs4.BeautifulSoup(html,'lxml')
  4. txt_box=soup.find('dl',attrs={'class':'txt_box'})
  5. a_tags=txt_box.find_all('a')
  6. urllist=[]
  7. for link in a_tags:
  8. urllist.append(base_url+link.get('href'))
  9. print('获取链接列表:', urllist)

终端区

这样一来urllist这个列表容器中就存放了刚才我们随机选择的页数page_num中所有小故事的统一资源定位符url。

接下来从中随机取出一个作为今晚发送给Gakki的幸运小故事~

代码练习:

编程区

  1. story_item = random.choice(urllist)
  2. print(story_item)

终端区

调用getHTMLText()爬取该网页内容:

代码练习:

编程区

  1. html=getHTMLText(story_item)
  2. print(html)

终端区

接下来对网页内容进行处理,将故事主体内容提取出来,存储在contents中。

代码练习:

编程区

  1. text=[]
  2. soup=bs4.BeautifulSoup(html,'lxml')
  3. tags=soup.find('div',class_='t_news_txt')
  4. for i in tags.findAll('p'):
  5. text.append(i.text)
  6. contents = "\n".join(text)
  7. print(contents)

终端区

发送邮件

可算拿到了今晚的睡前故事,就差最后一步发送邮件啦~

照例导入邮件处理模块,以contents为内容发送邮件给女盆友就大功告成!

代码练习:

编程区

  1. import zmail
  2. # 使用邮件账户名和密码登录服务器
  3. server = zmail.server('pyxiaoxiangjun@163.com', 'VSFGFMZVREDBZHNQ')
  4. mail = {
  5. 'subject': '睡前小故事', # 邮件的标题
  6. 'content_text': contents, # 邮件的文字内容
  7. }
  8. # 发送邮件
  9. ret = server.send_mail(['xinyuanjieyi@xiaoxiangxueyuan.com'], mail)
  10. print('发送结果:', ret)

终端区

叮咚~入睡前Gakki的手机按时收到一则邮件:

阿亮同学这回翻身农奴把歌唱了,不得不感叹自己这该死的魅力啊,不愧是来自程序员小哥哥的浪漫。

恭喜你完成了Python认知打卡课全部14关的学习,为你的坚持和努力鼓鼓掌吧~

经过这些天的学习,你一定感受到了Python的神奇功能。下一步你就可以亲自进入动手实操环节,学习用代码实现更多个性化功能。小象学院有专门针对零基础同学的Python体验课;深入的数据分析,人工智能,爬虫,办公自动化等等课程,如果你有相关需求,可以联系班主任老师了解更多课程哦。

扫描下方二维码添加班主任微信

爬虫 1/3

送给Gakki的睡前故事

1.0x

恭喜完成本课时的学习!
坚持学习

行动力超过

累计学习

学习下一课时