人生苦短,我用Python。
Python真的是很好的语言,很好用,那么我们该如何入门呢?
我觉得不用特别的学习,只要你有C/C++的一些知识,学习Python将不是一件很困难的事情。
这样一门语言,这样一个很好地工具,应该是不需要太高的学习成本的,所以我《Python边学边用》这个系列的文章,我将边用边学,可能代码不是那么“漂亮”,代码不是那么“优雅”,但是肯定实现了功能。
慢慢学,慢慢做,我会把这个工具用的越来越好。
文中描述方法不一定是最好的方法,只是我才疏学浅,自己只知道这么做能做出来,所以我就这么做了,欢迎交流批评。
要做什么
学校里有很多网站,教务处,研究生院,就业班,学术信息网,学院官网,实验室官网,等等等。。。。
每天各个网站上都会发几条新闻,有些还是蛮重要的新闻,比如奖学金申请,但是呢,每天翻7~8个网站,从7~8个网站的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
抓取网页
这里没有使用爬虫框架,主要是因为做这个是为了学习Python,实现简单功能即可。
在Python2版本中,有urllib和urlib2两个库可以用来实现request的发送。而在Python3中,已经不存在urllib2这个库了,统一为urllib。
urllib中包括了四个模块,包括urllib.request,urllib.error,urllib.parse,urllib.robotparser
- urllib.request可以用来发送request和获取request的结果
- urllib.error包含了urllib.request产生的异常
- urllib.parse用来解析和处理URL
- urllib.robotparse用来解析页面的robots.txt文件
基本网页获取
import urllib.request #库载入
response=urllib.request.urlopen('http://meeting.xidian.edu.cn/') #打开链接
page = response.read() # 读入网页
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 轻松抓取网页
提取筛选信息
pip install BeautifulSoup4
官方文档是最好的学习资料
pageSoup = BeautifulSoup(page, "html.parser")
newsList = pageSoup.select('div[class="main-right-list"] > ul > li')
得到结果大概是这个样子
oneNewsText = oneNews.get_text('~||#|$|%|&||~').split('~||#|$|%|&||~')
得到的结果大概这个样子
oneNewsUrl = oneNews.find('a')['href']
结果大概是这个样子
oneNewsUrl = parse.urljoin('http://gr.xidian.edu.cn/', oneNewsUrl)
结果大概是这个样子
oneNewsText[1] = datetime.datetime.strptime(oneNewsText[1], '%Y-%m-%d')
得到的结果大概是这个样子
if (datetime.datetime.now().date() - oneNewsText[0].date() <= datetime.timedelta(days=NewsDataDelet)):
lnewsalllist.append(oneNewsText)
# 研究生院官网
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
同理书写获取解析其他网站的函数,最后得到的所有解析结果大概是这样的
排序
newsAllList.sort(key=lambda x: x[0],reverse=True)
这里有一个知识点是lambda表达式x:x[0],就是x是list中的每一个元素,排序按照x[0]来进行比较,自己猜测体会的,不一定说的很完备
组织HTML
python run.py
http://localhost:5000
虽然说这使用模板完成了HTML的解析,但是需要运行一个服务器,然后通过浏览器访问这个服务器,和我的要求不符合。
page = render_template("index.html",
title = 'Home',
info = infomation,
postList = posts)
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>
通过邮件发送
# 发送邮件
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)
得到大概这样子的反馈信息