Python边学边用 - 学校新闻爬取并通过邮件发送

人生苦短,我用Python。
Python真的是很好的语言,很好用,那么我们该如何入门呢?
我觉得不用特别的学习,只要你有C/C++的一些知识,学习Python将不是一件很困难的事情。
这样一门语言,这样一个很好地工具,应该是不需要太高的学习成本的,所以我《Python边学边用》这个系列的文章,我将边用边学,可能代码不是那么“漂亮”,代码不是那么“优雅”,但是肯定实现了功能。
慢慢学,慢慢做,我会把这个工具用的越来越好。
文中描述方法不一定是最好的方法,只是我才疏学浅,自己只知道这么做能做出来,所以我就这么做了,欢迎交流批评。

要做什么

学校里有很多网站,教务处,研究生院,就业班,学术信息网,学院官网,实验室官网,等等等。。。。
每天各个网站上都会发几条新闻,有些还是蛮重要的新闻,比如奖学金申请,但是呢,每天翻78个网站,从78个网站的10多个页面中看一下当天的新闻,真是一件麻烦的事情。
大概都是这个样子的


效果呢希望做成这个样子:
每天定时收到一封邮件,邮件内容从所有这些网站中提取的新闻中,找出最近3天的发布的新闻,排序后以一个列表的方式发送到我的邮箱,标题就是新闻内容的超链接。

最后再手机端查看邮件的效果

怎么做

基本思路是这样
【抓取网页 -> 提取筛选信息 -> 排序 -> 组织HTML -> 通过邮件发送】 + 定时运行
那么这里主要记录一下【】中的主要过程

搭建开发环境

这里使用Python3.5,官网下载直接安装就可以
IDE使用PyCharm,社区版免费。
基础语法学习资料推荐 Python基础教程,作为入门教程很合适。看完入门之后,官方文档是最好的教程

PIP安装教程(Windows)

Python的优点是有许许多多的好用的轮子,为了方便获取这些轮子,需要安装pip来方便的获取。类似Linux的apt-get
Step1、官网下载
点击打开链接https://pypi.python.org/pypi/pip#downloads

Step2、安装PIP
下载完成之后,解压到一个文件夹,用CMD控制台进入解压目录,输入:

python setup.py install

Step3、使用PIP安装轮子
安装好PIP之后,可以直接使用下面的语法来安装轮子xxxxx

pip install xxxxx

Ref:windows下面安装Python和pip终极教程

抓取网页

import urllib.request #库载入 response=urllib.request.urlopen('http://meeting.xidian.edu.cn/') #打开链接 page = response.read() # 读入网页

