整体思路和之前的一篇博客爬虫豆瓣美女一致,这次加入了图片分类,同时利用tkinter模块做成GUI程序

效果如下:

整体代码如下:

  1. # -*- coding:utf-8 -*-
  2.  
  3. import requests
  4. from requests.exceptions import RequestException
  5. import tkinter as tk
  6. from tkinter import ttk
  7. from bs4 import BeautifulSoup
  8. import bs4
  9. from tkinter import *
  10. from tkinter.filedialog import askdirectory
  11. import os
  12.  
  13. class DB():
  14. def __init__(self):
  15. self.window = tk.Tk() #创建window窗口
  16. self.window.title("Crawler Pics") # 定义窗口名称
  17. # self.window.resizable(0,0) # 禁止调整窗口大小
  18. self.menu = ttk.Combobox(self.window,width=6)
  19. self.path = StringVar()
  20. self.lab1 = tk.Label(self.window, text = "目标路径:")
  21. self.lab2 = tk.Label(self.window, text="选择分类:")
  22. self.lab3 = tk.Label(self.window, text="爬取页数:")
  23. self.page = tk.Entry(self.window, width=5)
  24. self.input = tk.Entry(self.window, textvariable = self.path, width=80) # 创建一个输入框,显示图片存放路径
  25. self.info = tk.Text(self.window, height=20) # 创建一个文本展示框,并设置尺寸
  26.  
  27. self.menu['value'] = ('大胸妹','小翘臀', '黑丝袜', '美腿控', '有颜值','大杂烩')
  28. self.menu.current(0)
  29.  
  30. # 添加一个按钮,用于选择图片保存路径
  31. self.t_button = tk.Button(self.window, text='选择路径', relief=tk.RAISED, width=8, height=1, command=self.select_Path)
  32. # 添加一个按钮,用于触发爬取功能
  33. self.t_button1 = tk.Button(self.window, text='爬取', relief=tk.RAISED, width=8, height=1,command=self.download)
  34. # 添加一个按钮,用于触发清空输出框功能
  35. self.c_button2 = tk.Button(self.window, text='清空输出', relief=tk.RAISED,width=8, height=1, command=self.cle)
  36.  
  37. def gui_arrang(self):
  38. """完成页面元素布局,设置各部件的位置"""
  39. self.lab1.grid(row=0,column=0)
  40. self.lab2.grid(row=1, column=0)
  41. self.menu.grid(row=1, column=1,sticky=W)
  42. self.lab3.grid(row=2, column=0,padx=5,pady=5,sticky=tk.W)
  43. self.page.grid(row=2, column=1,sticky=W)
  44. self.input.grid(row=0,column=1)
  45. self.info.grid(row=3,rowspan=5,column=0,columnspan=3,padx=15,pady=15)
  46. self.t_button.grid(row=0,column=2,padx=5,pady=5,sticky=tk.W)
  47. self.t_button1.grid(row=1,column=2)
  48. self.c_button2.grid(row=0,column=3,padx=5,pady=5,sticky=tk.W)
  49.  
  50. def get_cid(self):
  51. category = {
  52. 'DX': 2,
  53. 'XQT': 6,
  54. 'HSW': 7,
  55. 'MTK': 3,
  56. 'YYZ': 4,
  57. 'DZH': 5
  58. }
  59. cid = None
  60. if self.menu.get() == "大胸妹":
  61. cid = category["DX"]
  62. elif self.menu.get() == "小翘臀":
  63. cid = category["XQT"]
  64. elif self.menu.get() == "黑丝袜":
  65. cid = category["HSW"]
  66. elif self.menu.get() == "美腿控":
  67. cid = category["MTK"]
  68. elif self.menu.get() == "有颜值":
  69. cid = category["YYZ"]
  70. elif self.menu.get() == "大杂烩":
  71. cid = category["DZH"]
  72. return cid
  73.  
  74. def select_Path(self):
  75. """选取本地路径"""
  76. path_ = askdirectory()
  77. self.path.set(path_)
  78.  
  79. def get_html(self, url, header=None):
  80. """请求初始url"""
  81. response = requests.get(url, headers=header)
  82. try:
  83. if response.status_code == 200:
  84. # print(response.status_code)
  85. # print(response.text)
  86. return response.text
  87. return None
  88. except RequestException:
  89. print("请求失败")
  90. return None
  91.  
  92. def parse_html(self, html, list_data):
  93. """提取img的名称和图片url,并将名称和图片地址以字典形式返回"""
  94. soup = BeautifulSoup(html, 'html.parser')
  95. img = soup.find_all('img')
  96. for t in img:
  97. if isinstance(t, bs4.element.Tag):
  98. # print(t)
  99. name = t.get('alt')
  100. img_src = t.get('src')
  101. list_data.append([name, img_src])
  102. dict_data = dict(list_data)
  103. return dict_data
  104.  
  105. def get_image_content(self, url):
  106. """请求图片url,返回二进制内容"""
  107. print("正在下载", url)
  108. self.info.insert('end',"正在下载:"+url+'\n')
  109. try:
  110. r = requests.get(url)
  111. if r.status_code == 200:
  112. return r.content
  113. return None
  114. except RequestException:
  115. return None
  116.  
  117. def download(self):
  118. base_url = 'https://www.dbmeinv.com/index.htm?'
  119. for i in range(1, int(self.page.get())+1):
  120. url = base_url + 'cid=' + str(self.get_cid()) + '&' + 'pager_offset=' + str(i)
  121. # print(url)
  122. header = {
  123. 'Accept': 'text/html,application/xhtml+xml,application/xml;q = 0.9, image/webp,image/apng,*/*;q='
  124. '0.8',
  125. 'Accept-Encoding': 'gzip,deflate,br',
  126. 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
  127. 'Cache-Control': 'max-age=0',
  128. 'Connection': 'keep-alive',
  129. 'Host': 'www.dbmeinv.com',
  130. 'Upgrade-Insecure-Requests': '',
  131. 'User-Agent': 'Mozilla/5.0(WindowsNT6.1;Win64;x64) AppleWebKit/537.36(KHTML, likeGecko) Chrome/'
  132. '70.0.3538.102Safari/537.36 '
  133. }
  134. list_data = []
  135. html = self.get_html(url)
  136. # print(html)
  137. dictdata = self.parse_html(html, list_data)
  138.  
  139. root_dir = self.input.get()
  140. case_list = ["大胸妹", "小翘臀", "黑丝袜", "美腿控", "有颜值", "大杂烩"]
  141. for t in case_list:
  142. if not os.path.exists(root_dir + '/pics'):
  143. os.makedirs(root_dir + '/pics')
  144. if not os.path.exists(root_dir + '/pics/' + str(t)):
  145. os.makedirs(root_dir + '/pics/' + str(t))
  146.  
  147. if self.menu.get() == "大胸妹":
  148. save_path = root_dir + '/pics/' + '大胸妹'
  149. for t in dictdata.items():
  150. try:
  151. # file_path = '{0}/{1}.{2}'.format(save_path, t[1], 'jpg')
  152. file_path = save_path + '/' + t[0] + 'q' + '.jpg'
  153. if not os.path.exists(file_path): # 判断是否存在文件,不存在则爬取
  154. with open(file_path, 'wb') as f:
  155. f.write(self.get_image_content(t[1]))
  156. f.close()
  157. print('文件保存成功')
  158. except FileNotFoundError:
  159. continue
  160.  
  161. elif self.menu.get() == "小翘臀":
  162. save_path = root_dir + '/pics/' + '小翘臀'
  163. for t in dictdata.items():
  164. try:
  165. # file_path = '{0}/{1}.{2}'.format(save_path, t[1], 'jpg')
  166. file_path = save_path + '/' + t[0] + 'q' + '.jpg'
  167. if not os.path.exists(file_path): # 判断是否存在文件,不存在则爬取
  168. with open(file_path, 'wb') as f:
  169. f.write(self.get_image_content(t[1]))
  170. f.close()
  171. print('文件保存成功')
  172. except FileNotFoundError:
  173. continue
  174.  
  175. elif self.menu.get() == "黑丝袜":
  176. save_path = root_dir + '/pics/' + '黑丝袜'
  177. for t in dictdata.items():
  178. try:
  179. # file_path = '{0}/{1}.{2}'.format(save_path, t[1], 'jpg')
  180. file_path = save_path + '/' + t[0] + 'q' + '.jpg'
  181. if not os.path.exists(file_path): # 判断是否存在文件,不存在则爬取
  182. with open(file_path, 'wb') as f:
  183. f.write(self.get_image_content(t[1]))
  184. f.close()
  185. print('文件保存成功')
  186. except FileNotFoundError:
  187. continue
  188.  
  189. elif self.menu.get() == "美腿控":
  190. save_path = root_dir + '/pics/' + '美腿控'
  191. for t in dictdata.items():
  192. try:
  193. # file_path = '{0}/{1}.{2}'.format(save_path, t[1], 'jpg')
  194. file_path = save_path + '/' + t[0] + 'q' + '.jpg'
  195. if not os.path.exists(file_path): # 判断是否存在文件,不存在则爬取
  196. with open(file_path, 'wb') as f:
  197. f.write(self.get_image_content(t[1]))
  198. f.close()
  199. print('文件保存成功')
  200. except FileNotFoundError:
  201. continue
  202.  
  203. elif self.menu.get() == "有颜值":
  204. save_path = root_dir + '/pics/' + '有颜值'
  205. for t in dictdata.items():
  206. try:
  207. # file_path = '{0}/{1}.{2}'.format(save_path, t[1], 'jpg')
  208. file_path = save_path + '/' + t[0] + 'q' + '.jpg'
  209. if not os.path.exists(file_path): # 判断是否存在文件,不存在则爬取
  210. with open(file_path, 'wb') as f:
  211. f.write(self.get_image_content(t[1]))
  212. f.close()
  213. print('文件保存成功')
  214. except OSError:
  215. continue
  216.  
  217. elif self.menu.get() == "大杂烩":
  218. save_path = root_dir + '/pics/' + '大杂烩'
  219. for t in dictdata.items():
  220. try:
  221. # file_path = '{0}/{1}.{2}'.format(save_path, t[1], 'jpg')
  222. file_path = save_path + '/' + t[0] + 'q' + '.jpg'
  223. if not os.path.exists(file_path): # 判断是否存在文件,不存在则爬取
  224. with open(file_path, 'wb') as f:
  225. f.write(self.get_image_content(t[1]))
  226. f.close()
  227. print('文件保存成功')
  228. except FileNotFoundError:
  229. continue
  230.  
  231. def cle(self):
  232. """定义一个函数,用于清空输出框的内容"""
  233. self.info.delete(1.0,"end") # 从第一行清除到最后一行
  234.  
  235. def main():
  236. t = DB()
  237. t.gui_arrang()
  238. tk.mainloop()
  239.  
  240. if __name__ == '__main__':
  241. main()

