Skip to content

Commit d0f0c38

Browse files
committed
Fix issue where user is not signed in
1 parent 6f2afa7 commit d0f0c38

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

lchelper/crawler.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from typing import List
44

55
from selenium import webdriver
6+
from selenium.common.exceptions import TimeoutException
67
from selenium.webdriver.common.by import By
78
from selenium.webdriver.support import expected_conditions as Expected
89
from selenium.webdriver.support.wait import WebDriverWait
@@ -39,6 +40,19 @@ def get_cookie_path(username: str, site: str) -> str:
3940
return os.path.join(COOKIE_FOLDER, f"{username}@{site}.dat")
4041

4142

43+
def check_login(browser, site: str, timeout: int = 10) -> bool:
44+
try:
45+
if site == "leetcode":
46+
WebDriverWait(browser, timeout).until(
47+
Expected.presence_of_element_located((By.CSS_SELECTOR, 'img.avatar')))
48+
else: # site == "leetcode-cn"
49+
WebDriverWait(browser, timeout).until(
50+
Expected.presence_of_element_located((By.CSS_SELECTOR, 'span.ant-avatar')))
51+
return True
52+
except TimeoutException:
53+
return False
54+
55+
4256
def update_cookie(username: str, site: str) -> None:
4357
r"""Update the cookie for the LeetCode user."""
4458
browser = webdriver.Chrome()
@@ -69,12 +83,8 @@ def update_cookie(username: str, site: str) -> None:
6983
# elem = browser.find_element_by_css_selector('button[data-cy="sign-in-btn"]')
7084
# browser.execute_script("arguments[0].click();", elem)
7185

72-
if site == "leetcode":
73-
WebDriverWait(browser, 120).until(
74-
Expected.presence_of_element_located((By.CSS_SELECTOR, 'img.avatar')))
75-
else: # site == "leetcode-cn"
76-
WebDriverWait(browser, 120).until(
77-
Expected.presence_of_element_located((By.CSS_SELECTOR, 'span.ant-avatar')))
86+
if not check_login(browser, site, timeout=120):
87+
raise RuntimeError("Login failed!")
7888

7989
cookies = browser.get_cookies()
8090
jar = http.cookiejar.LWPCookieJar()
@@ -127,23 +137,31 @@ def get_problems(contest_url: str, site: str, cookie_path: str) -> List[Problem]
127137
cookie_jar.load(ignore_discard=True, ignore_expires=True)
128138
for c in cookie_jar:
129139
browser.add_cookie({"name": c.name, 'value': c.value, 'path': c.path})
140+
browser.get(contest_url) # visit again to refresh page with cookies added
141+
142+
if not check_login(browser, site, timeout=10):
143+
browser.quit()
144+
print(f"Cookie '{cookie_path}' might have expired. Please try logging in again")
145+
exit(1)
130146

131147
elem = browser.find_element_by_css_selector("ul.contest-question-list")
132148
links = elem.find_elements_by_tag_name("a")
133149
problem_paths = [(link.get_attribute("href"), link.text) for link in links]
134150
log(f"Found problems: {[name for _, name in problem_paths]!r}")
135151

136-
if site == "leetcode":
137-
statement_css_selector = "div.question-content"
138-
code_css_selector = "pre.CodeMirror-line"
139-
else: # site == "leetcode-cn"
140-
statement_css_selector = "div[data-key='description-content'] div.content__1Y2H"
141-
code_css_selector = "div.monaco-scrollable-element div.view-line"
142-
143152
parsed_problems = []
144153
for idx, (problem_url, problem_name) in enumerate(problem_paths):
145154
browser.get(problem_url)
146-
statement = browser.find_element_by_css_selector(statement_css_selector).text
155+
try:
156+
# Page during contest; editor located below statement.
157+
statement_css_selector = "div.question-content"
158+
code_css_selector = "pre.CodeMirror-line"
159+
statement = browser.find_element_by_css_selector(statement_css_selector).text
160+
except TimeoutException:
161+
# Page after contest; statement and editor in vertically split panes.
162+
statement_css_selector = "div[data-key='description-content'] div.content__1Y2H"
163+
code_css_selector = "div.monaco-scrollable-element div.view-line"
164+
statement = browser.find_element_by_css_selector(statement_css_selector).text
147165
examples = [
148166
elem.text for elem in browser.find_elements_by_css_selector("pre:not([class])") if elem.text]
149167
code = [elem.text for elem in browser.find_elements_by_css_selector(code_css_selector)]

main.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ def main():
7373

7474
cached_problems: Optional[List[Dict[str, Any]]] = None
7575
if not args.no_cache:
76-
if contest_name in info:
77-
cached_problems = info[contest_name]
76+
if (site, contest_name) in info:
77+
cached_problems = info[site, contest_name]
7878

7979
if cached_problems is None:
8080
available_users = lchelper.get_users()
@@ -109,9 +109,11 @@ def main():
109109
user = candidates[0]
110110
cookie_path = lchelper.get_cookie_path(user.username, user.site)
111111
url = f"https://{user.site}.com/contest/{contest_name}"
112+
lchelper.log(f"User: {user}, URL: {url}")
113+
112114
problems = lchelper.get_problems(url, user.site, cookie_path)
113115

114-
info[contest_name] = [lchelper.utils.to_dict(p) for p in problems]
116+
info[site, contest_name] = [lchelper.utils.to_dict(p) for p in problems]
115117
with open(CACHE_FILE, "wb") as f:
116118
pickle.dump(info, f)
117119
else:

0 commit comments

Comments
 (0)