Skip to content

Commit 7c74a01

Browse files
authored
[crunchyroll] Fix login (yt-dlp#2530)
Closes yt-dlp#1424 Authored by: tejing1
1 parent 1d3586d commit 7c74a01

File tree

1 file changed

+27
-45
lines changed

1 file changed

+27
-45
lines changed

yt_dlp/extractor/crunchyroll.py

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
sanitized_Request,
3636
traverse_obj,
3737
try_get,
38-
urlencode_postdata,
3938
xpath_text,
4039
)
4140
from ..aes import (
@@ -44,8 +43,8 @@
4443

4544

4645
class CrunchyrollBaseIE(InfoExtractor):
47-
_LOGIN_URL = 'https://www.crunchyroll.com/login'
48-
_LOGIN_FORM = 'login_form'
46+
_LOGIN_URL = 'https://www.crunchyroll.com/%3Cspan%20class="x x-first x-last">welcome/login'
47+
_API_BASE = 'https://api.crunchyroll.com'
4948
_NETRC_MACHINE = 'crunchyroll'
5049

5150
def _call_rpc_api(self, method, video_id, note=None, data=None):
@@ -62,50 +61,33 @@ def _login(self):
6261
username, password = self._get_login_info()
6362
if username is None:
6463
return
65-
66-
login_page = self._download_webpage(
67-
self._LOGIN_URL, None, 'Downloading login page')
68-
69-
def is_logged(webpage):
70-
return 'href="/logout"' in webpage
71-
72-
# Already logged in
73-
if is_logged(login_page):
74-
return
75-
76-
login_form_str = self._search_regex(
77-
r'(?P<form><form[^>]+?id=(["\'])%s\2[^>]*>)' % self._LOGIN_FORM,
78-
login_page, 'login form', group='form')
79-
80-
post_url = extract_attributes(login_form_str).get('action')
81-
if not post_url:
82-
post_url = self._LOGIN_URL
83-
elif not post_url.startswith('http'):
84-
post_url = compat_urlparse.urljoin(self._LOGIN_URL, post_url)
85-
86-
login_form = self._form_hidden_inputs(self._LOGIN_FORM, login_page)
87-
88-
login_form.update({
89-
'login_form[name]': username,
90-
'login_form[password]': password,
91-
})
92-
93-
response = self._download_webpage(
94-
post_url, None, 'Logging in', 'Wrong login info',
95-
data=urlencode_postdata(login_form),
96-
headers={'Content-Type': 'application/x-www-form-urlencoded'})
97-
98-
# Successful login
99-
if is_logged(response):
64+
if self._get_cookies(self._LOGIN_URL).get('etp_rt'):
10065
return
10166

102-
error = self._html_search_regex(
103-
'(?s)<ul[^>]+class=["\']messages["\'][^>]*>(.+?)</ul>',
104-
response, 'error message', default=None)
105-
if error:
106-
raise ExtractorError('Unable to login: %s' % error, expected=True)
107-
108-
raise ExtractorError('Unable to log in')
67+
upsell_response = self._download_json(
68+
f'{self._API_BASE}/get_upsell_data.0.json', None, 'Getting session id',
69+
query={
70+
'sess_id': 1,
71+
'device_id': 'whatvalueshouldbeforweb',
72+
'device_type': 'com.crunchyroll.static',
73+
'access_token': 'giKq5eY27ny3cqz',
74+
'referer': self._LOGIN_URL
75+
})
76+
if upsell_response['code'] != 'ok':
77+
raise ExtractorError('Could not get session id')
78+
session_id = upsell_response['data']['session_id']
79+
80+
login_response = self._download_json(
81+
f'{self._API_BASE}/login.1.json', None, 'Logging in',
82+
data=compat_urllib_parse_urlencode({
83+
'account': username,
84+
'password': password,
85+
'session_id': session_id
86+
}).encode('ascii'))
87+
if login_response['code'] != 'ok':
88+
raise ExtractorError('Login failed. Bad username or password?', expected=True)
89+
if not self._get_cookies(self._LOGIN_URL).get('etp_rt'):
90+
raise ExtractorError('Login succeeded but did not set etp_rt cookie')
10991

11092
def _real_initialize(self):
11193
self._login()

0 commit comments

Comments
 (0)