通过 Pyqt5 实现一个界面化的下载器,在通过网络请求实现各种类型的图片的下载。可以通过界面上输入不同图片的关键字从而实现下载图片并将下载好的图片保存到自定义的文件路径中。
文末附源码、操作视频
在介绍代码块内容之前,先来看一下需要用到的三方的 python 库。
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import os
from scripy_images import ScripyImages
其中和 Pyqt5 相关的三个模块的导入在前面的天气查询系统的介绍中就已经提到过了,若是需要下载《Pyqt5 天气查询系统》的源码,请在公众号内回复:"天气查询系统"。那么剩下的两个操作库一个是 os 模块主要是用来做系统文件相关操作的,还有一个就是 scripy_images 模块是用来通过网络请求来获取和下载图片的。
接下来介绍 Pyqt5 相关的页面定义等函数的使用。同样的先在 Pyqt5 的窗口上面添加我们需要的需要的组件,最后通过将这些组件添加到布局里面,大概的实现过程就是遵循这个顺序来实现的。
def init_ui(self):
self.setWindowTitle('百度图片提取应用')
grid = QGridLayout()
self.page_label = QLabel()
self.page_label.setText('设置爬取页数:')
self.page_line_text = QLineEdit()
self.page_line_text.setPlaceholderText('输入整数')
self.page_line_text.setValidator(QIntValidator(1, 99))
self.page_line_text.setFocus()
self.keyword_label = QLabel()
self.keyword_label.setText('设置图关键字:')
self.keyword_line_text = QLineEdit()
self.keyword_line_text.setValidator(QRegExpValidator(QRegExp('[\u4E00-\u9FA5]+')))
self.keyword_line_text.setMaxLength(6)
self.keyword_line_text.setPlaceholderText('输入汉字')
self.file_path = QLineEdit()
self.file_path.setPlaceholderText('自定义文件路径')
self.file_path.setReadOnly(True)
self.file_path_button = QPushButton()
self.file_path_button.setText('自定义路径')
self.file_path_button.clicked.connect(self.file_path_click)
self.request_button = QPushButton()
self.request_button.setText('快速开始抓取图片')
self.request_button.clicked.connect(self.download_image)
self.log_text = QTextEdit()
self.log_text.setPlaceholderText('抓取进度结果展示...')
self.log_text.setReadOnly(True)
self.log_text.setMaximumHeight(100)
self.version_msg_label = QLabel()
self.version_msg_label.setText('公众号:[Python 集中营] 发布')
self.version_msg_label.setAlignment(Qt.AlignCenter)
grid.addWidget(self.page_label, 0, 0, 1, 1)
grid.addWidget(self.page_line_text, 0, 1, 1, 2)
grid.addWidget(self.keyword_label, 1, 0, 1, 1)
grid.addWidget(self.keyword_line_text, 1, 1, 1, 2)
grid.addWidget(self.file_path, 2, 0, 1, 2)
grid.addWidget(self.file_path_button, 2, 2, 1, 1)
grid.addWidget(self.request_button, 3, 0, 1, 3)
grid.addWidget(self.log_text, 4, 0, 1, 3)
grid.addWidget(self.version_msg_label, 5, 0, 1, 3)
self.setLayout(grid)
再接着就是定义相应的槽函数,其中有两个槽函数的使用一个是实在定义文件的存储的路径时需要一个槽函数用来将获取文件路径。还有一个就是开始进行百度图片的下载过程,通过这个槽函数来调用下载模块的执行。
def file_path_click(self):
self.cwd = os.getcwd()
directory = QFileDialog.getExistingDirectory(self, '选取文件夹', self.cwd)
print(directory)
self.file_path.setText(directory + '/')
def download_image(self):
check_param = False
self.log_text.setText("")
self.log_text.insertPlainText("-----开始必填项参数检查-----\n")
if self.page_line_text.text().strip() != '' and \
self.keyword_line_text.text().strip() != '' and \
self.file_path.text().strip() != '':
self.log_text.insertPlainText("---参数检查成功---\n")
check_param = True
else:
self.log_text.insertPlainText("---参数检查失败---\n")
self.log_text.insertPlainText("请填写必填项后继续...\n")
check_param = False
self.log_text.insertPlainText("-----结束必填项参数检查-----\n")
if check_param is True:
self.log_text.insertPlainText("-----开始下载百度图片-----\n")
self.log_text.insertPlainText("---请耐心等待---\n")
ScripyImages(page_num=self.page_line_text.text(),current=self.keyword_line_text.text(),file_path=self.file_path.text())
self.log_text.insertPlainText("-----结束下载百度图片-----\n")
接着就是调用主函数执行整个逻辑。
if __name__ == '__main__':
app = QApplication(sys.argv)
baidu = baiduImage()
baidu.show()
sys.exit(app.exec_())
整个 Pyqt5 的调用执行过程就是这样的,获取完整的代码块包括百度图片执行网络请求下载的部分在公众号回复"百度图片下载器"获取完整代码块。
操作视频演示......
【往期回顾】
python3中的zip()、zip(*)、list()之间的灵活转换!
python print() 函数的格式化字符串输出
PyQt5 GUI && Requests Api 做一个天气查询系统(文末领取完整代码)!
一款优美的windows cmd命令行工具cmder
如何进行excel数据分析之后的可视化数据写入保存!
excel数据处理二:快速完成openpyxl数据的新增、修改!
excel数据处理一:巧妙使用openpyxl提取、筛选数据
比Selenium更方便的自动化测试工具Helium!
Python数据可视化:可视化数据分析插件D-Tale
计算速度太慢?试试 lru_cache 装饰器!
Original: https://www.cnblogs.com/lwsbc/p/15708591.html
Author: Python集中营
Title: PyQt5 GUI:百度图片下载器(文末附源码)
相关阅读1
Title: Python 快速排序法(转)
方法解读:
例:对初始序列:"6 1 2 7 9 3 4 5 10 8"采用快速排序法:
一、分别从初始序列"6 1 2 7 9 3 4 5 10 8"两端开始"探测"。
先 从右往左找一个 小于6的数,再从 左往右找一个大于 6的数,然后 交换他们。
这里可以用两个变量 i 和 j ,分别指向序列最左边和最右边。
我们为这两个变量起个好听的名字" 哨兵i"和" 哨兵j"。
刚开始的时候让 哨兵i指向序列的最左边(即 i=1),指向 数字6。
让 哨兵j指向序列的最右边(即 j=10),指向 数字8。
二、首先哨兵j 开始出动。
因为此处设置的基准数是最左边的数,所以需要让 哨兵j先出动,这一点非常重要(请自己想一想为什么)。
哨兵j一步一步地向左挪动(即 j--),直到找到一个小于6的数停下来。
接下来 哨兵i 再一步一步向右挪动(即 i++),直到找到一个数大于6的数停下来。
最后 哨兵j 停在了数字5面前, 哨兵i 停在了数字7面前。
现在交换 哨兵i 和 哨兵j 所指向的元素的值。
到此,第一次交换结束。
三、接下来开始 哨兵j 继续向左挪动(再友情提醒,每次必须是 哨兵j先出发)。
他发现了4(比基准数6要小,满足要求)之后停了下来。
哨兵i 也继续向右挪动的,他发现了9(比基准数6要大,满足要求)之后停了下来。
此时再次进行交换。
四、第二次交换结束,"探测"继续。
哨兵j继续向左挪动,他发现了3(比基准数6要小,满足要求)之后又停了下来。
哨兵i 继续向右移动,糟啦!此时 哨兵i 和 哨兵j 相遇了, 哨兵i 和 哨兵j 都走到3面前。
说明此时"探测"结束。
我们将基准数6和3进行交换。交换之后的序列如下。
五、 到此第一轮"探测"真正结束。
此时以基准数6为分界点,6左边的数都小于等于6,6右边的数都大于等于6。
回顾一下刚才的过程,其实 哨兵j 的使命就是要找小于基准数的数,而 哨兵i 的使命就是要找大于基准数的数,直到 i 和 j 碰头为止。
现在基准数6已经归位,它正好处在序列的第6位。
此时我们已经将原来的序列,以6为分界点拆分成了两个序列,左边的序列是"3 1 2 5 4",右边的序列是"9 7 10 8"。
接下来还需要分别处理这两个序列。因为6左边和右边的序列目前都还是很混乱的。
不过不要紧,我们已经掌握了方法,接下来只要模拟刚才的方法分别处理6左边和右边的序列即可。
六、现在先来处理6左边的序列现吧。
左边的序列是"3 1 2 5 4"。请将这个序列以3为基准数进行调整,使得3左边的数都小于等于3,3右边的数都大于等于3。好了开始动笔吧。
如果你模拟的没有错,调整完毕之后的序列的顺序应该是。
2 1 3 5 4
OK,现在3已经归位。
接下来需要处理3左边的序列"2 1"和右边的序列"5 4"。
对序列"2 1"以2为基准数进行调整,处理完毕之后的序列为"1 2",到此2已经归位。
序列"1"只有一个数,也不需要进行任何处理。至此我们对序列"2 1"已全部处理完毕,得到序列是"1 2"。
序列"5 4"的处理也仿照此方法,最后得到的序列如下。
1 2 3 4 5 6 9 7 10 8
七、对于序列"9 7 10 8"也模拟刚才的过程,直到不可拆分出新的子序列为止。
最终将会得到这样的序列,如下。
1 2 3 4 5 6 7 8 9 10
八、到此,排序完全结束。
细心的同学可能已经发现,快速排序的每一轮处理其实就是将这一轮的基准数归位,直到所有的数都归位为止,排序就结束了。
下面上个霸气的图来描述下整个算法的处理过程。
九、原始网址:https://blog.csdn.net/adusts/article/details/80882649
十、Python程序:
#快速排序法一:有小到大排序
def quickSort(arr,left,right):#arr:待排序的数列;left:数列开始的下标索引;right:数列结束的下标索引
if left > right:#如果开始索引大于结束索引
return
temp=arr[left];#取最左边的数为 基准数
i,j=left,right
while i!= j:#现从右边开始找
while arr[j]>=temp and i
将 基准数 归位
arr[left]=arr[i]
arr[i]=temp
quickSort(arr,left,i-1)#递归:继续处理左边的
quickSort(arr,i+1,right)#递归:继续处理右边的
测试
arr=[10,7,8,8,9,1,5]
n=len(arr)
quickSort(arr,0,n-1)
print("排序后的数组:")
for i in range(n):
print("%d" %arr[i])
#快速排序法二:由大到小排序
def quickSort(arr,left,right):#arr:待排序的数列;left:数列开始的下标索引;right:数列结束的下标索引
if left > right:#如果开始索引大于结束索引
return
temp=arr[left];#取最左边的数为 基准数
i,j=left,right
while i!= j:#现从右边开始找
while arr[j] and i
将 基准数 归位
arr[left]=arr[i]
arr[i]=temp
quickSort(arr,left,i-1)#递归:继续处理左边的
quickSort(arr,i+1,right)#递归:继续处理右边的
测试
arr=[10,7,8,8,9,1,5]
n=len(arr)
quickSort(arr,0,n-1)
print("排序后的数组:")
for i in range(n):
print("%d" %arr[i])
Original: https://www.cnblogs.com/xiangers/p/15433774.html
Author: xiangers
Title: Python 快速排序法(转)
相关阅读2
Title: Go 事,Gopher 要学的数字类型,变量,常量,运算符 ,第2篇
学习前的铺垫
如果一门语言是动态语言,那数据类型不是很重要,但当待学习的语言是静态语言时,数据类型的重要性就凸显出来了,而且必须作为必备只是进行学习。
在 Go 语言中,数据类型主要用于声明变量和函数返回值的类型,在声明时是为了把数据所需的内存规定出来,这样可以充分利用内存。
因为有其它语言的基础,所以直接学习 Go 中的各类型即可。
Go 数字类型
数字类型分为三种,即整型,浮点型和其它数字类型,其中整型又分为:
- uint8:无符号 8 位;
- uint16:无符号 16 位;
- uint32:无符号 32 位;
- uint64:无符号 64 位;
- int8:有符号;
- int16:有符号;
- int32:有符号;
- int64:有符号。
浮点类型,包含两种,分别是 float32
, float64
,还有 complex64
和 complex128
。
其它数字类型说明如下:
byte
:与无符号 int,即int8
类似;rune
:无符号int32
类似;uint
:32 位或者 64 位;int
:与unit
类似;uintptr
:无符号整数。
以上都是数字类型,除此之外还有更多内容,都将在后文重点学习。
Go 变量
Go 中变量的声明,在上一篇博客中我们已经涉及,这次我们展开说说。
首先,可以一次申请多个变量:
var bianliang,bianlaing type
参考下述测试代码:
package main
import "fmt"
func main() {
var a string = "梦想橡皮擦"
fmt.Println(a)
var b, c int = 1, 2
fmt.Println(b, c)
}
在声明变量的时候如果没有给初始值,系统自动赋零值,例如 int 类型为 0,float 类型为 0.0 ......(上篇博客已经学习,可以回顾一下)
目前你仅学习了数字类型,所有数字类型的零值,都是 0。
Go 中的变量声明也可以省略变量类型,即下述代码也可正常运行。
package main
import "fmt"
func main() {
var a, b = 1, 2
fmt.Println(a, b)
}
系统自动推断变量类型。
变量声明简化写法
使用 var 声明变量时,还可以简写,例如:
name := "梦想橡皮擦"
package main
import "fmt"
func main() {
b := 3
fmt.Println("不使用 b")
}
错误信息是 7:2: b declared but not used
,这点非常有趣,在其它语言是没有类似的验证的,但这保证了无用变量的声明和空间的浪费。
并行/同时赋值
在 Go 中,可以同时对多个变量赋值,测试代码如下所示。
package main
import "fmt"
func main() {
a, b, c := 3, 2, 1
fmt.Println(a, b, c)
}
相应的如果希望交换两个变量值,也可以像 Python 一样,直接进行交换。
a,b = b,a
这里先认识一个特殊的符号, _
空白标识符,该变量可以用于抛弃值,例如下述代码。
_,b = 1,2
其中 1 会被抛弃,其中 _
实际是一个只写变量,不可读,该变量也被叫做匿名变量,它不占内存空间,也不会分配内存,匿名变量可以多次声明,即下述代码:
_, b := 1, 2
_, a := 1, 2
Go 常量
常量就是不可被修改的变量,Go 常量支持的数据类型有布尔型,数字型,字符串型,定义语法格式是:
const bianliang [type] = value
其中 type
被声明叫做显式定义,无 type
表示隐式声明。
多个相同类型的声明可以简写成一行。
const name,my_str = "橡皮擦","一个普通的字符串"
Go 中有一个特殊常量 iota
,是一个可以被编译器修改的常量。
iota
在 const 关键字出现时被充值为 0,const 中每新增一行常量声明, iota
增加一次计数,所以将 iota 当成 const 语句块的行索引也可以。
Go 运算符
运算符知识点在任何语言都中非常类似,一元的有: +
, -
, *
, /
, %
, ++
, --
,在 Python 中不见的自增和自减操作符又重新出现了。
上述操作符一般叫做算数运算符,除此之外还有关系运算符,即大于小于等内容。
逻辑操作符也是三个,分别是 逻辑与 &&
,逻辑或 ||
,逻辑非 !
。
位运算符可以先略过,后续用到在考虑复习一下。
在接下来就是赋值运算符,即与 =
号相关的运算符,也是通用知识点,直接掌握了。
重点要说明的是下述两个特殊运算符,这里与 C 语言同源,即 &
取地符, *
指针变量标记。
func main() {
_, b := 1, 2
// _, a := 1, 2
fmt.Println("变量 b 的地址是", &b)
}
声明一个 int 类型的指针变量,使用代码如下所示。
_, b := 1, 2
var ptr *int
// 赋值
ptr = &b
今天的最后一个知识点是运算符的优先级,如果你有其它语言基础,这部分自动忽略即可。
Original: https://blog.51cto.com/cnca/5561833
Author: 梦想橡皮擦
Title: Go 事,Gopher 要学的数字类型,变量,常量,运算符 ,第2篇
相关阅读3
Title: Python自学笔记11-函数定义、调用和参数类型
Python函数的定义
函数是代码封装的一种手段,函数中包含一段可以重复执行的代码,在需要用到这些代码时,只需要调用函数,就会运行函数中的代码。
python 函数这么定义:
def 函数名称(参数1, 参数2): 函数体(要运行的代码)
比如一个很简单的函数定义:
def add(a, b): return a + b
现在我们举个例子说明函数的作用。
print('打开高级车门')print('开发动机')print('安全带')print('踩油门')print('掌握方向')
如果要开很多次车,那么每次都需要敲相同的 5 行代码,这样会造成几个问题:
- • 很容易编写不同的代码,或者代码出现错误
- • 代码冗余,可读性不强
- • 不容易维护,当需要修改某个步骤时,要修改多处。
Python函数的调用
现在我们可以把上述代码封装在函数中,当需要运行这些代码时,调用函数就可以了,这样减少了很多复制粘贴或者手工编写多行代码的步骤,函数的名称也表明了代码的作用,当需要修改部分逻辑,只需要修改函数体就可以了。
def run_car(): print('打开高级车门') print('发动发动机') print('系上安全带') print('踩油门') print('掌握方向')run_car()# 其他代码run_car()
Python函数的返回值
return 表示当函数执行完之后,想让函数外面的程序得到函数执行的结果, return 的值可以任意的数据类型。
def add(a, b): return a + bresult = add(3,4)print(result)
- • 函数体当中的代码, 遇到 return 会终止运行。
- • 函数的返回结果可以是任意类型,包括 None
- • 当函数体当中没有 return ,默认返回 None
Python函数可以返回多个值, 只需要在多个值之间加上逗号,得到的是元组类型。
def add(a, b): return a, b
参数的四种类型
return 表示函数返回给外部的值,而参数表示函数从外部接收的值。在函数定义时候的参数叫做形式参数,它其实就是一个变量名称,在函数调用时候的参数叫做实际参数,相当于给变量赋值。
def get_coffee(suger): if suger > 100: return '甜咖啡' elif suger < 1: return '美式' else: return '莫名其妙的咖啡'result = get_coffee(100)print(result)
注意,形式参数的个数和实际参数的个数要一样,而且顺序要一致,这种方式叫做位置参数。(和领导吃饭做位置)如果形式参数和实际参数的个数不一致,会导致程序无法分别赋值:
def add(a, b): c = a + b - 1 return cadd(5, 7, 8) # NO
关键字参数:在调用函数的时候,做一个关键字标记,以防传参错误,造成损失。主要是当参数很多的情况,你记不清顺序,关键字去标识数据的意思。
默认参数:在函数定义的时候,给某个变量直接赋值,成为默认值。 就是使用默认值直接赋值,在调用函数的时候,可以少传参数。关键字参数,默认参数也好,都必须放到位置参数的后面。
def add(a, b=0): c = a + b - 1 return cadd(a=4, b=6)add(3)
自动化测试场景:添加多个数据,运行多个用例
def write_case(number): for _ in range(number): username = input("请输入用户名:") passwd = input("请输入密码:") age = input("请输入年龄:") user = dict() user.update(username=username, passwd=passwd, age=age) yield userdef run(case): print(f"运行用例-用户名{case['username']}") cases = write_case(2) for case in cases: run(case)
Original: https://blog.51cto.com/u_12188579/5631286
Author: 九柄聊测试
Title: Python自学笔记11-函数定义、调用和参数类型