python + pyqt 实现的你下载css背景图片的小工具(最终版)
学习python有三个星期了,算是做的第一个小工具,其实也没必要做成图形界面,只是为的GUI学习(再说技术总归给人使用的,熟练很多shell命令只是个“匠人”。)
win8下面:
ubutu 下:
虽是小工具,大版本有3个
1.命令行版
2.pyqt GUI版
3.pyqt GUI 线程版
期间也大大小小的bug修复n多次,几次重构(笑),算得上是“软件开发的小周期”吧。今天贴代码是是第3版:
saveCssImg.py
# coding: utf-8 -*- import urllib2,urllib import sys,re,os,urlparse from PyQt4 import QtCore, QtGui class saveCssBackImg(QtGui.QWidget): updateSig = QtCore.pyqtSignal(str) def __init__(self,cssUrl,savePath,parent=None): super(saveCssBackImg, self).__init__(parent) self.cssUrl = cssUrl self.savePath = mkdir(savePath) def saveImg(self): counter = 1 errnum = 0 imgList = self.getImgList() img_num = len(imgList) for img in imgList: img = img.strip("'") img = img.strip('"') if re.match('^https?://', img): imgsrc = img.split('?')[0] else: imgsrc = urlparse.urljoin(self.cssUrl, img).split('?')[0] imgname = os.path.split(imgsrc)[1] try: httpcode = urllib.urlopen(imgsrc).code except: httpcode = None if httpcode == 200 : try: urllib.urlretrieve(imgsrc, os.path.join(self.savePath,imgname)) info = u'[%2d/%2d]<a href="%s">%s</a>' %( counter, img_num , imgsrc,imgsrc ) except: errnum += 1 info = u'[%2d/%2d]<a href="%s">%s</a> <span style="color:red">保存失败[%s]</span>' %( counter, img_num , imgsrc ,imgsrc,errnum) else: errnum += 1 info = u'[%2d/%2d]<a href="%s">%s</a> <span style="color:red">[%s][code:%s]</span>' %( counter, img_num , imgsrc ,imgsrc ,errnum, httpcode) self.updateSig.emit(info) counter+=1 def getImgList(self): allimglist = re.findall(r'url\s*\((.*?)\)', self.getCssContent()) imgList = set(allimglist) return imgList def getCssContent(self) : try: rsp = urllib2.urlopen(self.cssUrl,timeout = 1) return rsp.read() except urllib2.URLError, e: self.updateSig.emit('<font color=red>%s</font>' % e ) except BaseException, e: self.updateSig.emit('<font color=red>%s</font>' % e ) def mkdir(savePath): fullPath = os.path.join(os.getcwd(),savePath) if not os.path.exists(fullPath) : try: os.mkdir(os.path.join(os.getcwd(),savePath)) return fullPath except: print 'can\'t creat dir: %s, please creat it manually! ' % fullPath return return fullPath
project_ui.py
# coding: utf-8 -*- from PyQt4 import QtCore, QtGui from saveCssImg import * try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: def _fromUtf8(s): return s try: _encoding = QtGui.QApplication.UnicodeUTF8 def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) class UI_getImg(QtGui.QDialog): def __init__(self, parent=None): super(UI_getImg, self).__init__(parent) self.setupUi(self) self.lineEdit.setText('http://simg.sinajs.cn/blog7style/css/conf/blog/article.css') self.textBrowser.setOpenExternalLinks(True) self.textBrowser.setLineWrapMode(QtGui.QTextEdit.NoWrap) self.textBrowser.setStyleSheet("QTextBrowser {background: #eee; }") self.pushButton.clicked.connect(self.goWork) def goWork(self): self.thread = WorkerThread() self.thread.sinOut.connect(self.outText) self.thread.finished.connect(self.workFinished) cssUrl = str(self.lineEdit.text()) savePath = 'downImgs' self.textBrowser.setText(u'CSS文件地址: <a href="%s">%s</a><br>__________<br>' % (cssUrl,cssUrl)) self.pushButton.setDisabled(True) self.thread.setEvr(cssUrl,savePath) def workFinished(self): self.outText(u'<br>__________<br>已退出下载!') self.pushButton.setDisabled(False) def setupUi(self, Dialog): Dialog.setObjectName(_fromUtf8("Dialog")) Dialog.resize(800, 407) self.pushButton = QtGui.QPushButton(Dialog) self.pushButton.setGeometry(QtCore.QRect(700, 20, 75, 23)) self.pushButton.setObjectName(_fromUtf8("pushButton")) self.textBrowser = QtGui.QTextBrowser(Dialog) self.textBrowser.setGeometry(QtCore.QRect(10, 60, 780, 341)) self.textBrowser.setObjectName(_fromUtf8("textBrowser")) self.lineEdit = QtGui.QLineEdit(Dialog) self.lineEdit.setGeometry(QtCore.QRect(10, 20, 670, 20)) self.lineEdit.setObjectName(_fromUtf8("lineEdit")) self.retranslateUi(Dialog) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): Dialog.setWindowTitle(_translate("Dialog", "下载Css文件图片", None)) self.pushButton.setText(_translate("Dialog", "下载", None)) def outText(self,text): self.textBrowser.append(text) class WorkerThread(QtCore.QThread): sinOut = QtCore.pyqtSignal(str) def __init__(self,parent=None): super(WorkerThread,self).__init__(parent) def setEvr(self,cssUrl,savePath): self.cssUrl = cssUrl self.savePath = savePath self.start() def getMsg(self,msg): self.sinOut.emit(msg) def run(self): self.saveimg = saveCssBackImg(self.cssUrl,self.savePath) self.saveimg.updateSig.connect(self.getMsg) self.saveimg.saveImg() if __name__ == "__main__": app = QtGui.QApplication([]) ui = UI_getImg() ui.setWindowFlags(QtCore.Qt.MSWindowsFixedSizeDialogHint) ui.show() app.exec_()
两处修复:
1.urllib.urlretrieve下载图片,对http status 404和403等也会保存成图片
2.QtGui.QTextBrower 横向滚动
github:(重构版,核心saveCssImg.py代码不再需要Pyqt)
接着学习了下开源利器linus前辈的另一大作git. andriod源码就是git管理的。