Qt+Python开发百度图片下载器

亮琴软件工作室 2021-09-15 14:13:08
Python 百度 Qt 开发 qt+python


一、资源下载地址

https://www.aliyundrive.com/s/jBU2wBS8poH

本项目路径:项目->收费->百度图片下载器(可试用5分钟)

安装包直接下载地址:http://139.9.165.1/media/BaiduPicDown.exe

二、项目介绍

1、本项目使用Vs2019+Qt+Python库来开发一个百度图片播放下载器(支持Gif)。

Qt播放Gif图片参考文章:

https://www.cnblogs.com/liangqin/p/15161809.html

本文主要描述Qt调用Python库来获取百度图片。

2、本项目完成的功能如下:

(1)、支持通过搜索关键词及图片张数来获取百度图片进行循环播放及保存原文件。

(2)、支持设置播放图片窗口大小。

(3)、支持Gif图片。

3、效果展示:

三、项目开始

1、准备工作

搭建一份Qt播放Gif图片的工程环境。然后获取python对应平台的头文件及库:

注意:安装的pythonLib目录下有很多文件,整个目录比较大,不便于我们程序发布。我们只需要保留程序所需要的文件即可,找到本程序的安装路径即可看到基本所需的Lib文件。

2、python程序来爬取百度图片

这里参考文章:

https://blog.csdn.net/xiligey1/article/details/73321152

然后进行简单修改,提供一个getImgUrls(key,num)接口给C++调用获取当前关键词多少张urls,提供一个getImg()接口给C++调用循环获取爬取到的图片,该接口返回给C++的是图片的base64编码。

修改后的内容如下:

baidu_photo_spider.py

 1 """根据搜索词下载百度图片"""
 2 import os
 3 import re
 4 import base64
 5 import time
 6 from typing import List, Tuple
 7 from urllib.parse import quote
 8
 9 import requests
 10
 11 from conf import *
 12
 13 # 关键词, 改为你想输入的词即可, 相当于在百度图片里搜索一样
 14 keyword = '治愈系柴犬'
 15
 16 # 最大下载数量
 17 max_download_images = 100
 18
 19 all_pic_urls = []
 20 count = 0
 21
 22 def get_page_urls(page_url: str, headers: dict) -> Tuple[List[str], str]:
 23 """获取当前翻页的所有图片的链接
 24  Args:
 25  page_url: 当前翻页的链接
 26  headers: 请求表头
 27  Returns:
 28  当前翻页下的所有图片的链接, 当前翻页的下一翻页的链接
 29 """
 30 if not page_url:
 31 return [], ''
 32 try:
 33 html = requests.get(page_url, headers=headers)
 34 html.encoding = 'utf-8'
 35 html = html.text
 36 except IOError as e:
 37  print(e)
 38 return [], ''
 39 pic_urls = re.findall('"objURL":"(.*?)",', html, re.S)
 40 next_page_url = re.findall(re.compile(r'<a href="(.*)" class="n">下一页</a>'), html, flags=0)
 41 next_page_url = 'http://image.baidu.com' + next_page_url[0] if next_page_url else ''
 42 return pic_urls, next_page_url
 43
 44 def getImgUrls(key,num):
 45 global keyword
 46 global max_download_images
 47 global all_pic_urls
 48 keyword = key
 49 max_download_images = num
 50 url_init = url_init_first + quote(keyword, safe='/')
 51 page_urls, next_page_url = get_page_urls(url_init, headers)
 52  all_pic_urls.extend(page_urls)
 53 page_count = 0
 54 while 1:
 55 page_urls, next_page_url = get_page_urls(next_page_url, headers)
 56 page_count += 1
 57 print('正在获取第%s个翻页的所有图片链接' % str(page_count))
 58 if next_page_url == '' and page_urls == []:
 59 print('已到最后一页,共计%s个翻页' % page_count)
 60 return
 61  all_pic_urls.extend(page_urls)
 62 if len(all_pic_urls) >= max_download_images:
 63 print('已达到设置的最大下载数量%s' % max_download_images)
 64 return
 65
 66 def down_pic(i,pic_url):
 67 try:
 68 pic = requests.get(pic_url, timeout=15)
 69 image_output_path = './images/' + str(i + 1) + '.jpg'
 70 with open(image_output_path, 'wb') as f:
 71  f.write(pic.content)
 72 print('成功下载第%s张图片: %s' % (str(i + 1), str(pic_url)))
 73 except IOError as e:
 74 print('下载第%s张图片时失败: %s' % (str(i + 1), str(pic_url)))
 75  print(e)
 76 return
 77
 78 def getImg():
 79 global all_pic_urls
 80 global count
 81 global max_download_images
 82 none='none'
 83 try:
 84 pic = requests.get(list(set(all_pic_urls))[count], timeout=15)
 85 imgbase64 = base64.b64encode(pic.content).decode()
 86  #print(count)
 87 count += 1
 88 if count == max_download_images:
 89 count = 0
 90 return imgbase64,none
 91 except IOError as e:
 92  print(e)
 93 return none,none
 94
 95 if __name__ == '__main__':
 96 if not os.path.exists('./images'):
 97 os.mkdir('./images')
 98
 99 getImgUrls('', 2)
