python项目(豆瓣影戏)

打印 上一主题 下一主题

主题 839|帖子 839|积分 2517

目录

1、项目效果
2、项目源码
3、技术实现
4、总结


媒介

           我的这个项目是做的一个豆瓣影戏爬取,爬取了豆瓣影戏的TOP排行榜的数据 包罗影戏的名称 演员 评分 评价人数等等 运用了TK布局助手 布了4个界面 有登录 注册 首页 详情
          注意:项目并没有连接数据库 
  一、项目效果

                                                    登录 


                                                      注册


 首页


详情




二、项目源码

   登录 
  1. from tkinter import *
  2. from tkinter.ttk import *
  3. from tkinter import Button
  4. import subprocess
  5. from tkinter import messagebox
  6. class WinGUI(Tk):
  7.     def __init__(self):
  8.         super().__init__()
  9.         self.__win()
  10.         self.name_var = "root"  # 固定的姓名
  11.         self.password_var = "123"  # 固定的密码
  12.         self.tk_label_lwudgfpe = self.__tk_label_lwudgfpe(self)
  13.         self.tk_label_lwudgqcp = self.__tk_label_lwudgqcp(self)
  14.         self.tk_input_lwudhq1s = self.__tk_input_lwudhq1s(self)
  15.         self.tk_input_lwudi5tc = self.__tk_input_lwudi5tc(self)
  16.         self.tk_button_lwudit80 = self.__tk_button_lwudit80(self)
  17.         self.tk_button_zc = self.__tk_button_zc(self)
  18.         # 设置主窗口的背景颜色
  19.         # self.config(bg='#B0E2FF')
  20.     def __win(self):
  21.         self.title("登录")
  22.         # 设置窗口大小、居中
  23.         width = 400
  24.         height = 300
  25.         screenwidth = self.winfo_screenwidth()
  26.         screenheight = self.winfo_screenheight()
  27.         geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
  28.         self.geometry(geometry)
  29.         self.resizable(width=False, height=False)
  30.     def scrollbar_autohide(self, vbar, hbar, widget):
  31.         """自动隐藏滚动条"""
  32.         def show():
  33.             if vbar: vbar.lift(widget)
  34.             if hbar: hbar.lift(widget)
  35.         def hide():
  36.             if vbar: vbar.lower(widget)
  37.             if hbar: hbar.lower(widget)
  38.         hide()
  39.         widget.bind("<Enter>", lambda e: show())
  40.         if vbar: vbar.bind("<Enter>", lambda e: show())
  41.         if vbar: vbar.bind("<Leave>", lambda e: hide())
  42.         if hbar: hbar.bind("<Enter>", lambda e: show())
  43.         if hbar: hbar.bind("<Leave>", lambda e: hide())
  44.         widget.bind("<Leave>", lambda e: hide())
  45.     def v_scrollbar(self, vbar, widget, x, y, w, h, pw, ph):
  46.         widget.configure(yscrollcommand=vbar.set)
  47.         vbar.config(command=widget.yview)
  48.         vbar.place(relx=(w + x) / pw, rely=y / ph, relheight=h / ph, anchor='ne')
  49.     def h_scrollbar(self, hbar, widget, x, y, w, h, pw, ph):
  50.         widget.configure(xscrollcommand=hbar.set)
  51.         hbar.config(command=widget.xview)
  52.         hbar.place(relx=x / pw, rely=(y + h) / ph, relwidth=w / pw, anchor='sw')
  53.     def create_bar(self, master, widget, is_vbar, is_hbar, x, y, w, h, pw, ph):
  54.         vbar, hbar = None, None
  55.         if is_vbar:
  56.             vbar = Scrollbar(master)
  57.             self.v_scrollbar(vbar, widget, x, y, w, h, pw, ph)
  58.         if is_hbar:
  59.             hbar = Scrollbar(master, orient="horizontal")
  60.             self.h_scrollbar(hbar, widget, x, y, w, h, pw, ph)
  61.         self.scrollbar_autohide(vbar, hbar, widget)
  62.     def __tk_label_lwudgfpe(self, parent):
  63.         label = Label(parent, text="用户名", anchor="center", )
  64.         label.place(x=20, y=60, width=80, height=38)
  65.         return label
  66.     def __tk_label_lwudgqcp(self, parent):
  67.         label = Label(parent, text="密码", anchor="center", )
  68.         label.place(x=20, y=140, width=78, height=38)
  69.         return label
  70.     def __tk_input_lwudhq1s(self, parent):
  71.         ipt = Entry(parent, )
  72.         ipt.place(x=117, y=60, width=263, height=39)
  73.         self.ipt1 = ipt
  74.         return ipt
  75.     def __tk_input_lwudi5tc(self, parent):
  76.         ipt = Entry(parent, )
  77.         ipt.place(x=117, y=140, width=258, height=39)
  78.         self.ipt2 = ipt
  79.         return ipt
  80.     def __tk_button_lwudit80(self, parent):
  81.         btn = Button(parent, text="登录", takefocus=False, )
  82.         btn.place(x=120, y=220, width=79, height=41)
  83.         # 添加事件绑定
  84.         btn.bind("<Button-1>", self.on_login_click)  # <Button-1> 是鼠标左键点击的事件
  85.         return btn
  86.     def __tk_button_zc(self,parent):
  87.         btn = Button(parent,text="注册",takefocus=False,)
  88.         btn.place(x=250, y=220, width=79, height=41)
  89.         btn.bind("<Button-1>", self.on_zc_click)  # <Button-1> 是鼠标左键点击的事件
  90.         return btn
  91.     # 添加一个新的方法作为回调函数
  92.     # 登录
  93.     def on_login_click(self, event):
  94.         # 输入框里值
  95.         entered_name = self.ipt2.get()
  96.         entered_password =self.ipt1.get()
  97.         if self.password_var== entered_name and self.name_var== entered_password:
  98.             self.run_index_script()
  99.         else:
  100.             # 显示错误提示
  101.             messagebox.showerror("登录失败", "账号或密码不正确,请重新输入。")
  102.     # 添加一个新的方法作为回调函数
  103.     # 注册
  104.     def on_zc_click(self, event):
  105.         try:
  106.             # 使用subprocess模块启动新的Python脚本
  107.             subprocess.Popen(['python', 'register.py'])
  108.             # 关闭当前窗口
  109.             # self.destroy()
  110.         except Exception as e:
  111.             print(f"Error occurred while running index.py: {e}")
  112.     def run_index_script(self):
  113.         try:
  114.             # 使用subprocess模块启动新的Python脚本
  115.             subprocess.Popen(['python', 'index.py'])
  116.             # 关闭当前窗口
  117.             # self.destroy()
  118.         except Exception as e:
  119.             print(f"Error occurred while running index.py: {e}")
  120.     def __event_bind(self):
  121.         pass
  122.     def __style_config(self):
  123.         pass
  124. if __name__ == "__main__":
  125.     win = WinGUI()
  126.     win.mainloop()
