Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion linkedin_scraper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""LinkedIn Scraper - Async Playwright-based scraper for LinkedIn."""
"""LinkedIn Scraper - Async Patchright-based scraper for LinkedIn."""

# Version
__version__ = "3.1.1"
Expand Down
21 changes: 12 additions & 9 deletions linkedin_scraper/core/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os
import time
from typing import Optional, Tuple
from playwright.async_api import Page, TimeoutError as PlaywrightTimeoutError
from patchright.async_api import Page, TimeoutError as PlaywrightTimeoutError
from dotenv import load_dotenv

from .exceptions import AuthenticationError
Expand All @@ -22,7 +22,7 @@ async def warm_up_browser(page: Page) -> None:
a normal browsing pattern before visiting LinkedIn.

Args:
page: Playwright page object
page: Patchright page object
"""
sites = [
'https://www.google.com',
Expand Down Expand Up @@ -51,7 +51,7 @@ def load_credentials_from_env() -> Tuple[Optional[str], Optional[str]]:
Supports both LINKEDIN_EMAIL/LINKEDIN_USERNAME and LINKEDIN_PASSWORD.

Returns:
Tuple of (email, password) or (None, None) if not found
Tuple of (email, password). Either or both may be None if not found.
"""
load_dotenv()

Expand All @@ -73,7 +73,7 @@ async def login_with_credentials(
Login to LinkedIn using email and password.

Args:
page: Playwright page object
page: Patchright page object
email: LinkedIn email (if None, tries to load from .env)
password: LinkedIn password (if None, tries to load from .env)
timeout: Timeout in milliseconds
Expand Down Expand Up @@ -192,9 +192,9 @@ async def login_with_cookie(page: Page, cookie_value: str) -> None:
"""
Login to LinkedIn using li_at cookie.

Args:
page: Playwright page object
cookie_value: Value of li_at cookie
Args:
page: Patchright page object
cookie_value: Value of li_at cookie

Comment on lines 192 to 198
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring and Args section have inconsistent indentation. The opening triple quotes at line 192 uses a single space instead of proper indentation, and the Args section at line 195 has extra leading spaces. This should be corrected to maintain consistent code formatting.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Raises:
AuthenticationError: If cookie login fails
Expand Down Expand Up @@ -247,7 +247,7 @@ async def is_logged_in(page: Page) -> bool:
Check if currently logged in to LinkedIn.

Args:
page: Playwright page object
page: Patchright page object

Returns:
True if logged in, False otherwise
Expand Down Expand Up @@ -275,7 +275,10 @@ async def is_logged_in(page: Page) -> bool:

# Return True if either nav elements found or on authenticated page
return has_nav_elements or is_authenticated_page
except PlaywrightTimeoutError:
return False
except Exception:
logger.warning("Unexpected error checking login status", exc_info=True)
return False


Expand All @@ -284,7 +287,7 @@ async def wait_for_manual_login(page: Page, timeout: int = 300000) -> None:
Wait for user to manually complete login (useful for 2FA, CAPTCHA, etc.).

Args:
page: Playwright page object
page: Patchright page object
timeout: Timeout in milliseconds (default: 5 minutes)

Raises:
Expand Down
Loading
Loading