My kids watch a lot of Netflix. Some of them watch it too much, and my wife and I want to be able to turn off the spigot at night so that they’ll go to sleep without us having to confiscate all the phones and tablets in the house. Unfortunately, Netflix doesn’t have parental controls that make this possible (in particular, they would need to support protecting profiles with PINs and time- and profile- based access restrictions). We therefore came up with the idea of changing our Netflix password at bedtime every night and changing it back in the morning.
However, there’s no way we can sustain logging into Netflix in a browser and changing our password twice a day, morning and night, so we need to we need to find a way to automate that.
Netflix doesn’t provide any sort of public API for things like that. OK, fine, whatever, I’m fluent in Perl’s WWW::Mechanize
and Python’s mechanize
, so I can just write a script to automate logging into my Netflix account and changing the password, right? Unfortunately, nope, it’s not that easy, because the password change page on the Netflix site is a funky React-based form, not a regular HTML form, so neither the Perl nor the Python library knows how to deal with it.
Fortunately, all is not lost: Selenium to the rescue!
#!/usr/bin/env python3
import argparse
from contextlib import contextmanager
import os
from selenium import webdriver
from selenium.webdriver.common.keys import Keys;
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import staleness_of
def parse_args():
parser = argparse.ArgumentParser(description="Change Netflix password")
parser.add_argument("--username", action="store", required=True)
parser.add_argument("--old-password", action="store", required=True)
parser.add_argument("--new-password", action="store", required=True)
parser.add_argument("--headless", action="store_true", default=False)
return parser.parse_args()
# Credit: http://www.obeythetestinggoat.com/how-to-get-selenium-to-wait-for-page-load-after-a-click.html
@contextmanager
def wait_for_page_load(driver, timeout=30):
old_page = driver.find_element_by_tag_name('html')
yield
WebDriverWait(driver, timeout).until(staleness_of(old_page))
def main():
args = parse_args()
options = webdriver.ChromeOptions()
if args.headless:
options.add_argument('headless')
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://www.netflix.com/login")
try:
elem = driver.find_element_by_name("userLoginId")
except NoSuchElementException:
elem = driver.find_element_by_name("email")
elem.send_keys(args.username)
elem = driver.find_element_by_name("password")
elem.send_keys(args.old_password)
elem.send_keys(Keys.RETURN)
with wait_for_page_load(driver):
driver.get("https://www.netflix.com/password")
elem = driver.find_element_by_name("currentPassword")
elem.send_keys(args.old_password)
elem = driver.find_element_by_name("newPassword")
elem.send_keys(args.new_password)
elem = driver.find_element_by_name("confirmNewPassword")
elem.send_keys(args.new_password)
elem = driver.find_element_by_id("btn-save")
elem.click()
with wait_for_page_load(driver):
pass
if __name__ == '__main__':
main()
thanks man you saved my day 🙂
Thanks! I had to update some lines because the Netflix web page changed. Here’s the updated main().
def main():
args = parse_args()
options = webdriver.ChromeOptions()
if args.headless:
options.add_argument(‘headless’)
driver = webdriver.Chrome(chrome_options=options)
driver.get(“https://www.netflix.com/login”)
elem = driver.find_element_by_name(“userLoginId”)
elem.send_keys(args.username)
elem = driver.find_element_by_name(“password”)
elem.send_keys(args.old_password)
elem.send_keys(Keys.RETURN)
with wait_for_page_load(driver):
driver.get(“https://www.netflix.com/password”)
driver.get(“https://www.netflix.com/password”)
elem = driver.find_element_by_name(“currentPassword”)
elem.send_keys(args.old_password)
elem = driver.find_element_by_name(“newPassword”)
elem.send_keys(args.new_password)
elem = driver.find_element_by_name(“confirmNewPassword”)
elem.send_keys(args.new_password)
elem = driver.find_element_by_id(“btn-save”)
elem.click()
with wait_for_page_load(driver):
pass
Thanks, updated above.
Could you help include a proxy service in the above program, so that if it is used multiple times netflix doesnot block the ip?
This uses a real web browser, so any proxy configuration you want to use would need to be done in the web browser, not in the Python code.
What are you doing that requires changing your password so frequently that Netflix is blocking your IP?