100
101  #下载图片
102 for i, pic_url in enumerate(list(set(all_pic_urls))[:max_download_images]):
103  down_pic(i, pic_url)
104
105  #循环读取列表中的图片
106 while 1:
107  print(getImg())
108 time.sleep(5)

 3、封装C++调用python库的接口

直接上代码:

 1 #include "PythonDevApi.h"
 2 #include "Python.h"
 3
 4 void initPython()
 5 {
 6 Py_Initialize();//加载Python解释器
 7 PyRun_SimpleString("import sys");
 8 PyRun_SimpleString("sys.path.append('Dlls/')");
 9 }
10
11 void unInitPython()
12 {
13 Py_Finalize();//卸载Python解释器
14 }
15
16 static PyObject* pBaiduModule = NULL;
17
18 int pyGetBaiduImgInit(const char* key, int num)
19 {
20 pBaiduModule = PyImport_ImportModule("baidu_photo_spider");//Python py文件名
21  PyImport_ReloadModule(pBaiduModule);
22 if (pBaiduModule == nullptr)
23 return -1;
24
25 PyObject* pFunc = NULL;
26 PyObject* pArgs = NULL;
27 PyObject* pResult = NULL;
28 pFunc = PyObject_GetAttrString(pBaiduModule, "getImgUrls");//py文件内函数名
29 //执行函数
30 pArgs = Py_BuildValue("si", key, num);
31 pResult = PyObject_CallObject(pFunc, pArgs);
32
33 return 0;
34 }
35
36 int pyGetBaiduImgWork(char* img, int imgSize)
37 {
38 //执行函数
39 PyObject* pBaiduFunc = PyObject_GetAttrString(pBaiduModule, "getImg");//py文件内函数名
40 if (pBaiduFunc == NULL)
41 return -1;
42
43 PyObject* pArgs = NULL;
44 PyObject* pResult = PyObject_CallObject(pBaiduFunc, pArgs);
45 if (pResult == NULL)
46 return -1;
47
48 char* imgbase64, * none;
49 int ret = PyArg_ParseTuple(pResult, "s|s", &imgbase64, &none);
50 if (ret == 1)
51  {
52 if (memcmp(imgbase64, none, strlen(none)) != 0 && img != NULL && strlen(imgbase64) < imgSize)
53  {
54  memcpy(img, imgbase64, strlen(imgbase64));
55 return 0;
56  }
57  }
58 else
59  {
60 printf("ret:%d\n", ret);
61  }
62
63 return -1;
64 }
65
66 int pyGetBaiduImgUninit()
67 {
68 return 0;
69 }

4、调用封装好的python接口来进行图片获取与保存文件:

 1 void GuiQtDevThread::run()
 2 {
 3 int count = 0;
 4
 5  pyGetBaiduImgInit(m_key.toStdString().c_str(), m_num);
 6
 7 while (1)
 8  {
 9 //程序退出时终止线程
10 if (m_gui->getGetImgThreadState() == THREAD_STATE_E_PrepareStop)
11  {
12 m_gui->setGetImgThreadState(THREAD_STATE_E_Stop);
13  pyGetBaiduImgUninit();
14 return ;
15  }
16 count++;
17 if (count == 50)
18  {
19 count = 0;
20 //只能使用emit方式操作控件,直接操作控件会死机,这里会等待槽函数结束才继续运行(Qt::BlockingQueuedConnection)
21 memset(m_img, 0, m_img_size);
22 int ret = pyGetBaiduImgWork(m_img, m_img_size);
23 if (ret != 0)
24  {
25 QThread::msleep(100);
26 continue;
27  }
28
29 QByteArray decodeimg = QByteArray::fromBase64(m_img);
30
31  CQVString filenamet;
32 filenamet.Append("%s%d", "imgtmp", _getpid());
33  QFile file(filenamet.GetBuffer());
34  file.open(QIODevice::WriteOnly);
35  file.write(decodeimg);
36  file.close();
37 QThread::msleep(50);
38
39 QString saveFileName = m_gui->getSaveDir();
40 if (saveFileName.length() > 1)
41  {
42 bool dirExist = true;
43  QDir dir;
44 if (!dir.exists(saveFileName))
45  {
46 dirExist = dir.mkdir(saveFileName);
47  }
48
49 if (dirExist)
50  {
51  CQVString filenamet;
52 filenamet.Append("%s%d", "imgtmp", _getpid());
53  QImageReader reader(filenamet.GetBuffer());
54 reader.setDecideFormatFromContent(true);
55 int nCount = reader.imageCount();
56 if (nCount > 0 && reader.canRead())
57  {
58  QString fileFomate(QImageReader::imageFormat(filenamet.GetBuffer()));
59
60 saveFileName += "/";
61 QDateTime current_date_time = QDateTime::currentDateTime();
62 QString current_date = current_date_time.toString("yyyy-MM-dd-hh-mm-ss");
63 saveFileName += current_date;
64 saveFileName += ".";
65 saveFileName += fileFomate;
66  QFile saveFile(saveFileName);
67  saveFile.open(QIODevice::WriteOnly);
68  saveFile.write(decodeimg);
69  saveFile.close();
70 QThread::msleep(50);
71
72  }
73  }
74  }
75
76 m_gui->setFileChange();
77  }
78 QThread::msleep(100);
79  }
80 }

 5、项目生成后事件需要把pythondll拷贝到exe目录下,并且把pythonDLLsLib目录以及我们写的py程序拷贝到主工程和exe目录下。这样才能保证vs2019和双击exe正常运行程序,如图:

 

 

