前言 这是一个使用python和beautifulsoup4编写的图片下载程序,主要支持视觉中国网站,可以获取当前网址网页的图片列表,有3种图片下载方式,全部下载、单张下载以及任意张下载。 本例是在之前的一篇博文的基础上,进行了优化了,使界面看起来更整齐,增加了网页浏览。
实际窗口: 如上图,可以直接在“图片获取网址”处输入网址,然后点击获取列表按钮,也可以先在“网址”处输入网址,如视觉中国,可以在界面内的浏览器浏览网页,寻找需要的图片页面,网址会自动更新。
右侧是下载按钮,图片保存地址默认是桌面,也可以手动修改。
所以,本程序大致分为三部分,一是界面内网页浏览,使用Qwebengineview模块,一是网页数据获取和分析,使用requests和beautifulsoup4模块,一是图片下载,使用urllib模块。
以下分别说明:
一、界面网页浏览 在窗口界面内浏览网页,主要使用Qt的Qwebengineview模块,或者说部件。 通常情况下,创建一个实力即可:
self.webview=QWebEngineView(self)
但本例中为了实现网页浏览时,可以点击网页上的链接,实现窗口内跳转,于是重写了Qwebengineview的createwindow函数:
class MyWebEngineView(QWebEngineView):
"""此处重载了QWebEngineView,当点击网页内链接时,可以在本窗口内跳转"""
def createWindow(self,QWebEnginePage_WebWindowType):
page = MyWebEngineView(self)
page.urlChanged.connect(self.on_url_changed)
return page
def on_url_changed(self,url):
self.setUrl(url)
然后在主窗口界面调用上面的类实例:
self.webview=MyWebEngineView(self)
self.webview.setGeometry(20,120,480,600)
self.webview.setZoomFactor(0.4)
self.webview.loadFinished.connect(self.urlchange_f)
self.webview.urlChanged.connect(self.urlchange_f)
这样,当我们在窗口上打开一个网页时,就可以实现窗口内跳转了。 二、网页获取数据 首先是通过requests的get函数,获取给定网址的原始数据。
def get_url_text(self, url):
# 获取当前网址下的总体信息
url_info = requests.get(url)
url_info.encoding = url_info.apparent_encoding
url_text = url_info.text
return url_text
然后将获取的网页数据返回,网页原始数据大致如下: 数据来自视觉中国网页
class="wd-checkbox-label wd-pl-title"> 竖图
新城
href="/creative-image/33229" title="科技 创意"> 科技 创意
获取到原始数据后,就可以对这个数据进行处理,提取其中的图片信息:
def get_img_url_list(self, url):
# 对获取的网页信息进行处理,提取图片链接地址
url_text = self.get_url_text(url)
#print(url_text)
soup = BeautifulSoup(url_text, 'html.parser')
url_list = soup.find('div', class_='gallery_inner')
img_url_list = url_list.find_all('a')
# print(img_url_list)
lli = img_url_list[:(len(img_url_list) - 1)]
# print(len(lli))
img_num = str(len(lli))
self.lbl_imgnumber.setText('共找到: ' + img_num + ' 张图片')
#self.lbl_imgnumber.adjustSize()
self.te.clear()
# 对获取到的图片链接地址信息再次处理,将其分割并有序存入list表中。
for i, img_url_list_s in enumerate(lli):
# print(img_url_list_s)
li = img_url_list_s.find('img')
name1 = li['alt']
# print(name1)
img_url = li['data-src']
img_src = 'https:' + img_url
# self.get_image_info(img_src,name1)
self.img_url_list.append({'name': name1, 'img-src': img_src})
#使图片列表显示与list中的索引是一一对应的,这样下载时编号不会出错
for i,itm in enumerate(self.img_url_list):
index=str(i)
imgret=itm
imgname=imgret['name']
imgurl=imgret['img-src']
print(index)
print(imgname+imgurl)
self.te.append(str(i + 1) + ' ' + imgname+imgurl+ '\r\n')
我们提取了图片数据后,储存在一个list中,同时显示到文本框中。
三、图片下载 图片下载,其实是将当前网址指向的图片保存到本地,使用request.urlretrieve函数:
request.urlretrieve(urlpath, filename=fl)
因为我们已经获取了网页的图片列表,并保存在list中,此时无论是全下载还是单张下载,只需要对list中的元素进行操作即可。
完整代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import webbrowser
import requests
import time
import sys
from urllib import request
from bs4 import BeautifulSoup
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWebEngineWidgets import QWebEngineView,QWebEnginePage
from common_help import CommonHelper
class example(QWidget):
def __init__(self) -> None:
super().__init__()
self.initUI()
def initUI(self):
# 加载QSS样式文件
self.stylefile = 'python-paichong\qss_main_style.qss'
self.qssstyle = CommonHelper.readQSS(self.stylefile)
self.img_url_list = []
self.dic="C:\\Users\\rongjv\Desktop"
#self.webview=QWebEngineView(self)
self.lbl_webview=QLabel(self)
self.lbl_webview.setText("网址:")
self.lbl_webview.setGeometry(20,100,40,20)
self.le_website=QLineEdit(self)
self.le_website.setGeometry(60,100,300,20)
self.le_website.setText("https://www.vcg.com/")
self.btn_website=QPushButton('浏览',self)
self.btn_website.setGeometry(380,100,60,20)
self.btn_website.clicked.connect(self.photo_link2)
self.lbl_url = QLabel(self)
self.lbl_url.setText('图片获取网址:')
self.lbl_url.setGeometry(20, 60, 80, 20)
#self.lbl_url.adjustSize()
# 网址输入框
self.le_url = QLineEdit(self)
self.le_url.setGeometry(100, 60, 400, 20)
self.le_url.setText('https://www.vcg.com/creative-image/keji/') #视觉中国网站-科技主题图片
# self.le_url.adjustSize()
self.btn_back=QPushButton('返回',self)
self.btn_back.setGeometry(460,100,40,20)
self.btn_back.clicked.connect(self.webpageback)
self.btn_get_url = QPushButton('获取列表', self)
self.btn_get_url.setGeometry(520, 60, 80, 30)
#self.btn_get_url.adjustSize()
self.btn_get_url.clicked.connect(self.get_image_list)
# 图片列表
self.te = QTextEdit(self)
self.te.setGeometry(520, 120, 320, 600)
self.lbl_list_img = QLabel(self)
self.lbl_list_img.setText('图片列表:')
self.lbl_list_img.setGeometry(520, 100, 100, 20)
#self.lbl_list_img.adjustSize()
# 图片张数统计
self.lbl_imgnumber = QLabel(self)
self.lbl_imgnumber.setText('0张图片')
self.lbl_imgnumber.setGeometry(620, 100, 160, 20)
self.btn_save_document = QPushButton('选择保存地址', self)
self.btn_save_document.setGeometry(900, 130, 100, 30)
#self.btn_save_document.adjustSize()
self.btn_save_document.clicked.connect(self.save_document)
# 显示选择的保存文件夹地址
self.lbl_save_document1=QLabel(self)
self.lbl_save_document1.setGeometry(900,160,60,20)
self.lbl_save_document1.setText("保存路径:")
self.lbl_save_document2 = QLabel(self)
self.lbl_save_document2.setGeometry(900, 180, 300, 20)
self.lbl_save_document2.setText(self.dic)
#self.lbl_save_document2.adjustSize()
self.btn_download_all = QPushButton('全部下载', self)
self.btn_download_all.setGeometry(900, 240, 100, 30)
#self.btn_download_all.adjustSize()
self.btn_download_all.clicked.connect(self.download_img_all)
self.btn_download_single = QPushButton('单张下载', self)
self.btn_download_single.setGeometry(900, 320, 100, 30)
#self.btn_download_single.adjustSize()
self.btn_download_single.clicked.connect(self.download_img_single)
# 单张下载选择号
self.le_img_num_single = QLineEdit(self)
self.le_img_num_single.setGeometry(1100, 320, 60, 20)
self.lbl_img_num_single = QLabel(self)
self.lbl_img_num_single.setText('下载编号')
self.lbl_img_num_single.setGeometry(1030, 320, 60, 20)
self.btn_download_x = QPushButton('任意张下载', self)
self.btn_download_x.setGeometry(900, 400, 100, 30)
#self.btn_download_x.adjustSize()
self.btn_download_x.clicked.connect(self.download_img_x)
# 多张下载起始编号
self.le_img_start_num_x = QLineEdit(self)
self.le_img_start_num_x.setGeometry(1030, 430, 60, 20)
# 起始编号文本
self.lbl_img_start_num_x = QLabel(self)
self.lbl_img_start_num_x.setText('起始编号')
self.lbl_img_start_num_x.setGeometry(1030, 400, 60, 20)
# 多张下载张数
self.le_img_num_x = QLineEdit(self)
self.le_img_num_x.setGeometry(1100, 430, 60, 20)
# 下载张数文本
self.lbl_img_num_x = QLabel(self)
self.lbl_img_num_x.setText('下载张数')
self.lbl_img_num_x.setGeometry(1100, 400, 60, 20)
# 标题带超链接
self.lbl_head_title = QLabel(self)
self.lbl_head_title.setOpenExternalLinks(True)
# self.lbl_head_title.linkHovered.connect()
# self.lbl_head_title.linkActivated.connect()
self.lbl_head_title.setText("支持网站:视觉中国网https://www.vcg.com/")
self.lbl_head_title.setGeometry(20, 20, 400, 20)
#self.lbl_head_title.adjustSize()
# 图片带超链接(baidu)
self.lbl_link_1 = QLabel(self)
self.lbl_link_1.setPixmap(QPixmap('python-paichong\img\百度logo.png')) # 设置图标,与文字冲突,则setText的文字不显示
self.lbl_link_1.mousePressEvent = self.photo_link # 设置图片点击事件
self.lbl_link_1.setGeometry(320, 10, 80, 40)
self.lbl_link_2 = QLabel(self)
self.lbl_link_2.setPixmap(QPixmap('python-paichong\img\sjzglogo.png'))
self.lbl_link_2.mousePressEvent = self.photo_link2
self.lbl_link_2.setGeometry(400, 10, 100, 40)
# 窗口
self.setGeometry(100, 40, 1000, 600)
self.setWindowTitle('图片下载器')
self.setWindowIcon(QIcon('python-paichong\img\img1.png'))
self.setStyleSheet(self.qssstyle)
self.showMaximized() #窗口最大化
self.show()
def photo_link(self, test):
pass
#webbrowser.open('https://www.baidu.com/')
#self.webview.load(QUrl("https://www.baidu.com/"))
def photo_link2(self, test):
#webbrowser.open('https://www.vcg.com/')
self.urltemp=self.le_website.text()
self.webview.load(QUrl(self.urltemp))
def urlchange_f(self):
"""当网页URL改变时,获取其URL并显示"""
self.webview.setZoomFactor(0.5)
self.urltemp=self.webview.url().url()
#self.dic=self.webview.url().url()
self.le_url.setText(self.urltemp)
#print(self.webview.url().url())
self.le_website.setText(self.urltemp)
def webpageback(self):
self.history=self.webview.history()
self.history.back()
def get_image_list(self):
# 获取图片列表
try:
self.url = self.le_url.text()
# print(self.url)
print("已经开始执行,请等待!")
begin_time = int(time.time())
self.get_img_url_list(self.url)
# get_page_info()
end_time = int(time.time())
print(f"持续时间:{end_time - begin_time}秒")
print("执行结束")
except Exception as e:
QMessageBox.information(self, '输入提示', '异常: '+str(e), QMessageBox.Yes | QMessageBox.No,
defaultButton=QMessageBox.No)
print('异常:',e)
def save_document(self):
# 选择文件夹并显示文件夹路径
self.dic = QFileDialog.getExistingDirectory(self, "保存地址", 'C:/')
# print(self.dic)
self.lbl_save_document2.adjustSize()
def download_img_all(self):
# 全部图片下载
for self.img_url_list_1 in self.img_url_list:
# print(self.img_url_list_1)
self.img_src = self.img_url_list_1['img-src']
self.name = self.img_url_list_1['name']
# print('当前下载图片:'+self.name+'\n'+self.img_src)
self.save_image(self.img_src, self.name)
def download_img_single(self):
# 根据所选择的编号,下载单张图片
self.img_num_single = int(self.le_img_num_single.text())
self.img_url_single = self.img_url_list[self.img_num_single - 1]
self.img_url_single_name = self.img_url_single['name']
self.img_url_single_src = self.img_url_single['img-src']
print('当前下载图片:' + '\n' + '图片名称:' + self.img_url_single_name +
'\n' + '图片链接:' + self.img_url_single_src)
self.save_image(self.img_url_single_src, self.img_url_single_name)
def download_img_x(self):
# 根据所选起始编号和张数,下载图片
if self.le_img_num_x.text() == '' or self.le_img_start_num_x.text() == '':
QMessageBox.information(self, '输入提示', '请输入正确的起始编号和张数!', QMessageBox.Yes | QMessageBox.No,
# print('输入错误!')
exit
else:
self.img_num_x_startnum = int(self.le_img_start_num_x.text())
self.img_num_x_num = int(self.le_img_num_x.text())
self.img_x_list = self.img_url_list[
(self.img_num_x_startnum - 1):(self.img_num_x_startnum - 1 + self.img_num_x_num)]
for self.img_x_list_1 in self.img_x_list:
self.img_x_src = self.img_x_list_1['img-src']
self.name_x = self.img_x_list_1['name']
print('当前下载图片:' + '\n' + '图片名称:' + self.name_x +
'\n' + '图片链接:' + self.img_x_src)
self.save_image(self.img_x_src, self.name_x)
print(self.img_num_x_num)
def save_image(self, urlpath, name):
# 依据图片的详细完整链接地址,保存图片至本地文件夹
# img_dir='C:/Users/rongjv/Desktop'
img_dir = self.dic
# 远程打开图片写入到本地 第一种方式open
# with open(f"{image_dir}/{img_name}", mode="wb") as add:
# add.write(requests.get(image_path).content)
# 远程打开图片写入到本地 第二种方式urllib
fl=f"{img_dir}/{name}.jpg"
#print(fl)
QMessageBox.information(self, '提示', '下载完成', QMessageBox.Ok,
defaultButton=QMessageBox.Ok)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = example()
sys.exit(app.exec_())
实例演示:
相关文章
本文由 用户 于 2024-01-16 发布在 夸智网,如有疑问,请联系我们。本文链接:https://www.kuazhi.com/post/712893076.html
网络安全 漏洞挖掘 CTF 玲珑安全第三期如约而至
Jenkins新建项目中源码管理Repository URL使用Git报错:Failed to connect to repository : Command "git ls-remote -h......
web安全 【DevOps】网络安全进阶之路:打造更安全、更可靠的网站
华为交换机流量统计
安全 Ruoyi若依漏洞复现总结
软件工程 软件设计 探索设计模式的魅力:分布式模式让业务更高效、更安全、更稳定
前端框架 收藏
[Deepin 15] 编译安装 PHP-5.6.30
发表评论