复制代码
  注册(与登录页面相似,只是判定不相同)
  1.   # 添加一个新的方法作为回调函数
  2.     def on_register_click(self, event):
  3.         # 输入框里的值
  4.         # 注册新用户
  5.         new_username = self.ipt2.get().strip()
  6.         new_password = self.ipt1.get().strip()
  7.         if new_username and new_password:
  8.             messagebox.showinfo("注册", "注册成功!")
  9.         else:
  10.             messagebox.showwarning("注册", "用户名或密码不能为空!")
复制代码
   首页(布局是运用了TK助手 大家可自行设置 我这里只展示了部分功能性代码)
  1. def thread_it(func, *args):
  2.     """
  3.     将函数打包进线程(重要)
  4.     :param func:
  5.     :param args:
  6.     :return:
  7.     """
  8.     # 创建
  9.     t = Thread(target=func, args=args)
  10.     # 守护
  11.     # t.setDaemon(True)
  12.     # 启动
  13.     t.start()
  14. class movie_ui():
  15.     # def ll(self):
  16.     def __init__(self):
  17.         self.jsonData = []
  18.     def clear_treeview(self, tree):
  19.         """
  20.         清空表格
  21.         :param tree:
  22.         :return:
  23.         """
  24.         rows = tree.get_children()
  25.         for r in rows:
  26.             tree.delete(r)
  27.     def add_treeview(self, rows, tree):
  28.         """
  29.         新增表格数据
  30.         :param rows:
  31.         :param tree:
  32.         :return:
  33.         """
  34.         for r in rows:
  35.             tree.insert('', END, values=(r['title'], r['rank'], r['score'], r['vote_count']))
  36.     def select_treeview(self, event):
  37.         """
  38.         treeview行双击选中事件
  39.         :return:
  40.         """
  41.         # 获取选中的treeview数据行
  42.         item = self.movie_tv.selection()
  43.         values = self.movie_tv.item(item, "values")
  44.         print(values[0])
  45.         try:
  46.             # 跳转详情页面
  47.             d = WinGUI()
  48.             with open('movies.json', 'r', encoding='utf-8') as fp:
  49.                 # 获取json数据
  50.                 movies = json.load(fp)
  51.             for movie in movies:
  52.                 if movie['title'].__contains__(values[0]):
  53.                     # 将值绑定到详情信息文本框中
  54.                     d.mc.insert("1.0", movie["title"])
  55.                     d.pj.insert("1.0", movie["score"])
  56.                     d.rq.insert("1.0", movie["release_date"])
  57.                     d.lx.insert("1.0", movie["types"])
  58.                     d.yy.insert("1.0", movie["actors"])
  59.         except Exception as e:
  60.             print(f"Error occurred while running index.py: {e}")
  61.     def do_search_top(self):
  62.         """
  63.         排行榜查询按钮事件
  64.         :return:
  65.         """
  66.         # 清空表格
  67.         self.clear_treeview(self.movie_tv)
  68.         # 设置按钮为灰色
  69.         self.btn_top['state'] = DISABLED
  70.         # 下拉框的数据
  71.         jsonMovieData = loads(movieData)
  72.         # 循环获取选择下拉框中选中的值
  73.         movie_type = None
  74.         for subMovieData in jsonMovieData:
  75.             if subMovieData['title'] == self.movie_combo.get():
  76.                 movie_type = subMovieData['type']
  77.                 break
  78.         # 调用查询接口获取数据
  79.         res = get_movie_top(movie_type)
  80.         # 判断是否成功
  81.         if res['code'] == 200:
  82.             self.jsonData = res['movies']
  83.             self.add_treeview(res['movies'], self.movie_tv)
  84.         else:
  85.             messagebox.showinfo('提示', res['msg'][:1000])
  86.         # 按钮设置为正常状态
  87.         self.btn_top['state'] = NORMAL
  88.     def do_search_kw(self):
  89.         """
  90.         关键字查询按钮事件
  91.         :return:
  92.         """
  93.         # 清空表格
  94.         self.clear_treeview(self.movie_tv)
  95.         # 设置按钮为灰色
  96.         self.btn_top['state'] = DISABLED
  97.         self.btn_keyword['state'] = DISABLED
  98.         # 调用查询接口获取数据
  99.         res = get_movie_kw(self.movie_keyword_entry.get())
  100.         # 判断是否成功
  101.         if res['code'] == 200 and len(res['movies']) > 0:
  102.             self.jsonData = res['movies']
  103.             self.add_treeview(res['movies'], self.movie_tv)
  104.         else:
  105.             messagebox.showwarning('提示', '请输入关键字!')
  106.         # 按钮设置为正常状态
  107.         # 从排行榜搜索
  108.         self.btn_top['state'] = NORMAL
  109.         # 从关键字搜索
  110.         self.btn_keyword['state'] = NORMAL