版权声明
本文为[亮琴软件工作室]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/liangqin/p/15271958.html

  1. 从0起步学Python(附程序实例讲解)第1讲
  2. 从0起步学Python(附程序实例讲解)第1讲
  3. Apprendre Python à partir de 0 (avec des exemples de programme) leçon 1
  4. Apprendre Python à partir de 0 (avec des exemples de programme) leçon 1
  5. With Python, I'll take you to enjoy it for a month when the Mid Autumn Festival is coming
  6. You can't write interface software in Python! Which software on sale has no UI?
  7. Python国内外原题解析及源码1~15
  8. Python实现长篇英文自动纠错~
  9. Python implémente la correction automatique des erreurs en anglais long
  10. Analyse des problèmes originaux et code source de Python au pays et à l'étranger 1 ~ 15
  11. 一张思维导图学Python之表白
  12. Python教学中课程思政建设的研究探索2
  13. Recherche sur la construction idéologique et politique du Programme d'études dans l'enseignement Python 2
  14. Une présentation de la cartographie mentale Python
  15. Python高级用法总结(8)-函数式编程
  16. Python + Mirai development QQ robot starting tutorial (2021.9.9 test is valid)
  17. Python Advanced use Summary (8) - functional Programming
  18. How to get started with Python and share learning methods for free. All you want to know is here
  19. Python + Mirai development QQ robot starting tutorial (2021.9.9 test is valid)
  20. Python趣味编程中(PPT适合青少儿和零基础学习Python)
  21. Python基础第1讲(含代码、Python最新安装包、父与子的编程之旅:与小卡特一起学Python中文版)
  22. 用 Python 增强 Git
  23. Python基礎第1講(含代碼、Python最新安裝包、父與子的編程之旅:與小卡特一起學Python中文版)
  24. Base Python leçon 1 (y compris le Code, le dernier paquet d'installation Python, le voyage de programmation parent - enfant: apprendre la version chinoise de python avec le petit Carter)
  25. Dans la programmation amusante Python (ppt pour les jeunes enfants et l'apprentissage de base zéro Python)
  26. 非常好的题目详解Python字典的用法
  27. Python teaches you to build wechat push live Betta reminder from 0 (single room simplified version)
  28. Python 协程与 JavaScript 协程的对比
  29. 手把手带你用Python实现一个量化炒股策略
  30. Main dans la main pour mettre en œuvre une stratégie quantitative de spéculation boursière en python
  31. Comparaison des coproductions Python et JavaScript
  32. 【python种子项目ppc】一行代码生成项目与开发详细指导
  33. Docker 部署一个用 Python 编写的 Web 应用
  34. Python - poetry(4)管理环境
  35. Python - poetry(2)命令介绍
  36. [Python Seed Project PPC] a line of Code Generation Project and Development detailed guidance
  37. Introduction à la commande python - Poetry (2)
  38. Python - Poetry (4) Management Environment
  39. I collected Banhua's spatial data set in Python. In addition to meizhao, I found her other secrets again!
  40. I modified ban Hua's boot password in Python and found her secret after logging in again!
  41. After my girlfriend said good night to you, she was still online. I made a script in Python and successfully conquered it
  42. Python crawlers are used by you to climb sister pictures. We are ashamed to be with them!
  43. Python basic exercises, including answer analysis
  44. I used Python to capture the hot reviews of Wu's microblog events, chatting about technology and eating melons
  45. 60000 word summary of Python basic knowledge points, liver explosion, staying up late in a week [recommended collection]
  46. How do Python crawlers learn? Learn about the responsibilities of recruitment positions and see how much you can earn for your skills
  47. 20 lines of Python code crawl 2W multiple audio file materials [source code attached + detailed analysis] necessary for new media creation
  48. 微软开源浏览器自动化工具Playwright for Python(附源码)
  49. Python 中的进制转换
  50. Python 的算术运算符
  51. Python 的整数
  52. You love me, I love you. It's a headache for IP to be blocked [Python crawler practice: IP proxy JS reverse collection]
  53. Django learning knowledge points, road map, data summary, recommended collection!
  54. Headmaster Wang was hammered instead of flirting with his sister? No matter how rich you are, you just lick the dog [Python reptile actual combat: microblog comments]
  55. We are addicted to short videos and can't extricate ourselves? Python crawler advanced, take you to play short video
  56. How to learn Python Programming? Which books are suitable for beginners
  57. Python is so popular, what's the difference between it and other programming languages?
  58. Python web crawler - Jingdong Mall product list
  59. Django custom user model
  60. All the learning routes of Python and the knowledge system you want are here. Don't do useless work