Python爬糗百热门20条并邮件分发+wxPython简易GUI+py2app转成可运行文件
学了一阵子Python,拿来做个什么有意思的东西呢?爬糗百好了。爬到的内容,邮件分发出去。
然后又啃了两天的wxpython,做了个简易的邮件管理界面,能够在这里添加或者删除邮件,而且一键爬虫发送。
最后,索性封装成APP吧。又试了一把py2app。简单好用。
因为是让用户自行加入和删除邮箱。所以程序一定要兼顾到各种情况:比方输入的邮箱格式不合法。输入的邮箱里包括中文字符,分隔符不正确,删除了所有邮箱然后又要发邮件等问题。
首先是QiuBai.py:爬虫,正则匹配我们想要的内容。然后将内容稍作处理返回。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import urllib2
__author__ = 'Sophie2805' class FetchData(object):
def __init__(self,URL,referURL,pattern_1,pattern_2):
self.URL = URL
self.pattern_1 = pattern_1
self.patttern_2 = pattern_2
self.referURL = referURL def getHtml(self):
headers = {
'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6',
'Referer':self.referURL #http://www.qiushibaike.com/
}
req = urllib2.Request(
url = self.URL, #http://www.qiushibaike.com/text
headers = headers)
return urllib2.urlopen(req).read() def getData(self,html):
p_1 = re.compile(self.pattern_1)
div_content = p_1.findall(html.decode('utf8'))
row = 0
for m in range(len(div_content)):
div_content[m] = re.sub(self.patttern_2,'',div_content[m])
div_content[m] = ("---" + str(row+1) + "---" + div_content[m]).encode('utf-8')
row += 1
return div_content
接下来就是mail.py。注意。发送人的邮箱要检查下是否打开了SMTP协议
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import smtplib
from email.mime.text import MIMEText
from email.header import Header __author__ = 'Sophie2805' class SMail:
def __init__(self):
self.sender = '***@qq.com'
self.receiver = ['***@163.com','***@qq.com']
self.subject = '糗百热门20条推送'
self.username = '***@qq.com'
self.password = '******' def send_mail(self,msg):
try:
self.msg = MIMEText(msg,'plain','utf-8')
self.msg['Subject'] = Header(self.subject,'utf-8')
self.msg['To'] = ','.join(self.receiver)
self.msg['From'] = self.sender
self.smtp = smtplib.SMTP()
self.smtp.connect('smtp.qq.com')
self.smtp.login(self.username,self.password)
self.smtp.sendmail(self.msg['From'],self.receiver,self.msg.as_string())
self.smtp.quit()
return '1'
except Exception, e:
return str(e)
最后,用wxpython做了个简易的收件人管理界面,Spider_QiuBai.py,实现:添加邮件、删除邮件、一键爬虫发送糗百热门20条到邮件列表。
当然,为了程序正确执行,会有各种验证,比方输入的邮箱格式是否合法,发送时检查receiver列表是否为空等
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc29waGllMjgwNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="450" height="630" alt="">
程序比較简单,代码例如以下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'Sophie2805' import wx
import wx.grid
from mail import *
from QiuBai import * class Frame(wx.Frame):
QiuBai = None
content = None
m = SMail()
def __init__(self, parent=None, title='Get the Hottest QiuBai!',size=(450, 630),
style=wx.DEFAULT_FRAME_STYLE ^ (wx.RESIZE_BORDER |wx.MAXIMIZE_BOX)):
wx.Frame.__init__(self, parent=parent, title=title, size=size,style = style)
self.Centre()
panel = wx.Panel(self,-1) self.text_Email = wx.StaticText(panel,1, "You want it too? Add your email below. Using ';' between multiple emails. Existing emails will not be added again.")
self.input_Email = wx.TextCtrl(panel,2)
self.button_Email = wx.Button(panel,3,label='+') '''Bind with function'''
self.button_Email.Bind(wx.EVT_BUTTON,self.add) self.text_DeleteEmail = wx.StaticText(panel,4, "Existing receivers are listed below. You can delete by double clicking them and clicking on '-' button. Please note that it can hold 20 emails at most one time.") '''grid'''
self.grid = wx.grid.Grid(panel,5)
self.grid.CreateGrid(20,1)
self.grid.EnableEditing(False)
self.grid.SetColSize(0,200)
self.grid.SetColLabelValue(0,'Emails')
for i in range(len(self.m.receiver)):
self.grid.SetCellBackgroundColour(i,0,"grey")
self.grid.SetCellValue(i,0,self.m.receiver[i]) self.grid.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK,self.grid_change_color) self.button_DeleteEmail = wx.Button(panel,6,label='-')
self.button_Send = wx.Button(panel,7,label='send') '''Bind with function'''
self.button_Send.Bind(wx.EVT_BUTTON,self.sendmail)
self.button_DeleteEmail.Bind(wx.EVT_BUTTON,self.d_emails) '''BoxSizer'''
'''================================================================'''
add_Email = wx.BoxSizer() #input box and add button
add_Email.Add(self.input_Email,proportion=4,flag = wx.LEFT, border = 5)
add_Email.Add(self.button_Email,proportion=1,flag=wx.LEFT,border=15) ae = wx.BoxSizer(wx.VERTICAL)
ae.Add(self.text_Email,proportion =4, flag=wx.ALL, border=5)
ae.Add(add_Email,proportion=2, flag=wx.LEFT|wx.BOTTOM|wx.RIGHT, border=5) h_b = wx.BoxSizer()#send button and delete button
h_b.Add(self.button_Send,flag=wx.LEFT,border=5)
h_b.Add(self.button_DeleteEmail,flag=wx.LEFT,border=250) de = wx.BoxSizer(wx.VERTICAL)
de.Add(self.text_DeleteEmail,proportion=2,flag=wx.ALL, border=5)
de.Add(self.grid,proportion = 4,flag=wx.LEFT, border=80)
de.Add(h_b,proportion=1,flag=wx.TOP, border=10) vBoxSizer = wx.BoxSizer(wx.VERTICAL)
vBoxSizer.Add(ae,proportion=2,flag=wx.ALL,border=5)
vBoxSizer.Add(de,proportion=4,flag=wx.LEFT|wx.BOTTOM|wx.RIGHT,border=5)
panel.SetSizer(vBoxSizer) #delete the emails that cell bk color changed to yellow
def d_emails(self,evt):
count_yellow = 0
for i in range(len(self.m.receiver)):
if self.grid.GetCellBackgroundColour(i,0)==(255, 255, 0, 255): # yellow
count_yellow += 1 if count_yellow == 0:
wx.MessageBox('Wake up!\nSelect then delete!') else:
l = len(self.m.receiver)
self.m.receiver=[]
for i in range(l):
if self.grid.GetCellBackgroundColour(i,0)==(128, 128, 128, 255):#grey
self.m.receiver.append(self.grid.GetCellValue(i,0))
self.grid.SetCellValue(i,0,'')#clear the cell's value
self.grid.SetCellBackgroundColour(i,0,'white') for i in range(len(self.m.receiver)):
self.grid.SetCellBackgroundColour(i,0,"grey")
self.grid.SetCellValue(i,0,self.m.receiver[i])
self.grid.ForceRefresh() #change cell bk color when double click the cell. The cell without value will not be changed
def grid_change_color(self,evt):
if self.grid.GetCellValue(self.grid.GridCursorRow,self.grid.GridCursorCol) != '':
if self.grid.GetCellBackgroundColour(self.grid.GridCursorRow,self.grid.GridCursorCol)==(128, 128, 128, 255):#grey
self.grid.SetCellBackgroundColour(self.grid.GridCursorRow,self.grid.GridCursorCol,'yellow')
else:
self.grid.SetCellBackgroundColour(self.grid.GridCursorRow,self.grid.GridCursorCol,'grey')
self.grid.ForceRefresh() #add the emails that user input
def add(self,evt):
x = str(self.input_Email.GetValue().encode('utf-8'))
if len(x) == 0:
wx.MessageBox('Hey dude, input something first!')
elif len(x) != len(x.decode('utf-8')):#non ASCII character contained
wx.MessageBox('Hey dude, please input English character only!')
else:
x = x.split(';')
tag = 0
for i in range(len(x)):
if len(x[i]) != 0:
if x[i] in self.m.receiver:
x[i]=''#existing emails, set to ''
elif self.validate_email(x[i]) == None:
wx.MessageBox('Hey dude, eyes wide open! \nPlease input like this: xxx@xxx.com;eee@eee.org')
tag = 1
break
if tag == 0: # all emails are valid
for item in x:
if len(item) != 0:
self.m.receiver.append(item)
for i in range(len(self.m.receiver)):
self.grid.SetCellBackgroundColour(i,0,"grey")
self.grid.SetCellValue(i,0,self.m.receiver[i])
self.input_Email.Clear()
self.grid.ForceRefresh() #validate the emails user input
def validate_email(self,s):
pattern = "^[a-zA-Z0-9\._-]+@([a-zA-Z0-9_-]+\.)+([a-zA-Z]{2,3})$"
p = re.compile(pattern)
return p.match(s) def sendmail(self,evt):
if len(self.m.receiver) == 0:
wx.MessageBox('Are you kidding me?\n Add some receivers then send!')
else:
self.QiuBai = FetchData('http://www.qiushibaike.com/text','http://www.qiushibaike.com/',
'<div class="content">[\n\s]+.+[\n\s]','[<div class="content"><br/>\n]')
self.content = self.QiuBai.getData(self.QiuBai.getHtml())
msg = '\n\n'.join(self.content)
result = self.m.send_mail(msg)
if result == '1':
wx.MessageBox('The hottest QiuBai had been sent.\n Enjoy it ^_^ !')
else:
wx.MessageBox('Some exception occurred :-(\nTry again later...\n'+result)
class GetQiuBaiApp(wx.App):
def OnInit(self):
frame = Frame()
frame.Show()
return True if __name__ == "__main__":
app = GetQiuBaiApp()
app.MainLoop()
最后就是Python转APP了:
(1)在MAC终端里输入pip install py2app安装py2app
(2)创建setup.py,我的project位于/Users/Sophie/PycharmProjects/QiuBai,所以cd到这个路径下。然后vi setup.py。在这个文件中输入例如以下内容(提前准备个icns图标。放到project路径下)
"""
py2app build script for MyApplication
Usage:
python setup.py py2app
"""
from setuptools import setup
OPTIONS = {
'iconfile':'lemon.icns'
}
setup(
app=["Spider_QiuBai.py"],
options={'py2app': OPTIONS},
setup_requires=["py2app"],
)
(3)rm -rf build dist(假设反复多次打包的话。这个命令是须要的。第一次不须要)
(4)python setup.py py2app 用这个命令打包,打包好的app会存放在该路径下的dist路径下。我的例如以下:/Users/Sophie/PycharmProjects/QiuBai/dist
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc29waGllMjgwNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
至此,这个小玩意儿已经做好了,当中略麻烦的可能就是正则还有界面了 Hope you enjoy it ^ ^
Python爬糗百热门20条并邮件分发+wxPython简易GUI+py2app转成可运行文件的更多相关文章
- 这届网友实在是太有才了!用python爬取15万条《我是余欢水》弹幕
年初时我们用数据解读了几部热度高,但评分差强人意的国产剧,而最近正午阳光带着两部新剧来了,<我是余欢水>和<清平乐>,截止到目前为止,这两部剧在豆瓣分别为7.5分和7.9分,算 ...
- Python性能优化的20条建议 (转载)
优化算法时间复杂度 算法的时间复杂度对程序的执行效率影响最大,在Python中可以通过选择合适的数据结构来优化时间复杂度,如list和set查找某一个元素的时间复杂度分别是O(n)和O(1).不同的场 ...
- python基础===Python性能优化的20条建议
优化算法时间复杂度 算法的时间复杂度对程序的执行效率影响最大,在Python中可以通过选择合适的数据结构来优化时间复杂度,如list和set查找某一个元素的时间复杂度分别是O(n)和O(1).不同的场 ...
- Python性能优化的20条建议
优化算法时间复杂度 算法的时间复杂度对程序的执行效率影响最大,在Python中可以通过选择合适的数据结构来优化时间复杂度,如list和set查找某一个元素的时间复杂度分别是O(n)和O(1).不同的场 ...
- Python爬取酷狗飙升榜前十首(100)首,写入CSV文件
酷狗飙升榜,写入CSV文件 爬取酷狗音乐飙升榜的前十首歌名.歌手.时间,是一个很好的爬取网页内容的例子,对爬虫不熟悉的读者可以根据这个例子熟悉爬虫是如何爬取网页内容的. 需要用到的库:requests ...
- 萌新学习Python爬取B站弹幕+R语言分词demo说明
代码地址如下:http://www.demodashi.com/demo/11578.html 一.写在前面 之前在简书首页看到了Python爬虫的介绍,于是就想着爬取B站弹幕并绘制词云,因此有了这样 ...
- Python学习-使用Python爬取陈奕迅新歌《我们》网易云热门评论
<后来的我们>上映也有好几天了,一直没有去看,前几天还爆出退票的事件,电影的主题曲由陈奕迅所唱,特地找了主题曲<我们>的MV看了一遍,还是那个感觉.那天偶然间看到Python中 ...
- Python爬取十四万条书籍信息告诉你哪本网络小说更好看
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: TM0831 PS:如有需要Python学习资料的小伙伴可以加点击 ...
- 【2022知乎爬虫】我用Python爬虫爬了2300多条知乎评论!
您好,我是 @马哥python说,一枚10年程序猿. 一.爬取目标 前些天我分享过一篇微博的爬虫: https://www.cnblogs.com/mashukui/p/16414027.html 但 ...
随机推荐
- UVALive 6663 Count the Regions 离散+bfs染色_(:зゝ∠)_
题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=4675">点击打开链接 gg.. ...
- python的range()函数使用方法
python的range()函数使用非常方便.它能返回一系列连续添加的整数,它的工作方式类似于分片.能够生成一个列表对象. range函数大多数时常出如今for循环中.在for循环中可做为索引使用.事 ...
- 去哪网实习总结:JavaWeb中文传參乱码问题的解决(JavaWeb)
本来是以做数据挖掘的目的进去哪网的.结构却成了系统开发... 只是还是比較认真的做了三个月.老师非常认同我的工作态度和成果... 实习立即就要结束了,总结一下几点之前没有注意过的变成习惯和问题,分享给 ...
- [AHOI 2009] 同类分布
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1799 [算法] 数位DP [代码] #include<bits/stdc++. ...
- 15. 3Sum[M]三数之和
题目 Given an array nums of n integers, are three elements a, b, c in nums such that a+b+c=0? Find all ...
- SqlServer数据库字典
网上有很多SQL Server数据库字典的SQL语句,七零八落,我在工作整理了一下思路,总结SQL代码如下.数据库字典包括表结构(分2K和2005).索引和主键. 外键.约束.视图.函数.存储过程.触 ...
- 设置cookie,删除cookie,读取cookie
1.首先来说下cookie的作用 我们在浏览器中,经常涉及到数据的交换,比如你登录邮箱,登录一个页面.我们经常会在此时设置30天内记住我,或者自动登录选项.那么它们是怎么记录信息的呢,答案就是今天的主 ...
- swfupload组件上传文件
前段时间做文件上传用的是H5的一个插件,由于浏览器的兼容性不好,所以又换了一个Flash版本的上传文件插件,感觉这个上传插件的使用方式跟H5的差不多,有些雷同.不过,由于后续浏览不再支持Flash(略 ...
- 在centos6.5上升级php-libxml版本到2.9.0
当前系统,软件版本说明: php libxml glibc 2.12 zlib xz-libs 需求: 应开发的需求,线上环境,php-libxml版本升级到2.8以上. 升级步骤:1.安装工具集 y ...
- codevs 3945 完美拓印 (KMP)
题目大意:给你一个神奇的印章,他左右下三个面都是直的,上面是凸凹不平的面(凸凹都平行于别的面).然后给你一个轮廓线,如果一个面能与轮廓线完全重合,可以把印章的这个沿着轮廓线拓印,求所有的拓印方案. 把 ...