|
0鱼币
本帖最后由 什么鬼… 于 2017-8-5 23:59 编辑
最近看了鱼哥的tkinter视频,然后心血来潮想练练手,于是准备写一个有GUI的b站的爬虫,但是今天碰到个玄学问题....
首先:遇到问题的地方
这里我的get_video函数是一个二级按钮的回调函数.
我的不完整的GUI是这样的
程序目标:通过用户选板块,然后获取分区,选择分区之后,取分区里面的视频的封面和标题,放在预览区供选择
然后通过checkbutton获取所需要的视频,最后再下载
中间遇到过一些问题,比如什么PhotoImage必须是gif不能jpg啊
还有图片是不是要本地先下载啊
但是楼主google了一波发现有直接通过url搞出图片的方法
然而
获取到了图片之后在video区域并不显示. 就像下图
我在前面加了一个print(pic_url)查看图片发现没有问题.(print的结果如图1)
后来我又把代码写到另外一个文件里面,发现图片又可以显示,如图
这就很迷了...楼主表示找不到原因,目前已经弃疗,希望大佬们帮忙看看分析一下....
代码贴在下面咯(不要吐槽代码风格....)问题在图1里面有,代码里面用*分割开了
- from tkinter import *
- from PIL import Image,ImageTk
- import io
- import urllib.request
- import json
- import requests
- import re
- class Main_Plat:
- def __init__(self):
- self.bilibili=B_Station() # 获取b站资源
- self.root=Tk()
- self.root.geometry("1000x480+200+20")
- self.root.resizable(width=True,height=False)
- self.root.title("bilibili小爬虫!")
- self.bankuaivar=StringVar()
- self.smallbankuaivar = StringVar()
- self.videovar = StringVar()
- self.bankuai=Frame(master=self.root)
- self.smallbankuai = Frame(master=self.root)
- self.videobankuai=Frame(master=self.root)
- #self.scrolledtext=ScrolledText(self.videobankuai)
- #self.scrolledtext.grid()
- self.small_bankuai_list=[]
- self.video_list=[] # 装需要下载的视频
- self.check_var_list=[]
- part_list = ["动画",
- "番剧",
- "国创",
- "音乐",
- "舞蹈",
- "游戏",
- "科技",
- "生活",
- "鬼畜",
- "时尚",
- "广告",
- "娱乐",
- "电影",
- "电视剧"
- ]
- label = Label(self.smallbankuai, text='分区', fg="red", font=("微软雅黑", 12), width=16)
- label.pack(fill=X)
- label=Label(self.bankuai,text='板块',fg="red",font=("微软雅黑",12),width=8)
- label.pack(fill=X)
- label=Label(self.videobankuai,text="video预览区",fg="red",font=('微软雅黑',12))
- label.pack()
- for part in part_list:
- btn=Radiobutton(self.bankuai,text=part,variable=self.bankuaivar,value=part,
- indicatoron=False,command=self.get_next,font=("微软雅黑",12),width=8)
- btn.pack(fill=X)
- self.bankuai.pack(side=LEFT,anchor=NW)
- self.smallbankuai.pack(side=LEFT,anchor=N)
- self.videobankuai.pack(anchor=N)
- self.root.mainloop()
- def get_next(self):
- if self.small_bankuai_list:
- for btn in self.small_bankuai_list:
- btn.destroy()
- self.small_bankuai_list=[]
- temp = self.bilibili.get_small_part(self.bankuaivar.get()) # 得到一个元组构成的列表(tid,link,name)
- for each in temp:
- btn=Radiobutton(self.smallbankuai,text=each[2],variable=self.smallbankuaivar,
- value=each[2],indicatoron=False,width=16,font=("微软雅黑",12),command=self.get_video)
- btn.pack(fill=X)
- self.small_bankuai_list.append(btn)
- def get_video(self):
- smallbankuai = self.bilibili.get_small_part(self.bankuaivar.get())
- video_list = self.bilibili.get_one(smallbankuai,1) # 获取视频资料的json,后续对页码进行修改--通过变量获取
- item=video_list[0] #这里本来是一个for循环,这里为了测试把for item in video_list:改成item=video_list[0]
- var = StringVar()
- #***********************************************************************************************************************************
- pic_url = item['pic']
- print(pic_url)
- image_bytes = urllib.request.urlopen(pic_url).read()
- data_stream = io.BytesIO(image_bytes)
- pil_image = Image.open(data_stream).resize((150,150),Image.ANTIALIAS)
- tk_image = ImageTk.PhotoImage(pil_image)
- label=Label(self.videobankuai,image=tk_image) #测试使用Label
- label.pack()
- #************************************************************************************************************************************
- choice = Checkbutton(self.videobankuai,text=item['title'],image=tk_image,variable=var,
- onvalue=item["aid"],offvalue='0',command=self.callback)
- choice.pack() #实际使用的choice
- def callback1(self):
- for each in self.check_var_list:
- temp = each.get()
- if temp =='0':
- self.video_list.remove(temp)
- if temp !='0':
- self.video_list.append(temp)
- class B_Station:
- def __init__(self):
- self.u = requests.session()
- self.headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
- r = self.u.get("https://www.bilibili.com/", headers=self.headers)
- r.encoding = r.apparent_encoding
- self.part2link={}
- self.link2part={}
- while '<div id="home-app"></div>' not in r.text:
- r = self.u.get("https://www.bilibili.com/", headers=self.headers)
- r.encoding = r.apparent_encoding
- main_page = r.text
- part_list = re.findall(r'<a href="//([^"]+)" class="nav-link"><div class="num-wrap"><span class="num">--</span></div><div class="nav-name">([^<]+)</div></a>',main_page)
- for l, p in part_list:
- if p!="影视":
- l = 'https://'+l
- self.part2link.setdefault(p,l)
- self.link2part.setdefault(l,p)
- self.part2link.setdefault("电影",'https://bangumi.bilibili.com/movie/')
- self.part2link.setdefault('电视剧','https://bangumi.bilibili.com/tv/') # 电影区格式不同啊!!
- self.link2part.setdefault('https://bangumi.bilibili.com/movie/','电影')
- self.link2part.setdefault('https://bangumi.bilibili.com/tv/','电视剧')
- def get_small_part(self,part): # 返回一个元组构成的列表(tid,link,name)
- part_link = self.part2link[part]
- r = self.u.get(part_link,headers=self.headers)
- r.encoding = r.apparent_encoding
- small_part_list = re.findall(r'<li desc="" tid=(\d*) ><a href="([^"]+)">([^<]+)</a></li>',r.text)
- if not small_part_list:
- small_part_list = re.findall(r'<li desc="" tid="(\d*)" ?><a href="([^"]+)">([^<]+)</a>', r.text)
- if part == "广告":
- small_part_list = [('166','/video/ad-ad-1.html','全部')] # 对广告区的空分区的处理
- return small_part_list
- def get_one(self,small_part_list,page): # 传入上面的列表和页数,返回多个字典
- url = "https://api.bilibili.com/archive_rank/getarchiverankbypartion?callback=type=jsonp&tid={tid}&pn={page}".format(tid=str(small_part_list[0][0]),page=str(page))
- r = self.u.get(url,headers=self.headers)
- r.encoding=r.apparent_encoding
- temp = json.loads(r.text)
- temp = temp["data"]['archives']
- return temp
- if __name__ == "__main__":
- plat=Main_Plat()
复制代码
tk_image 不能是 临时变量,否则会被当作垃圾回收,图片就不显示了
|
|