关键点:

1.如何使用tkinter调用系统路径

2.构造url,参数化图片分类、抓取页数

3.使用tkinter获取输入参数传给执行代码


下面是练习的时候写的简陋版,不包含tkinter,主要是理清思路:

  1. import re
  2. import requests
  3. import os
  4. from requests.exceptions import RequestException
  5.  
  6. case = str(input("请输入你要下载的图片分类:"))
  7. category = {
  8. 'DX': 2,
  9. 'XQT': 6,
  10. 'HSW': 7,
  11. 'MTK': 3,
  12. 'YYZ': 4,
  13. 'DZH': 5
  14. }
  15. def get_cid():
  16. cid = None
  17. if case == "大胸妹":
  18. cid = category["DX"]
  19. elif case == "小翘臀":
  20. cid = category["XQT"]
  21. elif case == "黑丝袜":
  22. cid = category["HSW"]
  23. elif case == "美腿控":
  24. cid = category["MTK"]
  25. elif case == "有颜值":
  26. cid = category["YYZ"]
  27. elif case == "大杂烩":
  28. cid = category["DZH"]
  29. return cid
  30.  
  31. base_url = 'https://www.dbmeinv.com/index.htm?'
  32. url = base_url + 'cid=' + str(get_cid())
  33. r = requests.get(url)
  34. # print(r.status_code)
  35. html = r.text
  36. # print(r.text)
  37. # print(html)
  38.  
  39. name_pattern = re.compile(r'<img class="height_min".*?title="(.*?)"', re.S)
  40. src_pattern = re.compile(r'<img class="height_min".*?src="(.*?.jpg)"', re.S)
  41.  
  42. name = name_pattern.findall(html) # 提取title
  43. src = src_pattern.findall(html) # 提取src
  44. data = [name,src]
  45. # print(name)
  46. # print(src)
  47. d=[]
  48. for i in range(len(name)):
  49. d.append([name[i], src[i]])
  50.  
  51. dictdata = dict(d)
  52. # for i in dictdata.items():
  53. # print(i)
  54.  
  55. def get_content(url):
  56. try:
  57. r = requests.get(url)
  58. if r.status_code == 200:
  59. return r.content
  60. return None
  61. except RequestException:
  62. return None
  63.  
  64. root_dir = os.path.dirname(os.path.abspath('.'))
  65.  
  66. case_list = ["大胸妹","小翘臀","黑丝袜","美腿控","有颜值","大杂烩"]
  67. for t in case_list:
  68. if not os.path.exists(root_dir+'/pics'):
  69. os.makedirs(root_dir+'/pics')
  70. if not os.path.exists(root_dir+'/pics/'+str(t)):
  71. os.makedirs(root_dir+'/pics/'+str(t))
  72.  
  73. def Type(type):
  74. save_path = root_dir + '/pics/' + str(type)
  75. # print(save_path)
  76. for t in dictdata.items():
  77. try:
  78. #file_path = '{0}/{1}.{2}'.format(save_path, t[1], 'jpg')
  79. file_path = save_path + '/' + t[0]+ 'q' +'.jpg'
  80. print("正在下载: "+'"'+t[0]+'"'+t[1])
  81. if not os.path.exists(file_path): # 判断是否存在文件,不存在则爬取
  82. with open(file_path, 'wb') as f:
  83. f.write(get_content(t[1]))
  84. f.close()
  85. except FileNotFoundError:
  86. continue
  87. if case == "大胸妹":
  88. Type(case)
  89.  
  90. elif case == "小翘臀":
  91. Type(case)
  92.  
  93. elif case == "黑丝袜":
  94. Type(case)
  95.  
  96. elif case == "美腿控":
  97. Type(case)
  98.  
  99. elif case == "有颜值":
  100. Type(case)
  101.  
  102. elif case == "大杂烩":
  103. Type(case)

