用python写的嗅事百科阅读器

用python写的嗅事百科阅读器,第1张

概述用python写的嗅事百科阅读器

下面是内存溢出 jb51.cc 通过网络收集整理的代码片段。

内存溢出小编现在分享给大家,也给大家做个参考。

#!/usr/bin/env python3 #-*- Coding=utf-8 -*- import codecs import sys import urllib.request as request import io import re import gzip import lxml.etree as etree import logging import logging.handlers import tkinter as tk import tkinter.ttk as tkttk import tkinter.messageBox as tkmsg import tkinter.filedialog as tkfd import tkinter.scrolledtext as tkst import webbrowser from PIL import Image,ImageTk APP_name = 'QBReader' APP_VER  = 'v0.9' DEFAulT_PIC = 'default.jpg' PIC_W = 640 PIC_H = 480 LOG_DIR = 'log' LOG_LV_CH = logging.DEBUG LOG_LV_FH = logging.DEBUG LOG_file = 'QBReader.log' MAX_LOG_SIZE = 1024 * 1024  #1MB LOG_BACKUP_COUNT = 3 #if not os.path.exists(LOG_DIR): #    os.mkdir(LOG_DIR) logger = logging.getLogger('QBReader') logger.setLevel(LOG_LV_CH) #fh = logging.handlers.RotatingfileHandler(os.path.join(LOG_DIR,LOG_file),#                                          maxBytes=MAX_LOG_SIZE,#                                          backupCount=LOG_BACKUP_COUNT,#                                          enCoding='utf-8') #fh.setLevel(LOG_LV_FH) ch = logging.StreamHandler() ch.setLevel(LOG_LV_CH) formatter = logging.Formatter(                 "%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s") #fh.setFormatter(formatter) ch.setFormatter(formatter) # add the handlers to logger #logger.addHandler(fh) logger.addHandler(ch) DEBUG = logger.deBUG INFO = logger.info WARNING = logger.warning ERROR = logger.error class QiuBai(object):     def __init__(self,page_type=""):         self.host = 'http://www.qiushibaike.com'         self.qiubai_type = "NulL"         self.set_type(page_type)     def set_type(self,page_type=""):         if page_type == "hot":             self.url = "http://www.qiushibaike.com/hot/page/%s"             self.qiubai_type = "hot"         elif page_type == "week":             self.url = "http://www.qiushibaike.com/week/page/%s"             self.qiubai_type = "week"         elif page_type == "Now":             self.url = "http://www.qiushibaike.com/8hr/page/%s"             self.qiubai_type = "Now"         else:             self.url = "http://www.qiushibaike.com/8hr/page/%s"             self.qiubai_type = "Now"         INFO('set qiubai type to {0}'.format(self.qiubai_type))     def get_type_cn(self):         ret = '未知'         if self.qiubai_type == "hot":             ret = '24小时内'         elif self.qiubai_type == "week":             ret = '七天内'         elif self.qiubai_type == "Now":             ret = '热门'         else:             ret = '未知'         return ret     def get_type(self):         return self.qiubai_type     def get_page(self,page=1):         url = self.url % page         header = {"User-Agent": "Mozilla/4.0","Accept-EnCoding": "gzip,deflate"}         req = request.Request(url,headers=header)         HTML = request.urlopen(req)         if HTML.headers.get("content-encoding"):             comp_data = HTML.read()             comp_stream = io.BytesIO(comp_data)             gzipper = gzip.Gzipfile(fileobj=comp_stream)             text = gzipper.read().decode("utf-8")         else:             text=HTML.read().decode("utf-8")         return text     def get_image(self,image_url):         url = image_url         header = {"User-Agent": "Mozilla/4.0",}         req = request.Request(url,headers=header)         image_bytes = request.urlopen(req).read()         return image_bytes     def get_content(self,page):         qiubai_List = []         text = self.get_page(page)         try:             parser = etree.HTMLParser(recover=True)             text_dom = etree.fromstring(text,parser)         except:             ERROR("页面解析错误")         else:             '''div_node = text_dom.find("body").findall("div")             content_node = div_node[2].find("div").find("div").findall("div[@class][@ID]")'''             content_node = text_dom.xpath("//body/div[3]/div/div/div[@class][@ID]")             for qiubai_node in content_node:                 user_name = "匿名"                 qiubai_date = '未知'                 qiubai_text = "NulL"                 qiubai_pic = "NulL"                 qiubai_url = "NulL"                 stauts_funny = "0"                 stauts_not_funny = "0"                 stauts_reply = "0"                 for item in qiubai_node.xpath("child::div"):                     if item.get("class") == "author clearfix":                         #user_name = item.findall("a")[1].text                         user_name = ''.join(item.xpath("child::a[2]//text()"))                     elif item.get("class") == "content":                         qiubai_date = ''.join(item.xpath("attribute::Title"))                         #qiubai_text = item.text                         qiubai_text = ''.join(item.xpath("child::text()"))                         #format content,remove '\n' and whitespace                         qiubai_text = qiubai_text.strip('\n')                         qiubai_text = qiubai_text.strip()                     elif item.get("class") == "thumb":                         #qiubai_pic = item.find("a").find("img").get("src")                         qiubai_pic = ''.join(item.xpath("child::a/img/attribute::src"))                     elif item.get("class") == "stats clearfix":                         qiubai_url = ''.join(item.xpath("child::span[@class='stats-comments']/a/attribute::href"))                         qiubai_url = self.host + qiubai_url                         stauts_funny = ''.join(item.xpath("child::span[@class='stats-Vote']/i[@class='number']//text()"))                         stauts_reply = ''.join(item.xpath("child::span[@class='stats-comments']/a/i[@class='number']//text()"))                 #DEBUG("{0}-{1}".format(user_name,qiubai_text))                 if qiubai_text != "NulL":                     qiubai_List.append({'user_name': user_name,'qiubai_date': qiubai_date,'qiushi_content': qiubai_text,'qiushi_img': qiubai_pic,'qiushi_url': qiubai_url,'stauts_funny':stauts_funny,'stauts_reply':stauts_reply})         return qiubai_List class Set_QiuBai_Type(object):           # 定义对话框类     def __init__(self,root,init_type='Now'):    # 对话框初始化         self.qiubai_type = ''         self.top = tk.toplevel(root)     # 生成toplevel组件         self.top.withdraw()  #隐藏         self.top.Title('糗事类别选择')         self.top.resizable(False,False) #禁止改变大小                  mainframe = tkttk.Frame(self.top,padding="12 12 12 12")         mainframe.grID(column=0,row=0,sticky=(tk.N,tk.W,tk.E,tk.S))         label = tk.Label(mainframe,text='选择糗事类别') # 生成标签组件         label.grID(column=1,row=1)         modes = [             ("热门","Now"),("24小时内","hot"),("7天内","week"),]         self.v = tk.StringVar()         self.v.set(init_type)         co = 0         for text,mode in modes:             b = tk.Radiobutton(mainframe,text = text,variable=self.v,value=mode)    # 生成单选框组件             b.grID(column=co,row=2)             co += 1         button = tk.button(mainframe,text='Ok',# 生成按钮                         command=self.Ok)    # 设置按钮事件处理函数         #self.top.bind('<Enter>',self.Ok)         button.grID(column=1,row=3)         self.top.update_IDletasks()         self.top.deiconify()  #计算窗口大小         self.top.withdraw()  #隐藏窗口         app_geo = get_center_app_screen(root,self.top.winfo_reqwIDth(),self.top.winfo_reqheight())         self.top.geometry(app_geo)         self.top.deiconify()         DEBUG('d出窗口大小: {0}*{1}'.format(self.top.winfo_wIDth(),self.top.winfo_height()))          def Ok(self):                        # 定义按钮事件处理函数         self.qiubai_type = self.v.get()    # 获取文本框中内容,保存为input         self.top.destroy()               # 销毁对话框              def get(self):    # 返回在文本框输入的内容         return self.qiubai_type      class QiuBai_Gui(object):     def __init__(self,roots,obj_qb):         self.roots = roots         self.obj_qb = obj_qb         self.qb_page = 1         self.is_main_ui = True                  self.qb_content = self.obj_qb.get_content(self.qb_page)         self.content_len = len(self.qb_content)         self.content_index = 0;         #config menu         self.__confmenu__()         #cofig main gui         self.__confmaingui__()     def __confmenu__(self):         menu_roots = tk.Menu(self.roots)         menu_v = tk.Menu(menu_roots,tearoff=0)         menu_v.add_command(label='下一条',command=self.mv_next)         menu_v.add_command(label='上一条',command=self.mv_forward)         menu_v.add_command(label='刷新',command=self.mv_refresh)         menu_v.add_command(label='打开糗事页面',command=self.mv_open_source)         menu_v.add_separator()         menu_v.add_command(label='退出',command=self.mv_exit)         menu_st = tk.Menu(menu_roots,tearoff=0)         menu_st.add_command(label='类别',command=self.ms_type)         #menu_st.add_command(label='Proxy',command=self.ms_proxy)         menu_hp = tk.Menu(menu_roots,tearoff=0)         menu_hp.add_command(label='关于',command=self.ma_about)         #布局         menu_roots.add_cascade(label="查看",menu=menu_v)         menu_roots.add_cascade(label="设置",menu=menu_st)         menu_roots.add_cascade(label="帮助",menu=menu_hp)         self.roots.config(menu=menu_roots)     def __confmaingui__(self):         #main ui         main_frame = tkttk.Frame(self.roots,padding="12 12 12 12")         main_frame.grID(column=0,tk.S))         main_frame.columnconfigure(0,weight=1)         main_frame.rowconfigure(0,weight=1)         self.__main_ui__(main_frame)         #status frame         status_frame = tkttk.Frame(self.roots,padding="12 12 12 12")         status_frame.grID(column=0,row=1,tk.S))         #State         self.disState = tk.StringVar()         self.__update_read_state__()                  lbState = tkttk.Label(status_frame,textvariable=self.disState,borderwIDth=1,relIEf=tk.SUNKEN,anchor=tk.W,wIDth=74)         lbState.grID(column=0,row=5,columnspan=2,tk.S))         #DEBUG("{0}-{1}".format(type(main_frame),main_frame))          def __main_ui__(self,mainframe):         group_qiubai = tk.LabelFrame(mainframe,text="糗事",bg='#808000',padx=10,pady=5)         group_qiubai.grID(column=0,tk.S))         #text         #self.qiubai_txt = Text(group_qiubai,height=4,wIDth=70)         self.qiubai_txt = tkst.ScrolledText(group_qiubai,wIDth=69)         self.qiubai_txt.grID(column=1,columnspan=2)           #pic         self.qiubai_label = tk.Label(group_qiubai,height=PIC_H,wIDth=PIC_W)         self.qiubai_label.grID(column=1,columnspan=2)         self.__show_qiushi__(self.qb_content[self.content_index])         DEBUG(self.qb_content[self.content_index])         for child in mainframe.winfo_children():             child.grID_configure(padx=1,pady=5)         #bind key         self.qiubai_label.bind("<button>",self.__event_handler__)         group_qiubai.bind_all("<Key>",self.__event_handler__)         #qiubai text not input by key         self.qiubai_txt.bind("<KeyPress>",lambda e : "break")         #self.roots.bind("<Destroy>",lambda a:print('abc'))         #DEBUG("{0}-{1}".format(type(group_qiubai),group_qiubai))               def __updateState__(self,ststr):         self.disState.set(ststr)         self.roots.update()     def __update_read_state__(self):         self.__updateState__(             '页码({0}): {1} - ({2}/{3})  |  {4} 好笑 - {5} 回复  |  - {6},{7}'.format(                 self.obj_qb.get_type_cn(),self.qb_page,self.content_index+1,self.content_len,self.qb_content[self.content_index]['stauts_funny'],self.qb_content[self.content_index]['stauts_reply'],self.qb_content[self.content_index]['user_name'],self.qb_content[self.content_index]['qiubai_date']))     def __show_qiushi__(self,qiushi):         self.qiubai_txt.delete(0.0,tk.END)         self.qiubai_txt.insert(0.0,qiushi['qiushi_content'])         #pic         if 'NulL' != qiushi['qiushi_img']:             pil_bytes = self.obj_qb.get_image(qiushi['qiushi_img'])             pil_image = Image.open(io.BytesIO(pil_bytes))             pil_image_resize = self.__resize_pic__(pil_image)             qiubai_pic2= ImageTk.PhotoImage(pil_image_resize)             self.qiubai_label.configure(image = qiubai_pic2)             self.qiubai_label.image = qiubai_pic2             #self.roots.update()         else:             pil_image = Image.open(DEFAulT_PIC)             pil_image_resize = self.__resize_pic__(pil_image)             qiubai_pic2= ImageTk.PhotoImage(pil_image_resize)             self.qiubai_label.configure(image = qiubai_pic2)             self.qiubai_label.image = qiubai_pic2     def __resize_pic__(self,pil_image,w_Box=PIC_W,h_Box=PIC_H):         '''         resize a pil_image object so it will fit into         a Box of size w_Box times h_Box,but retain aspect ratio         '''         w,h = pil_image.size         f1 = 1.0*w_Box/w  # 1.0 forces float division in Python2         f2 = 1.0*h_Box/h         factor = min([f1,f2])         #print(f1,f2,factor)  # test         # use best down-sizing filter         wIDth = int(w*factor)         height = int(h*factor)         DEBUG("change image from {0}/{1} to {2}/{3}".format(w,h,wIDth,height))         return pil_image.resize((wIDth,height),Image.ANTIAliAS)     def __set_qiubai_type__(self,qiubai_type):         self.qb_page = 1         self.obj_qb.set_type(qiubai_type)         self.qb_content = self.obj_qb.get_content(self.qb_page)         self.content_len = len(self.qb_content)         self.content_index = 0;         self.__show_qiushi__(self.qb_content[self.content_index])         self.__update_read_state__()         DEBUG(self.qb_content[self.content_index])      def __event_handler__(self,event):         #DEBUG(event.Widget)         #DEBUG("{0}-{1}".format(type(event.Widget),event.Widget))         if self.is_main_ui:             if (event.num == 1) or (event.keysym in ('Right','Down')):                 self.mv_next()             if (event.num == 3) or (event.keysym in ('left','Up')):                 self.mv_forward()     def mv_next(self):         self.content_index += 1         #next page         if self.content_index >= self.content_len:             self.qb_page += 1             self.qb_content = self.obj_qb.get_content(self.qb_page)             self.content_len = len(self.qb_content)             self.content_index = 0;             INFO('go to next page {0}'.format(self.qb_page))         self.__show_qiushi__(self.qb_content[self.content_index])         self.__update_read_state__()         DEBUG(self.qb_content[self.content_index])             def mv_forward(self):         #DEBUG(self.content_index)         #forward page         if self.content_index <= 0:             if self.qb_page > 1:                 self.qb_page -= 1                 self.qb_content = self.obj_qb.get_content(self.qb_page)                 self.content_len = len(self.qb_content)                 self.content_index = self.content_len - 1 ;                 INFO('go to forward page {0}'.format(self.qb_page))             else:                 WARNING('have go to top page.')                 return         else:             self.content_index -= 1         self.__show_qiushi__(self.qb_content[self.content_index])         self.__update_read_state__()         DEBUG(self.qb_content[self.content_index])                 def mv_refresh(self):         self.content_index = 0         self.qb_page = 1         self.qb_content = self.obj_qb.get_content(self.qb_page)         self.content_len = len(self.qb_content)         INFO('refresh to page {0}'.format(self.qb_page))         self.__show_qiushi__(self.qb_content[self.content_index])         self.__update_read_state__()         DEBUG(self.qb_content[self.content_index])           def mv_open_source(self):         url = self.qb_content[self.content_index]['qiushi_url']         r = tkmsg.askquestion("查看源","网址:{0}\n\nURL已经保存到剪切板,是否在浏览器中打开?".format(url),parent=self.roots)         if 'yes' == r:             DEBUG('open url:{0}'.format(url))             webbrowser.open_new_tab(url)         else:             DEBUG('cancel to open url:{0}'.format(url))             self.roots.clipboard_append(url)              def mv_exit(self):         self.roots.quit()     def ms_type(self):         self.is_main_ui = False         self.roots.iconify() # 隐藏主窗口         t = Set_QiuBai_Type(self.roots,self.obj_qb.get_type()) # 生成对话框         self.roots.wait_window(t.top)         self.roots.deiconify() # 重新显示主窗口         if t.get():             self.__set_qiubai_type__(t.get())             INFO('change qiubai type to {0}'.format(t.get()))         self.is_main_ui = True     def ma_about(self):         tkmsg.showinfo("{0} {1}".format(APP_name,APP_VER),"作者: 逸山\n电子邮箱: [email protected]",parent=self.roots) def get_center_window_geometry(root,height):     screenwIDth = root.winfo_screenwIDth()     screenheight = root.winfo_screenheight()     size = '%dx%d+%d+%d' % (wIDth,height,(screenwIDth - wIDth)/2,(screenheight - height)/2)     INFO('screen geometry: {0}'.format(size))     return size def get_center_app_screen(root,height):     window_geo = root.geometry()     w,off_w,off_h = parse_geometry(window_geo)     size = '%dx%d+%d+%d' % (wIDth,(w - wIDth)/2 + off_w,(h - height)/2 + off_h)     INFO('app_pop_screen geometry: {0}'.format(size))     return size def parse_geometry(geometry):     m = re.match("(\d+)x(\d+)([-+]\d+)([-+]\d+)",geometry)     if not m:         raise ValueError("Failed to parse geometry string")     return map(int,m.groups())      if __name__ == "__main__":     qiubai_obj = QiuBai()          top = tk.Tk()     top.withdraw()  #隐藏窗口     top.Title(APP_name)     top.iconbitmap('home.ico')     top.resizable(False,False)     #top.maxsize(700,700)     #top.minsize(600,600)     QiuBai_Gui(top,qiubai_obj)     top.update_IDletasks()     top.deiconify() #重新计算窗口大小     top.withdraw()  #再次隐藏窗口     win_geo = get_center_window_geometry(top,top.winfo_wIDth(),top.winfo_height())     top.geometry(win_geo)     top.deiconify()     DEBUG('屏幕大小: {0}*{1}'.format(top.winfo_screenwIDth(),top.winfo_screenheight()))     DEBUG('需求窗口大小: {0}*{1}'.format(top.winfo_reqwIDth(),top.winfo_reqheight()))     DEBUG('窗口大小: {0}*{1}'.format(top.winfo_wIDth(),top.winfo_height()))     top.mainloop() 

以上是内存溢出(jb51.cc)为你收集整理的全部代码内容,希望文章能够帮你解决所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

总结

以上是内存溢出为你收集整理的用python写的嗅事百科阅读器全部内容,希望文章能够帮你解决用python写的嗅事百科阅读器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1198720.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-03
下一篇2022-06-03

发表评论

登录后才能评论

评论列表(0条)

    保存