parsagon 0.16.0__py3-none-any.whl → 0.17.0__py3-none-any.whl
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.
- parsagon/api.py +3 -1
- parsagon/executor.py +57 -3
- parsagon/main.py +5 -0
- parsagon/runs.py +2 -1
- {parsagon-0.16.0.dist-info → parsagon-0.17.0.dist-info}/METADATA +4 -5
- {parsagon-0.16.0.dist-info → parsagon-0.17.0.dist-info}/RECORD +9 -9
- {parsagon-0.16.0.dist-info → parsagon-0.17.0.dist-info}/WHEEL +1 -1
- {parsagon-0.16.0.dist-info → parsagon-0.17.0.dist-info}/entry_points.txt +0 -0
- {parsagon-0.16.0.dist-info → parsagon-0.17.0.dist-info}/top_level.txt +0 -0
parsagon/api.py
CHANGED
@@ -247,7 +247,7 @@ def get_pipelines():
|
|
247
247
|
return _api_call(httpx.get, f"/pipelines/")
|
248
248
|
|
249
249
|
|
250
|
-
def get_pipeline_code(pipeline_name, variables, headless, use_uc, optimize, use_proxy, pipeline_id=None):
|
250
|
+
def get_pipeline_code(pipeline_name, variables, headless, use_cdp, use_uc, optimize, use_proxy, pipeline_id=None):
|
251
251
|
if pipeline_id:
|
252
252
|
return _api_call(
|
253
253
|
httpx.post,
|
@@ -255,6 +255,7 @@ def get_pipeline_code(pipeline_name, variables, headless, use_uc, optimize, use_
|
|
255
255
|
json={
|
256
256
|
"variables": variables,
|
257
257
|
"headless": headless,
|
258
|
+
"use_cdp": use_cdp,
|
258
259
|
"use_uc": use_uc,
|
259
260
|
"optimize": optimize,
|
260
261
|
"use_proxy": use_proxy,
|
@@ -268,6 +269,7 @@ def get_pipeline_code(pipeline_name, variables, headless, use_uc, optimize, use_
|
|
268
269
|
json={
|
269
270
|
"variables": variables,
|
270
271
|
"headless": headless,
|
272
|
+
"use_cdp": use_cdp,
|
271
273
|
"use_uc": use_uc,
|
272
274
|
"optimize": optimize,
|
273
275
|
"use_proxy": use_proxy,
|
parsagon/executor.py
CHANGED
@@ -17,11 +17,17 @@ from lxml import etree
|
|
17
17
|
import lxml.html
|
18
18
|
from lxml.html.clean import Cleaner
|
19
19
|
from pypdf import PdfReader
|
20
|
-
from
|
20
|
+
from pyvirtualdisplay import Display
|
21
|
+
import undetected_chromedriver as uc
|
22
|
+
from selenium import webdriver
|
23
|
+
from selenium.webdriver.chrome.service import Service as ChromeService
|
24
|
+
from selenium.webdriver.chrome.options import Options
|
21
25
|
from selenium.webdriver.common.action_chains import ActionChains
|
22
26
|
from selenium.webdriver.common.by import By
|
23
27
|
from selenium.webdriver.common.keys import Keys
|
24
28
|
from selenium.webdriver.support.select import Select
|
29
|
+
from webdriver_manager.chrome import ChromeDriverManager
|
30
|
+
from webdriver_manager.core.driver_cache import DriverCacheManager
|
25
31
|
|
26
32
|
from parsagon import settings
|
27
33
|
from parsagon.api import (
|
@@ -76,6 +82,7 @@ class Executor:
|
|
76
82
|
infer=False,
|
77
83
|
use_uc=False,
|
78
84
|
driver_path=None,
|
85
|
+
options=[],
|
79
86
|
page_load_timeout=None,
|
80
87
|
script_timeout=None,
|
81
88
|
function_bank={},
|
@@ -83,8 +90,43 @@ class Executor:
|
|
83
90
|
self.task = task
|
84
91
|
self.headless = headless
|
85
92
|
self.function_bank = function_bank
|
86
|
-
self.
|
87
|
-
|
93
|
+
if self.headless:
|
94
|
+
self.display = Display(visible=False, size=(1280, 1050)).start()
|
95
|
+
if driver_path:
|
96
|
+
cache_manager = DriverCacheManager(root_dir=driver_path)
|
97
|
+
driver_executable_path = ChromeDriverManager(cache_manager=cache_manager).install()
|
98
|
+
else:
|
99
|
+
driver_executable_path = ChromeDriverManager().install()
|
100
|
+
if use_uc:
|
101
|
+
chrome_options = uc.ChromeOptions()
|
102
|
+
chrome_options.add_argument("--start-maximized")
|
103
|
+
for option in options:
|
104
|
+
chrome_options.add_argument(option)
|
105
|
+
chrome_options.add_experimental_option(
|
106
|
+
"prefs",
|
107
|
+
{
|
108
|
+
"download.default_directory": os.getcwd(),
|
109
|
+
"download.prompt_for_download": False,
|
110
|
+
"download.directory_upgrade": True,
|
111
|
+
"plugins.always_open_pdf_externally": True,
|
112
|
+
},
|
113
|
+
)
|
114
|
+
self.driver = uc.Chrome(driver_executable_path=driver_executable_path, options=chrome_options)
|
115
|
+
else:
|
116
|
+
chrome_options = webdriver.ChromeOptions()
|
117
|
+
chrome_options.add_argument("--start-maximized")
|
118
|
+
for option in options:
|
119
|
+
chrome_options.add_argument(option)
|
120
|
+
chrome_options.add_experimental_option(
|
121
|
+
"prefs",
|
122
|
+
{
|
123
|
+
"download.default_directory": os.getcwd(),
|
124
|
+
"download.prompt_for_download": False,
|
125
|
+
"download.directory_upgrade": True,
|
126
|
+
"plugins.always_open_pdf_externally": True,
|
127
|
+
},
|
128
|
+
)
|
129
|
+
self.driver = webdriver.Chrome(service=ChromeService(driver_executable_path), options=chrome_options)
|
88
130
|
if page_load_timeout:
|
89
131
|
self.driver.set_page_load_timeout(page_load_timeout)
|
90
132
|
if script_timeout:
|
@@ -115,6 +157,7 @@ class Executor:
|
|
115
157
|
"get_serp_data": get_serp_data,
|
116
158
|
"get_pdf_text": self.get_pdf_text,
|
117
159
|
"str_to_iso8601": self.str_to_iso8601,
|
160
|
+
"get_network_requests": self.get_network_requests,
|
118
161
|
}
|
119
162
|
self.custom_functions = {}
|
120
163
|
self.infer = infer
|
@@ -671,6 +714,17 @@ class Executor:
|
|
671
714
|
s = " ".join(s.split()[:-1])
|
672
715
|
return ""
|
673
716
|
|
717
|
+
def get_network_requests(window_id, delay=30):
|
718
|
+
requests = []
|
719
|
+
|
720
|
+
def handle_request(event):
|
721
|
+
requests.append(event)
|
722
|
+
|
723
|
+
driver.switch_to.window(window_id)
|
724
|
+
driver.add_cdp_listener("Network.requestWillBeSent", handle_request)
|
725
|
+
wait(delay)
|
726
|
+
return requests
|
727
|
+
|
674
728
|
def execute(self, code):
|
675
729
|
loc = {}
|
676
730
|
try:
|
parsagon/main.py
CHANGED
@@ -144,6 +144,11 @@ def get_args(argv):
|
|
144
144
|
type=str,
|
145
145
|
help="write the data to the given file path",
|
146
146
|
)
|
147
|
+
parser_run.add_argument(
|
148
|
+
"--use_cdp",
|
149
|
+
action="store_true",
|
150
|
+
help="enable CDP (only in undetected mode)",
|
151
|
+
)
|
147
152
|
parser_run.add_argument(
|
148
153
|
"--undetected",
|
149
154
|
action="store_true",
|
parsagon/runs.py
CHANGED
@@ -28,6 +28,7 @@ def run(
|
|
28
28
|
remote=False,
|
29
29
|
output_log=False,
|
30
30
|
output_file=None,
|
31
|
+
use_cdp=False,
|
31
32
|
undetected=False,
|
32
33
|
optimize=False,
|
33
34
|
use_proxy=False,
|
@@ -83,7 +84,7 @@ def run(
|
|
83
84
|
|
84
85
|
run = create_pipeline_run(pipeline_id, variables, True)
|
85
86
|
code = get_pipeline_code(
|
86
|
-
program_name, variables, headless, undetected, optimize, use_proxy, pipeline_id=program_id
|
87
|
+
program_name, variables, headless, use_cdp, undetected, optimize, use_proxy, pipeline_id=program_id
|
87
88
|
)["code"]
|
88
89
|
start_time = datetime.datetime.now(datetime.timezone.utc).isoformat()
|
89
90
|
run_data = {"start_time": start_time}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: parsagon
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.17.0
|
4
4
|
Summary: Allows you to create browser automations with natural language
|
5
5
|
Author-email: Sandy Suh <sandy@parsagon.io>
|
6
6
|
Project-URL: Homepage, https://parsagon.io
|
@@ -8,15 +8,14 @@ Classifier: Programming Language :: Python :: 3
|
|
8
8
|
Classifier: Operating System :: OS Independent
|
9
9
|
Requires-Python: >=3.8
|
10
10
|
Description-Content-Type: text/markdown
|
11
|
-
Requires-Dist:
|
12
|
-
Requires-Dist: selenium>=4.9.1
|
11
|
+
Requires-Dist: selenium==4.9.1
|
13
12
|
Requires-Dist: lxml[html_clean]==5.3.2
|
14
13
|
Requires-Dist: httpx>=0.27.0
|
15
14
|
Requires-Dist: psutil==7.0.0
|
16
|
-
Requires-Dist: rich
|
15
|
+
Requires-Dist: rich==13.6.0
|
17
16
|
Requires-Dist: PyVirtualDisplay==3.0
|
18
17
|
Requires-Dist: selenium-wire==5.1.0
|
19
|
-
Requires-Dist: cssselect
|
18
|
+
Requires-Dist: cssselect==1.2.0
|
20
19
|
Requires-Dist: undetected-chromedriver==3.5.5
|
21
20
|
Requires-Dist: webdriver-manager==4.0.2
|
22
21
|
Requires-Dist: jsonpath-ng==1.5.3
|
@@ -1,16 +1,16 @@
|
|
1
1
|
parsagon/__init__.py,sha256=_S5MlYHBViB4iY96_UbGo3mfGndE8MmFmb1EORJppK8,452
|
2
|
-
parsagon/api.py,sha256=
|
2
|
+
parsagon/api.py,sha256=8ZaJfx1Jnf18rFWhydcdRPswnddgDsc8UqTLIctMR0g,10565
|
3
3
|
parsagon/assistant.py,sha256=V3NL6UdDqe74W_X3wPQ1qwFuJRvHzitXtOt-XSCXvds,4065
|
4
4
|
parsagon/create.py,sha256=BERrBviwMvifg5OwApqdanvULJHHk39fIvnTCZN3Xkk,4432
|
5
5
|
parsagon/custom_function.py,sha256=oEj28qItaHUnsvLIHD7kg5QL3J3aO6rW6xKKP-H-Drs,770
|
6
6
|
parsagon/edit.py,sha256=5gtnx0gNB7Gvz8ET00SczE-ZS0TomN1um6uObP-OObE,3120
|
7
7
|
parsagon/exceptions.py,sha256=tG1vnpmUN1GdJ1GSpe1MaWH3zWmFLZCwtOfEGu8qPP0,910
|
8
|
-
parsagon/executor.py,sha256=
|
8
|
+
parsagon/executor.py,sha256=_jPdLxclmLekb03JCtxvslRpfUhVotL6rnHFw9EibXE,29927
|
9
9
|
parsagon/gui_entry.py,sha256=bqG9K0CArXWWwDGoT8aV17YLNM8MfjSf6SJ_B3QbNeA,671
|
10
10
|
parsagon/highlights.js,sha256=2UDfUApblU9xtGgTLCq4X7rHRV0wcqDSSFZPmJS6fJg,16643
|
11
|
-
parsagon/main.py,sha256=
|
11
|
+
parsagon/main.py,sha256=_ww08Fpf1S8ePXSDg2GqtmnQvdfSgMK_AiNq5CuhWko,10001
|
12
12
|
parsagon/print.py,sha256=-7iVKil0W9e8zX1EJMcdlqNdfpmfPxKTBtZfwzWpGYU,4106
|
13
|
-
parsagon/runs.py,sha256=
|
13
|
+
parsagon/runs.py,sha256=VDvWpg3x6D67jNSffimeL7rxQy8rycsys0kjV0fNWRU,8661
|
14
14
|
parsagon/secrets.py,sha256=72dr-6q1q2ATBkE75fT18tcvwDM-4nymTb9NDVwjHTE,545
|
15
15
|
parsagon/settings.py,sha256=ejd9wGCOEB68n8a0M2SyzlmlwPofnzMKaxpBqYhcs34,3552
|
16
16
|
parsagon/gui/__init__.py,sha256=ZvKZfcchSnBh__UY_XeMnQJACd1EG99ix3_SfSHth8g,68
|
@@ -25,8 +25,8 @@ parsagon/tests/test_invalid_args.py,sha256=TAFdHGy92lUxjljPrtODOuEGVss6rn-F5GvEK
|
|
25
25
|
parsagon/tests/test_pipeline_operations.py,sha256=aEwZNtIwOl9X7jdLDLB4YEdgMp7_x8PXCINAE7RT4NY,805
|
26
26
|
parsagon/tests/test_print.py,sha256=BG7f55YDBoL0S7k291-so_Gje_hUAQOkB-jh-bEYsJY,198
|
27
27
|
parsagon/tests/test_secrets.py,sha256=Ctsscl2tmMTZcFAy5dnyqUlgTov2UharZgLpbRCLdEg,2662
|
28
|
-
parsagon-0.
|
29
|
-
parsagon-0.
|
30
|
-
parsagon-0.
|
31
|
-
parsagon-0.
|
32
|
-
parsagon-0.
|
28
|
+
parsagon-0.17.0.dist-info/METADATA,sha256=g9XH7RSGomls3yYMfiWQLcxv5RGBQq3zauVZR7okw0g,2567
|
29
|
+
parsagon-0.17.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
30
|
+
parsagon-0.17.0.dist-info/entry_points.txt,sha256=I1UlPUb4oY2k9idkI8kvdkEcrjKGRSOl5pMbA6uu6kw,48
|
31
|
+
parsagon-0.17.0.dist-info/top_level.txt,sha256=ih5uYQzW4qjhRKppys-WiHLIbXVZ99YdqDcfAtlcQwk,9
|
32
|
+
parsagon-0.17.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|