效果如下

使用python做一个爬虫GUI程序的更多相关文章

  1. 用python做一个搜索引擎(Pylucene)

    什么是搜索引擎? 搜索引擎是“对网络信息资源进行搜集整理并提供信息查询服务的系统,包括信息搜集.信息整理和用户查询三部分”.如图1是搜索引擎的一般结构,信息搜集模块从网络采集信息到网络信息库之中(一般 ...

  2. fir.im Weekly - 如何做一个出色的程序员

    做一个出色的程序员,困难而高尚.本期 fir.im Weekly 精选了一些实用的 iOS,Android 开发工具和源码分享,还有一些关于程序员的成长 Tips 和有意思有质量的线下活动~ How ...

  3. 做一个懒COCOS2D-X程序猿(一)停止手打所有cpp文件到android.mk

    前言:”懒”在这里当然不是贬义词,而是追求高效,拒绝重复劳动的代名词!做一个懒COCOS2D-X程序猿的系列文章将教会大家在工作中如何偷懒,文章篇幅大多较短,有的甚至只是几行代码,争取把懒发挥到极致! ...

  4. 用Python做一个知乎沙雕问题总结

    用Python做一个知乎沙雕问题总结 松鼠爱吃饼干2020-04-01 13:40 前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以 ...

  5. 使用python做一个IRC在线下载器

    使用python做一个IRC在线下载器 1.开发流程 2.软件流程 3.开始 3.0 准备工作 3.1寻找API接口 3.2 文件模块 3.2.1 选择文件弹窗 3.2.2 提取文件名 3.2.2.1 ...

  6. 媳妇儿喜欢玩某音中的动漫特效,那我就用python做一个图片转化软件。

    ​    最近某音上的动漫特效特别火,很多人都玩着动漫肖像,我媳妇儿也不例外.看着她这么喜欢这个特效,我决定做一个图片处理工具,这样媳妇儿的动漫头像就有着落了.编码    为了快速实现我们的目标,我们 ...

  7. 用Python做一个简单的翻译工具

    编程本身是跟年龄无关的一件事,不论你现在是十四五岁,还是四五十岁,如果你热爱它,并且愿意持续投入其中,必定会有所收获. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过 ...

  8. NetAnalyzer笔记 之 三. 用C++做一个抓包程序

    [创建时间:2015-08-27 22:15:17] NetAnalyzer下载地址 经过前两篇的瞎扯,你是不是已经厌倦了呢,那么这篇让我们来点有意思的吧,什么,用C#.不,这篇我们先来C++的 Wi ...

  9. 在树莓派上用 python 做一个炫酷的天气预报

    教大家如何在树莓派上自己动手做一个天气预报.此次教程需要大家有一定的python 基础,没有也没关系,文末我会放出我已写好的代码供大家下载. 首先在开始之前 需要申请高德地图API,去高德地图官网注册 ...

随机推荐

  1. C++并发编程实战

    第1章 你好,C++并发世界 第2章 管理线程 第3章 在线程间数据共享 第4章 同步并发操作 第5章 C++内存模型和原子类型操作 第6章 设计基于锁的并发数据结构 第7章 设计无锁的并发数据结构 ...

  2. vue框架学习笔记(vue入门篇)

    vue框架 - 构建用户界面的渐进式框架 - 采用自底层向上增量开发的设计 - 核心库只关注视图层 - 当与单文件组件和vue生态系统支持的库结合使用时,也完全能够为复杂的单页应用程序提供驱动 - v ...

  3. MS SQL OPENJSON JSON

    前段时间,有写过一个小练习<MS SQL读取JSON数据>https://www.cnblogs.com/insus/p/10911739.html 晚上为一个网友的问题,尝试获取较深层节 ...

  4. python 学习(day1)

    初识python python的创始人为吉多*范罗苏姆(Guido van Rossum).1989年圣诞节期间,开发出来的脚本解释程序. python是⼀⻔什么样的语言 python 是一门解释型语 ...

  5. webpack入门配置步骤详解

    1.初始化 1.npm install webpack webpack-cli webpack-dev-server --g 全局安装必要的第三方插件 2.mkdir config dist src ...

  6. 详解JAVA8函数式接口{全}

    1: 函数式接口 1.1 概念 1.2 格式 1.3@FunctionalInterface注解 1.4 调用自定义函数接口 2:函数式编程 2.1:lambda的延迟执行 2.2 使用Lambda作 ...

  7. 现代C++实现多种print

    目录 Print Version1 Print Version2 Print Version3 Print Version4 容器的Print tuple容器的print 结语 学习C++的朋友会遇到 ...

  8. 关于 ASP.NET Core 中的 RazorPages

    Contact.cshtml @page @model ContactModel @{ ViewData["Title"] = "Contact"; } < ...

  9. 数据库——SQL-SERVER练习(4) 建表及数据完整性

    1. 输入下图的语句, 建立学生表STU. CREATE TABLE STU ( SNO NUMERIC() PRIMARY KEY, SNANE CHAR() NOT NULL, SSEX CHAR ...

  10. Spring Boot 中如何定制 Banner

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...