吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4537|回复: 14
收起左侧

[Python 转载] 爬取wallhaven图片网站,结合tkinter进行简单封装

  [复制链接]
klmatao 发表于 2020-6-16 16:32
本帖最后由 klmatao 于 2020-6-16 17:12 编辑

爬取网站:https://wallhaven.cc/

爬虫代码:

from fake_useragent import UserAgent
import requests
import os
from lxml import etree

class getHtml:
    def __init__(self):
        self.headers = {"User-Agent": UserAgent().random}

    def do_get_resp(self,url):
        resp = requests.get(url, headers=self.headers)
        return resp

    def do_getHtml(self, url):
        resp = requests.get(url, headers=self.headers)
        resp.encoding = "utf-8"
        if resp.status_code == 200:
            return resp.text
        else:
            return None

class Save_pic:
    def save(self,title,resp_content,key,savepath):
        save_pic_path = savepath + r"\{0}".format(key)
        if os.path.exists(save_pic_path):
            pass
        else:
            os.makedirs(save_pic_path)
        with open(save_pic_path+r"\{0}".format(title),"wb") as f:
            f.write(resp_content)
            f.close() 

class ParseHtml:
    # 解析主页面上的更多标签
    def do_parse_search(self, html):
        e = etree.HTML(html)
        pages_all = e.xpath('//h2')[0].xpath("string(.)")
        # pages 为当前搜索结果中的总页数
        pages = pages_all[len(pages_all)-3:]
        # 获取当前搜索接种的总图片数
        all_counts = e.xpath('//h1')[0].xpath("string(.)").split("Wallpapers")[0]
        # 返回一个列表
        return [pages,all_counts]

    def do_get_pic_hrefs(self,msg_list,want_page,key):
        # 获取最大的页数
        max_page = int(msg_list[0])
        if int(want_page) <= max_page:
            max_page == int(want_page)
        elif int(want_page) > max_page:
            pass
        for i in range(1,max_page+1):
            url = "https://wallhaven.cc/search?q={0}&page={1}".format(key,i)
            html = getHtml().do_getHtml(url)
            e = etree.HTML(html)
            # 获取图片的href,并对其进行加工处理
            hrefs = e.xpath('//figure/img/@data-src')
            realy_hrefs = []
            for href_str in hrefs:
                href_str_new = href_str.replace("small","full").replace("th","w")
                realy_href = href_str_new[:int(href_str_new.rfind("/"))+1] + "wallhaven-" + href_str_new[int(href_str_new.rfind("/"))+1:]
                realy_hrefs.append(realy_href)
            return realy_hrefs

    def do_save_pics(self,href_pic_list,savepath,key):
        # 循环遍历图片链接
        for url in href_pic_list:
            resp = getHtml().do_get_resp(url)
            if resp.status_code == 200:
                # e = etree.HTML(resp.text)
                # type = resp.url[len(resp.url)-3:]
                title = resp.url[int(resp.url.rfind("wallhaven-")):]
                Save_pic().save(title,resp.content,key,savepath)
            else:
                new_url = resp.url
                new_url = new_url[:int(new_url.rfind("."))+1]+"png"
                resp = getHtml().do_get_resp(new_url)
                # e = etree.HTML(resp.text)
                # width = e.xpath('//img/@width')[0]
                # height = e.xpath('//img/@height')[0]
                # type = resp.url[len(resp.url)-3:]
                title = resp.url[int(resp.url.rfind("wallhaven-")):]
                Save_pic().save(title,resp.content,key,savepath)

class Start_GO:
    def main(self,key,savepath,want_page):
        url = "https://wallhaven.cc/search?q={0}&page=2".format(key)
        html = getHtml().do_getHtml(url)
        msg_list = ParseHtml().do_parse_search(html)
        href_pic_list = ParseHtml().do_get_pic_hrefs(msg_list,want_page,key)
        ParseHtml().do_save_pics(href_pic_list,savepath,key)

    def search(self,key):
        url = "https://wallhaven.cc/search?q={0}&page=2".format(key)
        html = getHtml().do_getHtml(url)
        msg_list = ParseHtml().do_parse_search(html)
        return msg_list

GUI代码:

from tkinter import *
from tkinter.filedialog import askdirectory
from tkinter import messagebox
from paqu import *
from threading import Thread

# 参数设置
root_width = 1000
root_height = 700
# 默认保存文件路径
base_path = r"F:\pictures"