复制代码
   详情
  1. from tkinter import *
  2. from tkinter.ttk import *
  3. class WinGUI(Tk):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.__win()
  7.         self.tk_label_frame_lwym93kr = self.__tk_label_frame_lwym93kr(self)
  8.         self.tk_label_lwym9yej = self.__tk_label_lwym9yej( self.tk_label_frame_lwym93kr)
  9.         self.tk_label_lwymcscf = self.__tk_label_lwymcscf( self.tk_label_frame_lwym93kr)
  10.         self.tk_label_lwymdu0i = self.__tk_label_lwymdu0i( self.tk_label_frame_lwym93kr)
  11.         self.tk_label_lwymfoy1 = self.__tk_label_lwymfoy1( self.tk_label_frame_lwym93kr)
  12.         self.tk_label_lwymgb8y = self.__tk_label_lwymgb8y( self.tk_label_frame_lwym93kr)
  13.         self.tk_text_lwymink1 = self.__tk_text_lwymink1( self.tk_label_frame_lwym93kr)
  14.         self.tk_text_lwynp020 = self.__tk_text_lwynp020( self.tk_label_frame_lwym93kr)
  15.         self.tk_text_lwynpnhj = self.__tk_text_lwynpnhj( self.tk_label_frame_lwym93kr)
  16.         self.tk_text_lwynq5ny = self.__tk_text_lwynq5ny( self.tk_label_frame_lwym93kr)
  17.         self.tk_text_lwynqjmm = self.__tk_text_lwynqjmm( self.tk_label_frame_lwym93kr)
  18.         # 设置主窗口的背景颜色
  19.         # self.config(bg='#B0E2FF')
  20.     def __win(self):
  21.         self.title("豆瓣电影TOP250")
  22.         # 设置窗口大小、居中
  23.         width = 730
  24.         height = 370
  25.         screenwidth = self.winfo_screenwidth()
  26.         screenheight = self.winfo_screenheight()
  27.         geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
  28.         self.geometry(geometry)
  29.         self.resizable(width=False, height=False)
  30.     def scrollbar_autohide(self,vbar, hbar, widget):
  31.         """自动隐藏滚动条"""
  32.         def show():
  33.             if vbar: vbar.lift(widget)
  34.             if hbar: hbar.lift(widget)
  35.         def hide():
  36.             if vbar: vbar.lower(widget)
  37.             if hbar: hbar.lower(widget)
  38.         hide()
  39.         widget.bind("<Enter>", lambda e: show())
  40.         if vbar: vbar.bind("<Enter>", lambda e: show())
  41.         if vbar: vbar.bind("<Leave>", lambda e: hide())
  42.         if hbar: hbar.bind("<Enter>", lambda e: show())
  43.         if hbar: hbar.bind("<Leave>", lambda e: hide())
  44.         widget.bind("<Leave>", lambda e: hide())
  45.     def v_scrollbar(self,vbar, widget, x, y, w, h, pw, ph):
  46.         widget.configure(yscrollcommand=vbar.set)
  47.         vbar.config(command=widget.yview)
  48.         vbar.place(relx=(w + x) / pw, rely=y / ph, relheight=h / ph, anchor='ne')
  49.     def h_scrollbar(self,hbar, widget, x, y, w, h, pw, ph):
  50.         widget.configure(xscrollcommand=hbar.set)
  51.         hbar.config(command=widget.xview)
  52.         hbar.place(relx=x / pw, rely=(y + h) / ph, relwidth=w / pw, anchor='sw')
  53.     def create_bar(self,master, widget,is_vbar,is_hbar, x, y, w, h, pw, ph):
  54.         vbar, hbar = None, None
  55.         if is_vbar:
  56.             vbar = Scrollbar(master)
  57.             self.v_scrollbar(vbar, widget, x, y, w, h, pw, ph)
  58.         if is_hbar:
  59.             hbar = Scrollbar(master, orient="horizontal")
  60.             self.h_scrollbar(hbar, widget, x, y, w, h, pw, ph)
  61.         self.scrollbar_autohide(vbar, hbar, widget)
  62.     def __tk_label_frame_lwym93kr(self,parent):
  63.         frame = LabelFrame(parent,text="电影详情",)
  64.         frame.place(x=18, y=11, width=698, height=346)
  65.         return frame
  66.     def __tk_label_lwym9yej(self,parent):
  67.         label = Label(parent,text="影片名称",anchor="center", )
  68.         label.place(x=58, y=11, width=120, height=38)
  69.         return label
  70.     def __tk_label_lwymcscf(self,parent):
  71.         label = Label(parent,text="电影评价",anchor="center", )
  72.         label.place(x=59, y=71, width=119, height=37)
  73.         return label
  74.     def __tk_label_lwymdu0i(self,parent):
  75.         label = Label(parent,text="电影日期",anchor="center", )
  76.         label.place(x=60, y=131, width=119, height=39)
  77.         return label
  78.     def __tk_label_lwymfoy1(self,parent):
  79.         label = Label(parent,text="电影类型",anchor="center", )
  80.         label.place(x=60, y=191, width=119, height=39)
  81.         return label
  82.     def __tk_label_lwymgb8y(self,parent):
  83.         label = Label(parent,text="电影演员",anchor="center", )
  84.         label.place(x=60, y=251, width=119, height=39)
  85.         return label
  86.     # 电影演员
  87.     def __tk_text_lwymink1(self,parent):
  88.         self.yy = Text(parent)
  89.         self.yy.place(x=218, y=250, width=444, height=60)
  90.         return self.yy
  91.     # 电影名称
  92.     def __tk_text_lwynp020(self,parent):
  93.         self.mc = Text(parent)
  94.         self.mc.place(x=279, y=10, width=299, height=41)
  95.         return self.mc
  96.     # 电影评价
  97.     def __tk_text_lwynpnhj(self,parent):
  98.         self.pj = Text(parent)
  99.         self.pj.place(x=280, y=72, width=299, height=37)
  100.         return self.pj
  101.     # 电影日期
  102.     def __tk_text_lwynq5ny(self,parent):
  103.         self.rq = Text(parent)
  104.         self.rq.place(x=280, y=131, width=298, height=36)
  105.         return self.rq
  106.     # 电影类型
  107.     def __tk_text_lwynqjmm(self,parent):
  108.         self.lx = Text(parent)
  109.         self.lx.place(x=280, y=191, width=298, height=38)
  110.         return self.lx
  111. class Win(WinGUI):
  112.     def __init__(self, controller):
  113.         self.ctl = controller
  114.         super().__init__()
  115.         self.__event_bind()
  116.         self.__style_config()
  117.         self.ctl.init(self)
  118.     def __event_bind(self):
  119.         pass
  120.     def __style_config(self):
  121.         pass
  122. if __name__ == "__main__":
  123.     win = WinGUI()
  124.     win.mainloop()