查阅文档,或得到如何改变UA的参数,形成如下代码:
url = reqUrl headers = { 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' } req = request.Request(url=url, headers=headers) response = request.urlopen(req) page = response.read()
获取到的网页HTML将存储在page变量中,可以直接使用
print(page)
查看获取到的HTML页面,大概是这样一些内容,标准的HTML4页面

Ref:使用 Python 轻松抓取网页

提取筛选信息

得到的结果设置一个HTML页面,HTML页面的解析这里使用BeautifulSoup4来完成

安装BeautifulSoup4
pip install BeautifulSoup4
官方文档是最好的学习资料

首先需要分析页面的HTML标签结构来确定怎么提取数据,这里我使用Chrome浏览器的开发者工具来分析。
打开页面,按F12打开代码检查工具


分析完了,使用BeautifulSoup提取

1、首先分离所有li标签,使用select功能
pageSoup = BeautifulSoup(page, "html.parser") newsList = pageSoup.select('div[class="main-right-list"] > ul > li')
得到结果大概是这个样子

2、然后针对每个li标签,分离具体的url,标题和时间。
使用get_text获得标题和时间,至于~||#|$|%|&||~这个是什么鬼,指示我用来split的标志,我觉得这个标志就不会和文本重复了,这个方法肯定不是很好,求不吐槽。
oneNewsText = oneNews.get_text('~||#|$|%|&||~').split('~||#|$|%|&||~')
得到的结果大概这个样子


3、使用find标签功能,获取href类别中的url片段
oneNewsUrl = oneNews.find('a')['href']
结果大概是这个样子

4、使用urljoin来合并url片段和主域名
oneNewsUrl = parse.urljoin('http://gr.xidian.edu.cn/', oneNewsUrl)
结果大概是这个样子

5、将前面得到的时间利用datetime解析成标准时间格式
oneNewsText[1] = datetime.datetime.strptime(oneNewsText[1], '%Y-%m-%d')
得到的结果大概是这个样子

6、将获得的时间,标题,URL合并到一个list中就得到了最终的信息提取结果

7、将日期与当前日期判断,如果是最新两天的新闻,就放入大list中准备返回,如果不是就丢弃(这里可以先判断时间在进行其他的解析吧)
if (datetime.datetime.now().date() - oneNewsText[0].date() <=datetime.timedelta(days=NewsDataDelet)): lnewsalllist.append(oneNewsText)

然后就ok啦,所有代码时这样的
def gr_xidian(reqUrl,NewsDataDelet): lnewsalllist = [] url = reqUrl headers = { 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' } req = request.Request(url=url, headers=headers) response = request.urlopen(req) page = response.read() pageSoup = BeautifulSoup(page, "html.parser") newsList = pageSoup.select('div[class="main-right-list"] > ul > li') for oneNews in newsList: oneNewsText = oneNews.get_text('~||#|$|%|&||~').split('~||#|$|%|&||~') oneNewsUrl = oneNews.find('a')['href'] oneNewsUrl = parse.urljoin('http://gr.xidian.edu.cn/', oneNewsUrl) oneNewsText.append(oneNewsUrl) oneNewsText[1] = datetime.datetime.strptime(oneNewsText[1], '%Y-%m-%d') oneNewsText[0],oneNewsText[1] = oneNewsText[1],oneNewsText[0] del oneNewsText[2] if (datetime.datetime.now().date() - oneNewsText[0].date() <= datetime.timedelta(days=NewsDataDelet)): lnewsalllist.append(oneNewsText) return lnewsalllist
同理书写获取解析其他网站的函数,最后得到的所有解析结果大概是这样的

这里用到了BeautifulSoupdatetimeurllibparse
说一下时间转换吧,来自网络,详细自行Google

Ref:python BeautifulSoup 抓取网页内指定内容
用python的BeautifulSoup分析html

排序

排序就很简单啦,直接用的listsort
newsAllList.sort(key=lambda x: x[0],reverse=True)
这里有一个知识点是lambda表达式x:x[0],就是x是list中的每一个元素,排序按照x[0]来进行比较,自己猜测体会的,不一定说的很完备

Ref:python list排序的两种方法及实例讲解

组织HTML

这里呢,要说一说,遇到了一些坑。
根据我边学习边Google的结果,最先知道的方法是Python直接填写HTML,感觉太麻烦。
后来又找到了一个PYH,据说能比较方便的组织HTML,未研究。来自Google Code,传送门
后来找到了Web框架,感觉找到了救星
参考知乎回答,确定了使用最简单的Flask框架
关于虚拟环境,其实不需要,直接使用本机环境运行就可以
其他过程参考这篇教程

最后在windows的cmd中执行下面的语句开启Flask服务器
python run.py

在浏览器访问
http://localhost:5000

获得结果

虽然说这使用模板完成了HTML的解析,但是需要运行一个服务器,然后通过浏览器访问这个服务器,和我的要求不符合。
遂研究发现Flask使用render_template来进行HTML渲染
page = render_template("index.html", title = 'Home', info = infomation, postList = posts)

那么render_template方法能不能用来直接渲染HTML,尝试未果。放弃

模板从天而降
查询发现Flask使用的是Jinja2引擎,所以能不能直接调用这个引擎呢,尝试未果

又找到了Mako模板引擎
Mako是一个高性能的Python模板库,它的语法和API借鉴了很多其他的模板库,如Django、Jinja2等等。

需要一个HTML模板(其实什么模板都可以,使用HTML模板渲染出来的就是HTML)和一个脚本



渲染出来的结果,大概时这样

好,下面就这个干
渲染很简单,直接建立Mako的Template,然后使用render方法就可以进行渲染
from mako.template import Template def rederHtml(templateFile,postlist): t = Template(filename=templateFile) page = t.render( name = 'Jack', postlist = postlist ) return page

需要提前写好模板
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>XidianNews</title> </head> <body> <div class="newslist"> <table> <tbody> % for post in postlist: <tr bgcolor="${loop.cycle('#cce0ff', '#e6f0ff')}"> <td width="95" align="center" class="arctime"><font size = "3">${post['time']}</font></td> <td class="arctitle"><a target="_blank" href=${post['url']} title="Click to open in new tab"><font size = "3">${post['body']}</font></a></td> </tr> % endfor </tbody> </table> </div> </body> </html>

Ref:PYH
Web框架比较
Flask教程
Mako语法

通过邮件发送

发邮件使用smtplib完成,可以使用import traceback来跟踪详细的调试信息
`def SendMail(title,mailHtml,rcvList):
sender = '15829911730@sina.cn'
pwd = 'sina2011'
smtpHost = 'smtp.sina.com'
smtpPort = '25'

message = MIMEText(mailHtml, 'html')
message['Subject'] = title
message['From'] = sender

for receiver in rcvList:
    message['To'] = receiver

    try:
        smtpObj = smtplib.SMTP_SSL(smtpHost)
        #smtpObj.set_debuglevel(1)
        smtpObj.login(sender, pwd)
        smtpObj.sendmail(sender, receiver, message.as_string())
        print("Success to send to",receiver)
    except smtplib.SMTPException as e:
        errorMsg = "Error: %s" % (e)
        print(errorMsg)
        # traceback.print_exc()
else:
    smtpObj.quit()`

通过smtplib的调试信息可以得到与服务器之间交互的信息
smtpObj.set_debuglevel(1)
得到大概这样子的反馈信息


Ref:Python smtplib发送邮件

python3 发邮件实例(包括:文本、html、图片、附件、SSL、群邮件)

Python3 SMTP发送邮件

好啦,到这里就结束了

以上

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 22年12月更新:个人网站关停,如果仍旧对旧教程有兴趣参考 Github 的markdown内容[https://...
    tangyefei阅读 35,159评论 22 257
  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    aimaile阅读 26,440评论 6 428
  • 环境管理管理Python版本和环境的工具。p–非常简单的交互式python版本管理工具。pyenv–简单的Pyth...
    MrHamster阅读 3,783评论 1 61
  • GitHub 上有一个 Awesome - XXX 系列的资源整理,资源非常丰富,涉及面非常广。awesome-p...
    若与阅读 18,613评论 4 418
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139