PlaywrightCapture 1.28.0__tar.gz → 1.28.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {playwrightcapture-1.28.0 → playwrightcapture-1.28.2}/PKG-INFO +5 -4
- {playwrightcapture-1.28.0 → playwrightcapture-1.28.2}/playwrightcapture/capture.py +23 -2
- {playwrightcapture-1.28.0 → playwrightcapture-1.28.2}/playwrightcapture/helpers.py +9 -4
- {playwrightcapture-1.28.0 → playwrightcapture-1.28.2}/pyproject.toml +8 -7
- {playwrightcapture-1.28.0 → playwrightcapture-1.28.2}/LICENSE +0 -0
- {playwrightcapture-1.28.0 → playwrightcapture-1.28.2}/README.md +0 -0
- {playwrightcapture-1.28.0 → playwrightcapture-1.28.2}/playwrightcapture/__init__.py +0 -0
- {playwrightcapture-1.28.0 → playwrightcapture-1.28.2}/playwrightcapture/exceptions.py +0 -0
- {playwrightcapture-1.28.0 → playwrightcapture-1.28.2}/playwrightcapture/py.typed +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: PlaywrightCapture
|
3
|
-
Version: 1.28.
|
3
|
+
Version: 1.28.2
|
4
4
|
Summary: A simple library to capture websites using playwright
|
5
5
|
License: BSD-3-Clause
|
6
6
|
Author: Raphaël Vinot
|
@@ -20,15 +20,16 @@ Classifier: Topic :: Security
|
|
20
20
|
Provides-Extra: recaptcha
|
21
21
|
Requires-Dist: SpeechRecognition (>=3.14.1) ; extra == "recaptcha"
|
22
22
|
Requires-Dist: aiohttp-socks (>=0.10.1)
|
23
|
-
Requires-Dist: aiohttp[speedups] (>=3.11.
|
23
|
+
Requires-Dist: aiohttp[speedups] (>=3.11.14)
|
24
24
|
Requires-Dist: async-timeout (>=5.0.1) ; python_version < "3.11"
|
25
25
|
Requires-Dist: beautifulsoup4[charset-normalizer,lxml] (>=4.13.3)
|
26
26
|
Requires-Dist: dateparser (>=1.2.1)
|
27
|
-
Requires-Dist: playwright (>=1.
|
27
|
+
Requires-Dist: playwright (>=1.51.0)
|
28
28
|
Requires-Dist: playwright-stealth (>=1.0.6)
|
29
29
|
Requires-Dist: puremagic (>=1.28)
|
30
30
|
Requires-Dist: pydub (>=0.25.1) ; extra == "recaptcha"
|
31
|
-
Requires-Dist: setuptools (>=
|
31
|
+
Requires-Dist: setuptools (>=77.0.1)
|
32
|
+
Requires-Dist: typing-extensions (>=4.12.2,<5.0.0) ; python_version < "3.12"
|
32
33
|
Requires-Dist: tzdata (>=2025.1)
|
33
34
|
Requires-Dist: w3lib (>=2.3.1)
|
34
35
|
Project-URL: Issues, https://github.com/Lookyloo/PlaywrightCapture/issues
|
@@ -17,7 +17,7 @@ from dataclasses import dataclass
|
|
17
17
|
from io import BytesIO
|
18
18
|
from logging import LoggerAdapter, Logger
|
19
19
|
from tempfile import NamedTemporaryFile
|
20
|
-
from typing import Any,
|
20
|
+
from typing import Any, Literal, TYPE_CHECKING
|
21
21
|
from collections.abc import MutableMapping, Iterator
|
22
22
|
from urllib.parse import urlparse, unquote, urljoin, urlsplit, urlunsplit
|
23
23
|
from zipfile import ZipFile
|
@@ -46,11 +46,16 @@ if sys.version_info < (3, 11):
|
|
46
46
|
else:
|
47
47
|
from asyncio import timeout
|
48
48
|
|
49
|
+
if sys.version_info < (3, 12):
|
50
|
+
from typing_extensions import TypedDict
|
51
|
+
else:
|
52
|
+
from typing import TypedDict
|
53
|
+
|
49
54
|
if TYPE_CHECKING:
|
50
55
|
from playwright._impl._api_structures import (SetCookieParam, Geolocation,
|
51
56
|
HttpCredentials, Headers,
|
52
57
|
ViewportSize, Cookie,
|
53
|
-
ProxySettings)
|
58
|
+
ProxySettings, StorageState)
|
54
59
|
BROWSER = Literal['chromium', 'firefox', 'webkit']
|
55
60
|
|
56
61
|
try:
|
@@ -66,6 +71,7 @@ class CaptureResponse(TypedDict, total=False):
|
|
66
71
|
last_redirected_url: str
|
67
72
|
har: dict[str, Any] | None
|
68
73
|
cookies: list[Cookie] | None
|
74
|
+
storage: StorageState | None
|
69
75
|
error: str | None
|
70
76
|
error_name: str | None
|
71
77
|
html: str | None
|
@@ -186,6 +192,7 @@ class Capture():
|
|
186
192
|
self.should_retry: bool = False
|
187
193
|
self.__network_not_idle: int = 2 # makes sure we do not wait for network idle the max amount of time the capture is allowed to take
|
188
194
|
self._cookies: list[SetCookieParam] = []
|
195
|
+
self._storage: StorageState = {}
|
189
196
|
self._http_credentials: HttpCredentials = {}
|
190
197
|
self._geolocation: Geolocation = {}
|
191
198
|
self._headers: Headers = {}
|
@@ -358,6 +365,18 @@ class Capture():
|
|
358
365
|
path = cookie.get("path")
|
359
366
|
self.logger.warning(f'The cookie must have a URL ({url}) or a domain ({domain}) and a path ({path})')
|
360
367
|
|
368
|
+
@property
|
369
|
+
def storage(self) -> StorageState:
|
370
|
+
return self._storage
|
371
|
+
|
372
|
+
@storage.setter
|
373
|
+
def storage(self, storage: dict[str, Any] | None) -> None:
|
374
|
+
if not storage:
|
375
|
+
return
|
376
|
+
if 'cookies' in storage and 'origins' in storage:
|
377
|
+
self._storage['cookies'] = storage['cookies']
|
378
|
+
self._storage['origins'] = storage['origins']
|
379
|
+
|
361
380
|
@property
|
362
381
|
def headers(self) -> Headers:
|
363
382
|
return self._headers
|
@@ -458,6 +477,7 @@ class Capture():
|
|
458
477
|
timezone_id=self.timezone_id if self.timezone_id else None,
|
459
478
|
color_scheme=self.color_scheme if self.color_scheme else None,
|
460
479
|
viewport=vp,
|
480
|
+
storage_state=self.storage if self.storage else None,
|
461
481
|
# For debug only
|
462
482
|
# record_video_dir='./videos/',
|
463
483
|
**device_context_settings
|
@@ -1177,6 +1197,7 @@ class Capture():
|
|
1177
1197
|
self.logger.debug('Finishing up capture.')
|
1178
1198
|
if not capturing_sub:
|
1179
1199
|
try:
|
1200
|
+
to_return['storage'] = await self.context.storage_state(indexed_db=True)
|
1180
1201
|
to_return['cookies'] = await self.context.cookies()
|
1181
1202
|
self.logger.debug('Done with cookies.')
|
1182
1203
|
except Exception as e:
|
@@ -2,13 +2,19 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
+
import sys
|
6
|
+
|
5
7
|
from collections import defaultdict
|
6
|
-
from typing import TypedDict
|
7
8
|
|
8
9
|
from playwright.sync_api import sync_playwright
|
9
10
|
|
10
11
|
from .exceptions import UnknownPlaywrightDeviceType
|
11
12
|
|
13
|
+
if sys.version_info < (3, 12):
|
14
|
+
from typing_extensions import TypedDict
|
15
|
+
else:
|
16
|
+
from typing import TypedDict
|
17
|
+
|
12
18
|
|
13
19
|
class PlaywrightDevice(TypedDict):
|
14
20
|
|
@@ -22,9 +28,8 @@ class PlaywrightDevice(TypedDict):
|
|
22
28
|
|
23
29
|
def get_devices(in_testsuite: bool=False) -> dict[str, dict[str, dict[str, PlaywrightDevice]]]:
|
24
30
|
to_return: dict[str, dict[str, dict[str, PlaywrightDevice]]] = {'desktop': defaultdict(dict), 'mobile': defaultdict(dict)}
|
25
|
-
|
26
|
-
|
27
|
-
playwright.stop()
|
31
|
+
with sync_playwright() as playwright:
|
32
|
+
devices: dict[str, PlaywrightDevice] = playwright.devices
|
28
33
|
for device_name, settings in devices.items():
|
29
34
|
splitted_name = device_name.split(' ')
|
30
35
|
if splitted_name[0] == 'Desktop':
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "PlaywrightCapture"
|
3
|
-
version = "1.28.
|
3
|
+
version = "1.28.2"
|
4
4
|
description = "A simple library to capture websites using playwright"
|
5
5
|
authors = [
|
6
6
|
{name="Raphaël Vinot", email= "raphael.vinot@circl.lu"}
|
@@ -12,17 +12,18 @@ requires-python = ">=3.9"
|
|
12
12
|
dynamic = [ "classifiers" ]
|
13
13
|
|
14
14
|
dependencies = [
|
15
|
-
"playwright (>=1.
|
15
|
+
"playwright (>=1.51.0)",
|
16
16
|
"dateparser (>=1.2.1)",
|
17
17
|
"beautifulsoup4[charset-normalizer,lxml] (>=4.13.3)",
|
18
18
|
"w3lib (>=2.3.1)",
|
19
19
|
"tzdata (>=2025.1)",
|
20
20
|
"playwright-stealth (>=1.0.6)",
|
21
|
-
"setuptools (>=
|
21
|
+
"setuptools (>=77.0.1)",
|
22
22
|
"puremagic (>=1.28)",
|
23
23
|
"async-timeout (>=5.0.1) ; python_version < \"3.11\"",
|
24
|
-
"aiohttp[speedups] (>=3.11.
|
25
|
-
"aiohttp-socks (>=0.10.1)"
|
24
|
+
"aiohttp[speedups] (>=3.11.14)",
|
25
|
+
"aiohttp-socks (>=0.10.1)",
|
26
|
+
"typing-extensions (>=4.12.2,<5.0.0) ; python_version < \"3.12\""
|
26
27
|
]
|
27
28
|
|
28
29
|
[project.urls]
|
@@ -46,10 +47,10 @@ recaptcha = [
|
|
46
47
|
|
47
48
|
[tool.poetry.group.dev.dependencies]
|
48
49
|
types-beautifulsoup4 = "^4.12.0.20250204"
|
49
|
-
pytest = "^8.3.
|
50
|
+
pytest = "^8.3.5"
|
50
51
|
mypy = "^1.15.0"
|
51
52
|
types-dateparser = "^1.2.0.20250208"
|
52
|
-
types-pytz = "^2025.1.0.
|
53
|
+
types-pytz = "^2025.1.0.20250318"
|
53
54
|
|
54
55
|
|
55
56
|
[build-system]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|