diff --git a/README.md b/README.md
index 828eb07..17968f0 100644
--- a/README.md
+++ b/README.md
@@ -1,34 +1,31 @@
 <div align="center">
+
+[![Netflix.png](https://s4.ax1x.com/2021/12/24/TYGHXD.png)](https://s4.ax1x.com/2021/12/24/TYGHXD.png)
+
 <h1>Netflix</h1>
 监听奈飞(Netflix)密码变更邮件,自动重置密码。
 </div>
 
-### 简介
+### 缘起
+
+共享 Netflix 账户的用户,密码可能频繁被人修改,使大家无法登录。
 
-共享 Netflix 账户的用户,最大的烦恼莫过于密码频繁被不良人修改,本项目完美解决了这个问题。基本逻辑是监听 Netflix 密码变更邮件,自动重置密码。
-仅供 Netflix 账户主使用。
+本项目完美解决了这个问题,基本逻辑是监听 Netflix 密码变更邮件,自动重置密码。仅供 Netflix 账户主使用。
 
 ### 使用方法
 
-*这里只说明如何在 docker 中使用,按照步骤走即可。*
+*这里只说明如何在 Docker 中使用,按照步骤走即可。*
 
-#### 1、安装 docker
+#### 1、安装 Docker
 
 升级源并安装软件(下面两行命令二选一,根据你自己的系统)
 
-Debian / Ubuntu
-
-```shell
-apt-get update && apt-get install -y wget vim git
-```
-
-CentOS
-
 ```shell
-yum update && yum install -y wget vim git
+apt-get update && apt-get install -y wget vim git # Debian / Ubuntu
+yum update && yum install -y wget vim git # CentOS
 ```
 
-一句话命令安装 docker
+一句话命令安装 Docker
 
 ```shell
 wget -qO- get.docker.com | bash
@@ -37,7 +34,7 @@ wget -qO- get.docker.com | bash
 说明:请使用 KVM 架构的 VPS,OpenVZ 架构的 VPS 不支持安装 Docker,另外 CentOS 8 不支持用此脚本来安装 Docker。 更多关于 Docker
 安装的内容参考 [Docker 官方安装指南](https://docs.docker.com/engine/install/) 。
 
-启动 docker
+启动 Docker
 
 ```shell
 systemctl start docker
@@ -50,9 +47,9 @@ sudo systemctl enable docker.service
 sudo systemctl enable containerd.service
 ```
 
-#### 2、安装 docker-compose
+#### 2、安装 Docker-compose
 
-一句话命令安装 docker-compose,如果想自定义版本,可以修改下面的版本号(`DOCKER_COMPOSE_VER`对应的值),否则保持默认就好。
+一句话命令安装 Docker-compose,如果想自定义版本,可以修改下面的版本号(`DOCKER_COMPOSE_VER`对应的值),否则保持默认就好。
 
 ```shell
 DOCKER_COMPOSE_VER=1.29.2 && sudo curl -L "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VER}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && sudo chmod +x /usr/local/bin/docker-compose && sudo ln -snf /usr/local/bin/docker-compose /usr/bin/docker-compose && docker-compose --version
@@ -67,15 +64,45 @@ git clone https://github.com/luolongfei/netflix.git && cd netflix
 #### 4、修改 .env 配置
 
 完成步骤 3 后,现在你应该正位于源码根目录,即 `.env.example` 文件所在目录,执行
+
 ```shell
 cp .env.example .env
 ```
-然后使用`vim`修改`.env`文件中的配置项。注意在 docker 中运行的话,`DRIVER_EXECUTABLE_FILE`、`REDIS_HOST`以及`REDIS_PORT`的值保持默认即可。
+
+然后使用`vim`修改`.env`文件中的配置项。注意在 Docker 中运行的话,`DRIVER_EXECUTABLE_FILE`、`REDIS_HOST`以及`REDIS_PORT`的值保持默认即可。
 
 #### 5、运行
 
 直接执行
+
 ```shell
-docker-compose up -d
+docker-compose up -d --build
 ```
-执行完成后,项目便在后台跑起来了,再执行 `docker-compose ps` 可以看到程式的运行状态。
\ No newline at end of file
+
+执行完成后,项目便在后台跑起来了。
+
+#### 6、Docker-compose 常用命令
+
+查看程式的运行状态
+
+```shell
+docker-compose ps
+```
+输出程序日志
+```shell
+docker-compose logs
+```
+
+更多 Docker-compose 命令请参考: [Docker-compose 官方指南](https://docs.docker.com/compose/reference/) 。在官网能找到所有命令。
+
+#### 7、问答
+
+> 如何升级到新版本呢?
+> 
+请在`docker-compose.yml`文件所在目录,拉取最新的代码,然后同样执行`docker-compose up -d --build`,Docker 会自动使用最新的代码进行构建,
+构建完跑起来后,即是最新版本。
+
+> 非 Netflix 账户主可以使用本项目吗?
+> 
+不能。本项目仅供 Netflix 账户主使用,因为涉及到监听 Netflix 账户的邮件,而只有 Netflix 账户主才有 Netflix 邮箱以及其密码的权限,所以只有 Netflix 
+账户主有权使用。
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 7753ac0..9ed0cb5 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -5,6 +5,8 @@ services:
     build:
       context: .
       dockerfile: Dockerfile
+    depends_on:
+      - redis
     container_name: netflix
     volumes:
       - .:/conf
diff --git a/netflix.py b/netflix.py
index b3cc8eb..ae6bd45 100644
--- a/netflix.py
+++ b/netflix.py
@@ -77,7 +77,7 @@ def wrapper(*args, **kwargs):
 
 
 class Netflix(object):
-    VERSION = 'v0.4'
+    VERSION = 'v0.5.1'
 
     # 超时秒数,包括隐式等待和显式等待
     TIMEOUT = 23
@@ -302,9 +302,7 @@ def __forgot_password(self, netflix_username: str):
 
         time.sleep(2)
 
-        self.click_forgot_pwd_btn()
-
-        self.handle_unknown_error_alert(self.click_forgot_pwd_btn, 12)
+        self.handle_click_events(self.click_forgot_pwd_btn, max_num_of_attempts=12)
 
         # 直到页面显示已发送邮件
         logger.debug('检测是否已到送信完成画面')
@@ -355,9 +353,7 @@ def __reset_password(self, curr_netflix_password: str, new_netflix_password: str
 
             time.sleep(1)
 
-            self.click_submit_btn()
-
-            self.handle_unknown_error_alert(self.click_submit_btn)
+            self.handle_click_events(self.click_submit_btn)
 
             return self.__pwd_change_result()
         except Exception as e:
@@ -390,17 +386,57 @@ def click_submit_btn(self):
         """
         self.driver.find_element_by_id('btn-save').click()
 
-    def element_visibility_of(self, xpath: str) -> WebElement or None:
+    def element_visibility_of(self, xpath: str, verify_val: bool = False,
+                              max_num_of_attempts: int = 3, el_wait_time: int = 2) -> WebElement or None:
         """
         元素是否存在且可见
         适用于在已经加载完的网页做检测,可见且存在则返回元素,否则返回 None
         :param xpath:
+        :param verify_val: 如果传入 True,则验证元素是否有值,或者 inner HTML 不为空,并作为关联条件
+        :param max_num_of_attempts: 最大尝试次数,由于有的元素的值可能是异步加载的,需要多次尝试是否能获取到值,每次获取间隔休眠次数秒
+        :param el_wait_time: 等待时间,查找元素最多等待多少秒,默认 2 秒
         :return:
         """
         try:
             self.driver.implicitly_wait(2)
 
-            el = self.driver.find_element_by_xpath(xpath)
+            start_time = time.time()
+            while True:
+                if time.time() - start_time > el_wait_time:
+                    logger.warning(f'查找元素 {xpath} 耗时超过 {el_wait_time} 秒')
+
+                    return None
+
+                try:
+                    # 此处只为找到元素,如果下面不需要验证元素是否有值的话,则使用此处找到的元素
+                    # 否则下面验值逻辑会重新找到该元素以使用,此处的 el 会被覆盖
+                    el = self.driver.find_element_by_xpath(xpath)
+
+                    break
+                except Exception:
+                    pass
+
+            num = 0
+            while True:
+                if not verify_val:
+                    break
+
+                # 需要每次循环找到此元素,以确定元素的值是否发生变化
+                el = self.driver.find_element_by_xpath(xpath)
+
+                if el.tag_name == 'input':
+                    val = el.get_attribute('value')
+                    if val and len(val) > 0:
+                        break
+                elif el.text != '':
+                    break
+
+                # 多次尝试无果则放弃
+                if num > max_num_of_attempts:
+                    break
+                num += 1
+
+                time.sleep(num)
 
             return el if EC.visibility_of(el) else None
         except Exception:
@@ -408,24 +444,49 @@ def element_visibility_of(self, xpath: str) -> WebElement or None:
         finally:
             self.driver.implicitly_wait(Netflix.TIMEOUT)
 
-    def has_unknown_error_alert(self) -> bool:
+    def has_unknown_error_alert(self, error_el_xpath: str) -> bool:
         """
-        Netflix 提醒页面出现未知错误
+        页面提示未知错误
         :return:
         """
-        error_tips_el = self.element_visibility_of('//div[@class="ui-message-contents"]')
-
+        error_tips_el = self.element_visibility_of(error_el_xpath, True)
         if error_tips_el:
             # 密码修改成功画面的提示语与错误提示语共用的同一个元素,防止误报
             if 'YourAccount?confirm=password' in self.driver.current_url or 'Your password has been changed' in error_tips_el.text:
                 return False
 
-            logger.warning('页面出现未知错误提醒,提醒内容为 ' + error_tips_el.text)
+            logger.warning(f'页面出现未知错误:{error_tips_el.text}')
 
             return True
 
         return False
 
+    def handle_click_events(self, func, error_el_xpath='//div[@class="ui-message-contents"]',
+                            max_num_of_attempts: int = 10):
+        """
+        处理点击事件
+
+        在某些画面点击提交的时候,有可能报未知错误,需要稍等片刻再点击才正常
+        :param func:
+        :param max_num_of_attempts:
+        :return:
+        """
+        func()
+
+        num = 0
+        while True:
+            if self.has_unknown_error_alert(error_el_xpath):
+                func()
+
+                if num >= max_num_of_attempts:
+                    raise Exception('处理未知错误失败')
+                num += 1
+
+                logger.info(f'程式将休眠 {num} 秒后重试点击动作')
+                time.sleep(num)
+            else:
+                break
+
     def handle_unknown_error_alert(self, func, max_try: int = 10):
         """
         处理 Netflix 未知异常
@@ -467,9 +528,8 @@ def __reset_password_via_mail(self, reset_url: str, new_netflix_password: str) -
         self.driver.get(reset_url)
 
         self.input_pwd(new_netflix_password)
-        self.click_submit_btn()
 
-        self.handle_unknown_error_alert(self.click_submit_btn)
+        self.handle_click_events(self.click_submit_btn)
 
         # 如果奈飞提示密码曾经用过,则应该先改为随机密码,然后再改回来
         pwd_error_tips = self.element_visibility_of('//div[@data-uia="field-newPassword+error"]')
@@ -479,9 +539,8 @@ def __reset_password_via_mail(self, reset_url: str, new_netflix_password: str) -
 
             random_pwd = self.gen_random_pwd()
             self.input_pwd(random_pwd)
-            self.click_submit_btn()
 
-            self.handle_unknown_error_alert(self.click_submit_btn)
+            self.handle_click_events(self.click_submit_btn)
 
             if not self.__pwd_change_result():
                 return False
diff --git a/resources/Netflix_Logo_RGB.png b/resources/Netflix_Logo_RGB.png
new file mode 100644
index 0000000..151775b
Binary files /dev/null and b/resources/Netflix_Logo_RGB.png differ