Skip to content

Commit

Permalink
增加风控状态处理;增加登出功能
Browse files Browse the repository at this point in the history
  • Loading branch information
luolongfei committed Jan 12, 2022
1 parent 20cf469 commit 8a7cc8e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 42 deletions.
82 changes: 41 additions & 41 deletions netflix.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class Netflix(object):
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'

LOGIN_URL = 'https://www.netflix.com/login'
LOGOUT_URL = 'https://www.netflix.com/SignOut?lnkctr=mL'
RESET_PASSWORD_URL = 'https://www.netflix.com/password'
FORGOT_PASSWORD_URL = 'https://www.netflix.com/LoginHelp'
MANAGE_PROFILES_URL = 'https://www.netflix.com/ManageProfiles'
Expand Down Expand Up @@ -257,7 +258,7 @@ def get_all_args():

return parser.parse_args()

def __login(self, netflix_username: str, netflix_password: str):
def _login(self, netflix_username: str, netflix_password: str):
"""
登录
:param netflix_username:
Expand All @@ -283,12 +284,14 @@ def __login(self, netflix_username: str, netflix_password: str):

self.driver.find_element_by_class_name('login-button').click()

if self.has_unknown_error_alert():
raise UserWarning('当前账户可能处于风控期间,无法登录,本次操作将被忽略')

try:
WebDriverWait(self.driver, timeout=3, poll_frequency=0.94).until(lambda d: 'browse' in d.current_url)
except Exception as e:
WebDriverWait(self.driver, timeout=2, poll_frequency=0.5).until(
EC.visibility_of_element_located(
self.driver.find_element_by_xpath('//a[@data-uia="header-signout-link"]')),
EC.visibility_of_element_located((By.XPATH, '//a[@data-uia="header-signout-link"]')),
'查找登出元素未果')

logger.warning(f'当前账户可能非 Netflix 会员,本次登录没有意义')
Expand All @@ -315,7 +318,7 @@ def __forgot_password(self, netflix_username: str):

time.sleep(1)

self.handle_click_events(self.click_forgot_pwd_btn, max_num_of_attempts=12)
self.handle_event(self.click_forgot_pwd_btn, max_num_of_attempts=12)

# 直到页面显示已发送邮件
logger.debug('检测是否已到送信完成画面')
Expand Down Expand Up @@ -367,7 +370,7 @@ def __reset_password(self, curr_netflix_password: str, new_netflix_password: str

time.sleep(1)

self.handle_click_events(self.click_submit_btn)
self.handle_event(self.click_submit_btn)

return self.__pwd_change_result()
except Exception as e:
Expand Down Expand Up @@ -454,7 +457,7 @@ def element_visibility_of(self, xpath: str, verify_val: bool = False,
finally:
self.driver.implicitly_wait(Netflix.TIMEOUT)

def has_unknown_error_alert(self, error_el_xpath: str) -> bool:
def has_unknown_error_alert(self, error_el_xpath: str = '//div[@class="ui-message-contents"]') -> bool:
"""
页面提示未知错误
:return:
Expand All @@ -471,12 +474,11 @@ def has_unknown_error_alert(self, error_el_xpath: str) -> bool:

return False

def handle_click_events(self, func, error_el_xpath='//div[@class="ui-message-contents"]',
max_num_of_attempts: int = 10):
def handle_event(self, func, error_el_xpath='//div[@class="ui-message-contents"]', max_num_of_attempts: int = 10):
"""
处理点击事件
处理事件,一般是单个点击事件
在某些画面点击提交的时候,有可能报未知错误,需要稍等片刻再点击才正常
在某些画面点击提交的时候,有可能报未知错误,需要稍等片刻再点击或者重新触发一系列事件后才正常
:param func:
:param max_num_of_attempts:
:return:
Expand All @@ -492,38 +494,11 @@ def handle_click_events(self, func, error_el_xpath='//div[@class="ui-message-con
raise Exception('处理未知错误失败')
num += 1

logger.info(f'程式将休眠 {num} 秒后重试点击动作')
logger.debug(f'程式将休眠 {num} 秒后重试,最多不超过 {max_num_of_attempts} 次 [{num}/{max_num_of_attempts}]')
time.sleep(num)
else:
break

def handle_unknown_error_alert(self, func, max_try: int = 10):
"""
处理 Netflix 未知异常
Netflix 会随机出现提醒页面出现未知错误,请稍后重试的情况,需要稍等片刻再点击才正常
:param func:
:param max_try:
:return:
"""
num_of_tries = 0

while True:
if self.has_unknown_error_alert():
num_of_tries += 1

sleep_time = num_of_tries * 2
time.sleep(sleep_time)

logger.info(f'程式将休眠 {sleep_time} 秒后重试点击')

func()

if num_of_tries >= max_try:
raise Exception('处理 Netflix 未知异常失败')
else:
break

def __reset_password_via_mail(self, reset_url: str, new_netflix_password: str) -> bool:
"""
通过邮件重置密码
Expand All @@ -539,7 +514,7 @@ def __reset_password_via_mail(self, reset_url: str, new_netflix_password: str) -

self.input_pwd(new_netflix_password)

self.handle_click_events(self.click_submit_btn)
self.handle_event(self.click_submit_btn)

# 如果奈飞提示密码曾经用过,则应该先改为随机密码,然后再改回来
pwd_error_tips = self.element_visibility_of('//div[@data-uia="field-newPassword+error"]')
Expand All @@ -550,7 +525,7 @@ 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.handle_click_events(self.click_submit_btn)
self.handle_event(self.click_submit_btn)

self.__pwd_change_result()

Expand Down Expand Up @@ -1155,14 +1130,35 @@ def __recover_name(self, link_el: WebElement, real_name: str) -> bool:

return False

def _logout(self):
"""
登出
:return:
"""
try:
logger.debug('尝试登出')

self.driver.get(Netflix.LOGOUT_URL)

WebDriverWait(self.driver, timeout=4.9, poll_frequency=0.5).until(
EC.visibility_of_element_located((By.XPATH, '//a[@data-uia="header-login-link"]')), '查找登入元素未果')

logger.debug('登出成功')

return True
except Exception as e:
logger.warning('登出失败:{}', str(e))

return False

def protect_account_name(self):
"""
保护账户名不被修改
:return:
"""
for item in self.MULTIPLE_NETFLIX_ACCOUNTS:
try:
self.__login(item.get('u'), item.get('p'))
self._login(item.get('u'), item.get('p'))

self.driver.get(Netflix.MANAGE_PROFILES_URL)

Expand Down Expand Up @@ -1198,6 +1194,10 @@ def protect_account_name(self):
logger.success(f'用户名已恢复完成,共 {events_count} 件篡改事件,已成功处理 {success_num} 件')

logger.debug('用户名处理结束')

self._logout()
except UserWarning as e:
logger.debug(str(e))
except Exception as e:
logger.warning(f'用户名篡改检测出错:{str(e)} [账户:{item.get("u")}]')

Expand Down
2 changes: 1 addition & 1 deletion utils/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
@time 10:02
"""

__version__ = 'v0.5.5'
__version__ = 'v0.6'

0 comments on commit 8a7cc8e

Please sign in to comment.