class Application(Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.createWidgets()

    def change_tag_options(self, tag):
        self.pic_frame.pack_forget()
        self.xiaoshuo_frame.pack_forget()
        if tag == 0:
            self.pic_frame.pack(side="top", fill=Y)
        elif tag == 1:
            self.xiaoshuo_frame.pack(side="top", fill=Y)

    def createWidgets(self):
        # 创建三个子框架
        head_options_frame = Frame(self)
        head_options_frame.pack()

        tag_width = 25

        self.picture_but = Radiobutton(head_options_frame, text="图 片 下 载", width=tag_width,
                                       value=0, bd=1, indicatoron=0,command= lambda: self.change_tag_options(0))
        self.picture_but.pack(side="left", fill=Y)

        self.xiaoshuo_but = Radiobutton(head_options_frame, text="小 说 下 载", width=tag_width,
                                        value=1, bd=1, indicatoron=0,command=lambda: self.change_tag_options(1))
        self.xiaoshuo_but.pack(side="left", fill=Y)

        self.pic_frame = Frame(self)
        self.pic_frame.pack(side="top", fill=Y)
        Pic_Frame().createWidgets(self.pic_frame)

        self.xiaoshuo_frame = Frame(self)
        Content_Frame().createWidgets(self.xiaoshuo_frame)

class Pic_Frame(Frame):
    def createWidgets(self, new_frame):
        self.search_lab = Label(new_frame, text="请输入英文关键词:",font=("kaiti",15),width=20)
        self.search_lab.grid(row=0, column=0,pady=10)

        self.v1_key = StringVar()
        self.v1_key.set("sky")
        self.key_word_entry = Entry(new_frame,width=30,font=("kaiti",15),text=self.v1_key)
        self.key_word_entry.grid(row=0, column=1,ipadx=10)

        self.search_but = Button(new_frame,width=15,text="搜 索",font=("kaiti",15),command=lambda : MyThread(self.html_result))
        self.search_but.grid(row=0, column=2)

        self.search_result_text = Text(new_frame,width=100,height=30,state=DISABLED,bg="#C2FF68")
        self.search_result_text.grid(row=1, column=0,columnspan=3)

        self.num_lab = Label(new_frame, text="请输入下载页数:",font=("kaiti",15),width=20)
        self.num_lab.grid(row=2, column=0,pady=10)

        self.v2_page = StringVar()
        self.v2_page.set("2")
        self.want_download_page_num = Entry(new_frame,text=self.v2_page,font=("kaiti",15),width=30)
        self.want_download_page_num.grid(row=2, column=1)

        self.file_save_path__choice_lab = Label(new_frame, text="请选择保存文件路径:",font=("kaiti",15),width=20)
        self.file_save_path__choice_lab.grid(row=3, column=0,pady=10)

        self.file_save_path_lab = Label(new_frame, text=base_path,font=("kaiti",10),width=40)
        self.file_save_path_lab.grid(row=3, column=1)

        self.find_path_but = Button(new_frame,text="浏 览",font=("kaiti",15),width=15,command=self.save_path)
        self.find_path_but.grid(row=3, column=2)

        self.download_but = Button(new_frame,text="下 载",font=("kaiti",15),width=20,command= lambda : MyThread(self.download_txt))
        self.download_but.grid(row=4, column=0,columnspan=3)

    # 更换文件保存路径
    def save_path(self):
        path = askdirectory()
        self.file_save_path_lab["text"] = path

    # 搜索响应
    def html_result(self):
        search_key = self.v1_key.get()
        if search_key.isalpha():
            msg_list = Start_GO().search(search_key)
            self.search_result_text["state"] = NORMAL
            self.search_result_text.insert(INSERT,"搜索到{0}结果\t搜索到{1}页,共{2}张图片\n".format(search_key,msg_list[0],msg_list[1]))
            self.search_result_text["state"] = DISABLED
        else:
            messagebox.showerror(title="输入错误",message="非法输入!")

    # 定义下载函数
    def download_txt(self):
        key = self.v1_key.get()
        print("key:",key)
        savepath = self.file_save_path_lab["text"]
        print("路径:",savepath)
        want_page = self.v2_page.get()
        print("页数:",want_page)
        self.search_result_text["state"] = NORMAL
        self.search_result_text.insert(INSERT,"正在下载{0}中...\n".format(key))
        Start_GO().main(key,savepath,want_page)
        self.search_result_text.insert(INSERT,"{0}下载完成\n".format(key))
        self.search_result_text["state"] = DISABLED
        return messagebox.showinfo(title="Successed!",message="下载成功!")

# 定义多线程  
class MyThread(Thread):
    def __init__(self,func):
        super().__init__()
        self.func = func
        # 守护
        self.setDaemon(True)
        # 启动
        self.start()
    def run(self):
        self.func()

class Content_Frame(Frame):
    def createWidgets(self, new_frame):
        search_lab = Label(new_frame, text="请输入小说名")
        search_lab.grid(row=0, column=0)

if __name__ == "__main__":
    root = Tk()
    root_top = root.winfo_screenwidth() / 2 - root_width/2
    root_left = root.winfo_screenheight() / 2 - root_height / 2
    root.title("多功能使用工具")
    root.geometry("{0}x{1}+{2}+{3}".format(root_width,
                                           root_height, int(root_top), int(root_left)))
    app = Application(root)
    app.mainloop()

我将半成品打包成exe文件,放在度娘网盘,密码:836n。




欢迎正在学习的同学一起交流,共同进步!

免费评分

参与人数 4吾爱币 +3 热心值 +4 收起 理由
helanlijian + 1 + 1 谢谢@Thanks!
ibook + 1 + 1 我很赞同!
kokgmx + 1 我很赞同!
王星星 + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

silentlight 发表于 2020-7-26 09:55
感谢分享,顺便get到了一个非常好的壁纸网站
 楼主| klmatao 发表于 2020-6-16 18:00
阿昆 发表于 2020-6-16 17:05
老哥 你的百度链接错了、
https://pan.baidu.com/s/11e81I_vz2OWpBQeDU8s5lg

修改好了,重新发布了
阿昆 发表于 2020-6-16 17:05
老哥 你的百度链接错了、
https://pan.baidu.com/s/11e81I_vz2OWpBQeDU8s5lg
 楼主| klmatao 发表于 2020-6-16 17:11
阿昆 发表于 2020-6-16 17:05
老哥 你的百度链接错了、
https://pan.baidu.com/s/11e81I_vz2OWpBQeDU8s5lg

好,我修改一下
swhzxzx 发表于 2020-6-23 09:58
非常棒 谢谢你的分享
kiviki 发表于 2020-6-23 14:26
感谢分享,研究下
coderyl 发表于 2020-7-26 09:44
支持,看了之后感觉自己写的代码好垃圾
yek2furw 发表于 2020-12-19 16:41
感谢分享,请问楼主fake_useragent是那个包?
helanlijian 发表于 2021-2-23 08:41
来迟了,求楼主补个链呗
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 18:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表