复制代码
爬取代码 
  1. import json
  2. import urllib
  3. from json import loads
  4. from urllib import request
  5. import requests
  6. from requests_html import HTMLSession
  7. from selenium import webdriver
  8. from selenium.webdriver.chrome.options import Options
  9. from selenium.webdriver.common.by import By
  10. movieData = ' [' \
  11.             '{"title":"纪录片", "type":"1", "interval_id":"100:90"}, ' \
  12.             ' {"title":"传记", "type":"2", "interval_id":"100:90"}, ' \
  13.             ' {"title":"犯罪", "type":"3", "interval_id":"100:90"}, ' \
  14.             ' {"title":"历史", "type":"4", "interval_id":"100:90"}, ' \
  15.             ' {"title":"动作", "type":"5", "interval_id":"100:90"}, ' \
  16.             ' {"title":"情色", "type":"6", "interval_id":"100:90"}, ' \
  17.             ' {"title":"歌舞", "type":"7", "interval_id":"100:90"}, ' \
  18.             ' {"title":"儿童", "type":"8", "interval_id":"100:90"}, ' \
  19.             ' {"title":"悬疑", "type":"10", "interval_id":"100:90"}, ' \
  20.             ' {"title":"剧情", "type":"11", "interval_id":"100:90"}, ' \
  21.             ' {"title":"灾难", "type":"12", "interval_id":"100:90"}, ' \
  22.             ' {"title":"爱情", "type":"13", "interval_id":"100:90"}, ' \
  23.             ' {"title":"音乐", "type":"14", "interval_id":"100:90"}, ' \
  24.             ' {"title":"冒险", "type":"15", "interval_id":"100:90"}, ' \
  25.             ' {"title":"奇幻", "type":"16", "interval_id":"100:90"}, ' \
  26.             ' {"title":"科幻", "type":"17", "interval_id":"100:90"}, ' \
  27.             ' {"title":"运动", "type":"18", "interval_id":"100:90"}, ' \
  28.             ' {"title":"惊悚", "type":"19", "interval_id":"100:90"}, ' \
  29.             ' {"title":"恐怖", "type":"20", "interval_id":"100:90"}, ' \
  30.             ' {"title":"战争", "type":"22", "interval_id":"100:90"}, ' \
  31.             ' {"title":"短片", "type":"23", "interval_id":"100:90"}, ' \
  32.             ' {"title":"喜剧", "type":"24", "interval_id":"100:90"}, ' \
  33.             ' {"title":"动画", "type":"25", "interval_id":"100:90"}, ' \
  34.             ' {"title":"同性", "type":"26", "interval_id":"100:90"}, ' \
  35.             ' {"title":"西部", "type":"27", "interval_id":"100:90"}, ' \
  36.             ' {"title":"家庭", "type":"28", "interval_id":"100:90"}, ' \
  37.             ' {"title":"武侠", "type":"29", "interval_id":"100:90"}, ' \
  38.             ' {"title":"古装", "type":"30", "interval_id":"100:90"}, ' \
  39.             ' {"title":"黑色电影", "type":"31", "interval_id":"100:90"}' \
  40.             ']'
  41. # 电影类型
  42. def get_movie_top(m_type: str):
  43.     """
  44.     排行榜查询方法
  45.     https://movie.douban.com/j/chart/top_list?type=&interval_id=100:90&action=unwatched&start=0&limit=
  46.     :param m_type: 电影类型
  47.     :param num:    爬取数量
  48.     :param rating: 影片评分
  49.     :param pj:     评价人数
  50.     :return:
  51.     """
  52.     try:
  53.         headers = {
  54.             'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
  55.         }
  56.         # url = 'https://movie.douban.com/j/chart/top_list?type=' + str(
  57.         #     m_type) + '&interval_id=100:90&action=unwatched&start=0&limit=' + str(num)
  58.         # req = request.Request(url=url, headers=headers)
  59.         # # 用于打开一个远程的url连接,并且向这个连接发出请求,获取响应结果
  60.         # f = request.urlopen(req)
  61.         # # 获取响应对象
  62.         # response = f.read()
  63.         # # 将json转为python对象
  64.         # jsonData = loads(response)
  65.         url = "https://movie.douban.com/j/chart/top_list"
  66.         params = {
  67.             "type": m_type,
  68.             "interval_id": "100:90",
  69.             "action": "unwatched",
  70.             "start": "0",
  71.             # 固定每次搜索条数为50条
  72.             "limit": 50
  73.         }
  74.         resp = requests.get(url, headers=headers, params=params)
  75.         jsonData = resp.json()
  76.         movies_list = []
  77.         # 循环获取的电影信息并提取有效数据
  78.         for subData in jsonData:
  79.             # 将评分设定为大于1.0以上 评价人数大于100000
  80.             if (float(subData['score']) >= float(1.0)) and (float(subData['vote_count']) >= float(100000)):
  81.                 movie = {
  82.                     "title": subData["title"],
  83.                     "rank": subData["rank"],
  84.                     "cover_url": subData["cover_url"],
  85.                     "types": "/".join(subData["types"]),
  86.                     "regions": subData["regions"][0],
  87.                     "release_date": subData["release_date"],
  88.                     "vote_count": subData["vote_count"],
  89.                     "score": subData["score"],
  90.                     "actors": "/".join(subData["actors"])
  91.                 }
  92.                 movies_list.append(movie)
  93.         with open('movies.json', 'w', encoding='utf-8') as fp:
  94.             json.dump(movies_list, fp, ensure_ascii=False, indent=2)
  95.         return {'code': 200, 'movies': movies_list}
  96.     except Exception as ex:
  97.         err_str = "出现未知异常:{}".format(ex)
  98.         return {'code': 500, 'msg': err_str}
  99. def get_movie_kw2(kw:str):
  100.     params = {
  101.         "search_text": "指环王",
  102.         "cat": "1002"
  103.     }
  104.     session = HTMLSession(
  105.         browser_args=[
  106.             '--no-sand',
  107.             '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
  108.         ]
  109.     )
  110.     resp = session.get("https://search.douban.com/movie/subject_search", params=params)
  111.     resp.html.render()
  112.     html = resp.html;
  113.     movies_list = []
  114.     divs = html.xpath("//div[@class='item-root'")
  115.     print(divs)
  116.     return movies_list
  117. def get_movie_kw(kw: str):
  118.     """
  119.     基于关键字查询电影信息
  120.     https://movie.douban.com/subject_search?search_text=&cat=1002
  121.     :param kw:
  122.     :return:
  123.     """
  124.     chrome_options = Options()
  125.     # 设置为无头模式,即不显示浏览器
  126.     chrome_options.add_argument('--headless')
  127.     # 设置user=agent
  128.     chrome_options.add_argument(
  129.         'user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"')
  130.     # 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium
  131.     # chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
  132.     # # 不加载图片,加快访问速度
  133.     # chrome_options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
  134.     # 加载chromedriver驱动是否成功
  135.     load_driver_success = False
  136.     browser = None
  137.     try:
  138.         # 设置chromedriver驱动路径
  139.         browser = webdriver.Chrome(options=chrome_options)
  140.         # 页面加载超时时间为10s
  141.         browser.set_page_load_timeout(10)
  142.         # 页面js加载超时时间为10s
  143.         browser.set_script_timeout(10)
  144.         load_driver_success = True
  145.     except Exception as ex:
  146.         load_driver_success = False
  147.         err_str = "加载chromedriver驱动失败,请下载chromedriver驱动并填写正确的路径。\n\n异常信息:{}".format(ex)
  148.         return {'code': 500, 'msg': err_str}
  149.     if load_driver_success:
  150.         # print(load_driver_success)
  151.         try:
  152.             url = 'https://search.douban.com/movie/subject_search?search_text=' + urllib.parse.quote(kw) + '&cat=1002'
  153.             # print(url)
  154.             # get方式获取返回数据
  155.             browser.get(url)
  156.             # 通过样式选择器获取满足div.item-root要求的所有数据
  157.             divs = browser.find_elements(By.CSS_SELECTOR, "div.item-root")
  158.             movies_list = []
  159.             for div in divs:
  160.                 movie = {
  161.                     "title": '',
  162.                     "rank": '',
  163.                     "cover_url": '',
  164.                     "types": '',
  165.                     "regions": '',
  166.                     "release_date": '',
  167.                     "vote_count": '',
  168.                     "score": '',
  169.                     "actors": ''
  170.                 }
  171.                 cover_url = div.find_elements_by_css_selector(".cover")
  172.                 # print(cover_url)
  173.                 if cover_url:
  174.                     movie["cover_url"] = cover_url[0].get_attribute("src")
  175.                     movie["title"] = cover_url[0].get_attribute("alt")
  176.                 rating = div.find_elements_by_css_selector("span.rating_nums")
  177.                 if rating:
  178.                     movie["score"] = rating[0].text
  179.                 pl = div.find_elements_by_css_selector("span.pl")
  180.                 if pl:
  181.                     movie["vote_count"] = pl[0].text.replace("(", "").replace(")", "").replace("人评价", "")
  182.                 regions = div.find_elements_by_css_selector("div.abstract")
  183.                 if regions:
  184.                     movie["regions"] = regions[0].text
  185.                 actors = div.find_elements_by_css_selector("div.abstract_2")
  186.                 if actors:
  187.                     movie["actors"] = actors[0].text
  188.                 movies_list.append(movie)
  189.             return {'code': 200, 'movies': movies_list}
  190.         except Exception as ex:
  191.             # 关闭浏览器
  192.             browser.quit()
  193.             err_str = "chromedriver驱动加载成功,但是Selenium获取数据出现其他未知异常:{}".format(ex)
  194.             return {'code': 200, 'msg': err_str}
  195. if __name__ == "__main__":
  196.     # movies = get_movie_top("25", 20, 8.8, 100000)
  197.     # movies = get_movie_kw("指环王")
  198.     movies = get_movie_kw2("指环王")
  199.     print(movies)
  200.     # for m in movies['movies']:
  201.     #     print(m)
复制代码


三、技术实现

   tkinter 布局
    json   获取数据
    thread  线程
    requests 模块
    selenium 爬取
  

四、总结

           此次项目结合了许多之前学过的知识 有最基本的python语法 也有界面的融合 另有selenium数据的爬取 字典 集合 列表 函数 方法也有用到 
  
          着实可以连接数据库效果会更好 大家可以去尝试一下

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

玛卡巴卡的卡巴卡玛

金牌会员
这个人很懒什么都没写!

标签云

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