flaresolverr-cli 0.2.0__tar.gz → 0.2.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.
- {flaresolverr_cli-0.2.0/flaresolverr_cli.egg-info → flaresolverr_cli-0.2.2}/PKG-INFO +19 -8
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/README.md +18 -7
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2/flaresolverr_cli.egg-info}/PKG-INFO +19 -8
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/flaresolverr_cli.egg-info/SOURCES.txt +5 -3
- flaresolverr_cli-0.2.2/flaresolverr_cli.egg-info/entry_points.txt +2 -0
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/flaresolverr_cli.egg-info/top_level.txt +0 -2
- flaresolverr_cli-0.2.2/flaresolverr_session/__init__.py +28 -0
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2/flaresolverr_session}/cli.py +61 -42
- flaresolverr_cli-0.2.2/flaresolverr_session/exceptions.py +36 -0
- flaresolverr_cli-0.2.0/flaresolverr_rpc.py → flaresolverr_cli-0.2.2/flaresolverr_session/rpc.py +66 -45
- flaresolverr_cli-0.2.0/flaresolverr_session.py → flaresolverr_cli-0.2.2/flaresolverr_session/session.py +76 -140
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/setup.py +7 -6
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/tests/test_cli.py +277 -56
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/tests/test_rpc.py +1 -14
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/tests/test_session.py +40 -26
- flaresolverr_cli-0.2.0/flaresolverr_cli.egg-info/entry_points.txt +0 -2
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/LICENSE +0 -0
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/flaresolverr_cli.egg-info/dependency_links.txt +0 -0
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/flaresolverr_cli.egg-info/requires.txt +0 -0
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/setup.cfg +0 -0
- {flaresolverr_cli-0.2.0 → flaresolverr_cli-0.2.2}/tests/testconf.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flaresolverr-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A requests.Session that proxies through a FlareSolverr instance.
|
|
5
5
|
Home-page: https://github.com/Xavier-Lam/FlareSolverrSession
|
|
6
6
|
Author: Xavier-Lam
|
|
@@ -109,14 +109,19 @@ A `FlareSolverr` object is attached to the `response` as `response.flaresolverr`
|
|
|
109
109
|
| `flaresolverr.version` | FlareSolverr server version |
|
|
110
110
|
|
|
111
111
|
#### Exception Handling
|
|
112
|
+
All exceptions defined in the module based on `FlareSolverrError`, which inherits from `requests.RequestException`. The inheritance hierarchy is as follows:
|
|
113
|
+
|
|
114
|
+
requests.RequestException
|
|
115
|
+
└── FlareSolverrError
|
|
116
|
+
├── FlareSolverrResponseError
|
|
117
|
+
│ ├── FlareSolverrChallengeError
|
|
118
|
+
└── FlareSolverrUnsupportedMethodError
|
|
119
|
+
|
|
112
120
|
|
|
113
121
|
| Exception | Description |
|
|
114
122
|
|---|---|
|
|
115
|
-
| `
|
|
116
|
-
| `FlareSolverrChallengeError` | Challenge
|
|
117
|
-
| `FlareSolverrCaptchaError` | CAPTCHA detected. Inherits from `FlareSolverrChallengeError`. |
|
|
118
|
-
| `FlareSolverrTimeoutError` | Request timed out. |
|
|
119
|
-
| `FlareSolverrSessionError` | Session creation/destruction failed. |
|
|
123
|
+
| `FlareSolverrResponseError` | FlareSolverr returned an error response. The response dict is available as `response_data` attribute. |
|
|
124
|
+
| `FlareSolverrChallengeError` | Challenge solving failed. |
|
|
120
125
|
| `FlareSolverrUnsupportedMethodError` | Unsupported HTTP method or content type. |
|
|
121
126
|
|
|
122
127
|
### Command-Line Interface
|
|
@@ -142,14 +147,20 @@ flaresolverr-cli https://example.com -d "key=value&foo=bar"
|
|
|
142
147
|
#### Managing sessions
|
|
143
148
|
|
|
144
149
|
```bash
|
|
145
|
-
# Create a session
|
|
150
|
+
# Create a session
|
|
146
151
|
flaresolverr-cli -f http://localhost:8191/v1 session create my-session
|
|
147
152
|
|
|
153
|
+
# Create multiple sessions at once
|
|
154
|
+
flaresolverr-cli session create session1 session2 session3
|
|
155
|
+
|
|
148
156
|
# List all active sessions
|
|
149
157
|
flaresolverr-cli session list
|
|
150
158
|
|
|
151
159
|
# Destroy a session
|
|
152
160
|
flaresolverr-cli session destroy my-session
|
|
161
|
+
|
|
162
|
+
# Clear all sessions
|
|
163
|
+
flaresolverr-cli session clear
|
|
153
164
|
```
|
|
154
165
|
|
|
155
166
|
### RPC Tool
|
|
@@ -157,7 +168,7 @@ flaresolverr-cli session destroy my-session
|
|
|
157
168
|
The `flaresolverr_rpc` module provides a programmatic interface to the FlareSolverr JSON API, useful when you need low-level access to the raw API responses.
|
|
158
169
|
|
|
159
170
|
```python
|
|
160
|
-
from
|
|
171
|
+
from flaresolverr_session import RPC
|
|
161
172
|
|
|
162
173
|
with RPC("http://localhost:8191/v1") as rpc:
|
|
163
174
|
# Session management
|
|
@@ -65,14 +65,19 @@ A `FlareSolverr` object is attached to the `response` as `response.flaresolverr`
|
|
|
65
65
|
| `flaresolverr.version` | FlareSolverr server version |
|
|
66
66
|
|
|
67
67
|
#### Exception Handling
|
|
68
|
+
All exceptions defined in the module based on `FlareSolverrError`, which inherits from `requests.RequestException`. The inheritance hierarchy is as follows:
|
|
69
|
+
|
|
70
|
+
requests.RequestException
|
|
71
|
+
└── FlareSolverrError
|
|
72
|
+
├── FlareSolverrResponseError
|
|
73
|
+
│ ├── FlareSolverrChallengeError
|
|
74
|
+
└── FlareSolverrUnsupportedMethodError
|
|
75
|
+
|
|
68
76
|
|
|
69
77
|
| Exception | Description |
|
|
70
78
|
|---|---|
|
|
71
|
-
| `
|
|
72
|
-
| `FlareSolverrChallengeError` | Challenge
|
|
73
|
-
| `FlareSolverrCaptchaError` | CAPTCHA detected. Inherits from `FlareSolverrChallengeError`. |
|
|
74
|
-
| `FlareSolverrTimeoutError` | Request timed out. |
|
|
75
|
-
| `FlareSolverrSessionError` | Session creation/destruction failed. |
|
|
79
|
+
| `FlareSolverrResponseError` | FlareSolverr returned an error response. The response dict is available as `response_data` attribute. |
|
|
80
|
+
| `FlareSolverrChallengeError` | Challenge solving failed. |
|
|
76
81
|
| `FlareSolverrUnsupportedMethodError` | Unsupported HTTP method or content type. |
|
|
77
82
|
|
|
78
83
|
### Command-Line Interface
|
|
@@ -98,14 +103,20 @@ flaresolverr-cli https://example.com -d "key=value&foo=bar"
|
|
|
98
103
|
#### Managing sessions
|
|
99
104
|
|
|
100
105
|
```bash
|
|
101
|
-
# Create a session
|
|
106
|
+
# Create a session
|
|
102
107
|
flaresolverr-cli -f http://localhost:8191/v1 session create my-session
|
|
103
108
|
|
|
109
|
+
# Create multiple sessions at once
|
|
110
|
+
flaresolverr-cli session create session1 session2 session3
|
|
111
|
+
|
|
104
112
|
# List all active sessions
|
|
105
113
|
flaresolverr-cli session list
|
|
106
114
|
|
|
107
115
|
# Destroy a session
|
|
108
116
|
flaresolverr-cli session destroy my-session
|
|
117
|
+
|
|
118
|
+
# Clear all sessions
|
|
119
|
+
flaresolverr-cli session clear
|
|
109
120
|
```
|
|
110
121
|
|
|
111
122
|
### RPC Tool
|
|
@@ -113,7 +124,7 @@ flaresolverr-cli session destroy my-session
|
|
|
113
124
|
The `flaresolverr_rpc` module provides a programmatic interface to the FlareSolverr JSON API, useful when you need low-level access to the raw API responses.
|
|
114
125
|
|
|
115
126
|
```python
|
|
116
|
-
from
|
|
127
|
+
from flaresolverr_session import RPC
|
|
117
128
|
|
|
118
129
|
with RPC("http://localhost:8191/v1") as rpc:
|
|
119
130
|
# Session management
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flaresolverr-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A requests.Session that proxies through a FlareSolverr instance.
|
|
5
5
|
Home-page: https://github.com/Xavier-Lam/FlareSolverrSession
|
|
6
6
|
Author: Xavier-Lam
|
|
@@ -109,14 +109,19 @@ A `FlareSolverr` object is attached to the `response` as `response.flaresolverr`
|
|
|
109
109
|
| `flaresolverr.version` | FlareSolverr server version |
|
|
110
110
|
|
|
111
111
|
#### Exception Handling
|
|
112
|
+
All exceptions defined in the module based on `FlareSolverrError`, which inherits from `requests.RequestException`. The inheritance hierarchy is as follows:
|
|
113
|
+
|
|
114
|
+
requests.RequestException
|
|
115
|
+
└── FlareSolverrError
|
|
116
|
+
├── FlareSolverrResponseError
|
|
117
|
+
│ ├── FlareSolverrChallengeError
|
|
118
|
+
└── FlareSolverrUnsupportedMethodError
|
|
119
|
+
|
|
112
120
|
|
|
113
121
|
| Exception | Description |
|
|
114
122
|
|---|---|
|
|
115
|
-
| `
|
|
116
|
-
| `FlareSolverrChallengeError` | Challenge
|
|
117
|
-
| `FlareSolverrCaptchaError` | CAPTCHA detected. Inherits from `FlareSolverrChallengeError`. |
|
|
118
|
-
| `FlareSolverrTimeoutError` | Request timed out. |
|
|
119
|
-
| `FlareSolverrSessionError` | Session creation/destruction failed. |
|
|
123
|
+
| `FlareSolverrResponseError` | FlareSolverr returned an error response. The response dict is available as `response_data` attribute. |
|
|
124
|
+
| `FlareSolverrChallengeError` | Challenge solving failed. |
|
|
120
125
|
| `FlareSolverrUnsupportedMethodError` | Unsupported HTTP method or content type. |
|
|
121
126
|
|
|
122
127
|
### Command-Line Interface
|
|
@@ -142,14 +147,20 @@ flaresolverr-cli https://example.com -d "key=value&foo=bar"
|
|
|
142
147
|
#### Managing sessions
|
|
143
148
|
|
|
144
149
|
```bash
|
|
145
|
-
# Create a session
|
|
150
|
+
# Create a session
|
|
146
151
|
flaresolverr-cli -f http://localhost:8191/v1 session create my-session
|
|
147
152
|
|
|
153
|
+
# Create multiple sessions at once
|
|
154
|
+
flaresolverr-cli session create session1 session2 session3
|
|
155
|
+
|
|
148
156
|
# List all active sessions
|
|
149
157
|
flaresolverr-cli session list
|
|
150
158
|
|
|
151
159
|
# Destroy a session
|
|
152
160
|
flaresolverr-cli session destroy my-session
|
|
161
|
+
|
|
162
|
+
# Clear all sessions
|
|
163
|
+
flaresolverr-cli session clear
|
|
153
164
|
```
|
|
154
165
|
|
|
155
166
|
### RPC Tool
|
|
@@ -157,7 +168,7 @@ flaresolverr-cli session destroy my-session
|
|
|
157
168
|
The `flaresolverr_rpc` module provides a programmatic interface to the FlareSolverr JSON API, useful when you need low-level access to the raw API responses.
|
|
158
169
|
|
|
159
170
|
```python
|
|
160
|
-
from
|
|
171
|
+
from flaresolverr_session import RPC
|
|
161
172
|
|
|
162
173
|
with RPC("http://localhost:8191/v1") as rpc:
|
|
163
174
|
# Session management
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
LICENSE
|
|
2
2
|
README.md
|
|
3
|
-
cli.py
|
|
4
|
-
flaresolverr_rpc.py
|
|
5
|
-
flaresolverr_session.py
|
|
6
3
|
setup.py
|
|
7
4
|
flaresolverr_cli.egg-info/PKG-INFO
|
|
8
5
|
flaresolverr_cli.egg-info/SOURCES.txt
|
|
@@ -10,6 +7,11 @@ flaresolverr_cli.egg-info/dependency_links.txt
|
|
|
10
7
|
flaresolverr_cli.egg-info/entry_points.txt
|
|
11
8
|
flaresolverr_cli.egg-info/requires.txt
|
|
12
9
|
flaresolverr_cli.egg-info/top_level.txt
|
|
10
|
+
flaresolverr_session/__init__.py
|
|
11
|
+
flaresolverr_session/cli.py
|
|
12
|
+
flaresolverr_session/exceptions.py
|
|
13
|
+
flaresolverr_session/rpc.py
|
|
14
|
+
flaresolverr_session/session.py
|
|
13
15
|
tests/test_cli.py
|
|
14
16
|
tests/test_rpc.py
|
|
15
17
|
tests/test_session.py
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from flaresolverr_session.exceptions import (
|
|
4
|
+
FlareSolverrError,
|
|
5
|
+
FlareSolverrResponseError,
|
|
6
|
+
FlareSolverrChallengeError,
|
|
7
|
+
FlareSolverrUnsupportedMethodError,
|
|
8
|
+
)
|
|
9
|
+
from flaresolverr_session.rpc import RPC
|
|
10
|
+
from flaresolverr_session.session import Session, Response
|
|
11
|
+
|
|
12
|
+
__title__ = "flaresolverr-session"
|
|
13
|
+
__description__ = "A requests.Session that proxies through a FlareSolverr instance."
|
|
14
|
+
__url__ = "https://github.com/Xavier-Lam/FlareSolverrSession"
|
|
15
|
+
__version__ = "0.2.2"
|
|
16
|
+
__author__ = "Xavier-Lam"
|
|
17
|
+
__author_email__ = "xavierlam7@hotmail.com"
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"Session",
|
|
21
|
+
"Response",
|
|
22
|
+
"RPC",
|
|
23
|
+
"FlareSolverrError",
|
|
24
|
+
"FlareSolverrResponseError",
|
|
25
|
+
"FlareSolverrChallengeError",
|
|
26
|
+
"FlareSolverrUnsupportedMethodError",
|
|
27
|
+
"__version__",
|
|
28
|
+
]
|
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
from __future__ import print_function
|
|
5
5
|
|
|
6
6
|
import argparse
|
|
7
|
+
import base64
|
|
7
8
|
import json
|
|
8
9
|
import os
|
|
9
10
|
import sys
|
|
10
11
|
|
|
11
|
-
from
|
|
12
|
+
from flaresolverr_session.rpc import RPC
|
|
13
|
+
from flaresolverr_session.exceptions import FlareSolverrResponseError
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
def main(argv=None):
|
|
@@ -25,29 +27,33 @@ def main(argv=None):
|
|
|
25
27
|
first_args, remaining = main_parser.parse_known_args(argv)
|
|
26
28
|
command = first_args.command
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
try:
|
|
31
|
+
if command == "session":
|
|
32
|
+
parser = _build_session_parser()
|
|
33
|
+
args = parser.parse_args([command] + remaining)
|
|
34
|
+
rpc = RPC(first_args.flaresolverr_url)
|
|
35
|
+
res = _handle_session(rpc, args)
|
|
36
|
+
format_output(res)
|
|
37
|
+
return 0
|
|
38
|
+
|
|
39
|
+
if command == "request":
|
|
40
|
+
request_argv = remaining
|
|
41
|
+
elif command is not None:
|
|
42
|
+
request_argv = [command] + remaining
|
|
43
|
+
else:
|
|
44
|
+
main_parser.print_help()
|
|
45
|
+
return 0
|
|
35
46
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
req_parser = _build_request_parser()
|
|
48
|
+
args = req_parser.parse_args(request_argv)
|
|
49
|
+
rpc = RPC(first_args.flaresolverr_url)
|
|
50
|
+
res = _handle_request(rpc, args)
|
|
51
|
+
_truncate_response_body(res)
|
|
52
|
+
format_output(res)
|
|
42
53
|
return 0
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
rpc = RPC(first_args.flaresolverr_url)
|
|
47
|
-
res = _handle_request(rpc, args)
|
|
48
|
-
_truncate_response_body(res)
|
|
49
|
-
_format_output(res)
|
|
50
|
-
return 0
|
|
54
|
+
except FlareSolverrResponseError as exc:
|
|
55
|
+
format_output(exc.response_data, file=sys.stderr)
|
|
56
|
+
return 1
|
|
51
57
|
|
|
52
58
|
|
|
53
59
|
def _build_main_parser():
|
|
@@ -95,9 +101,8 @@ def _build_session_parser():
|
|
|
95
101
|
create_parser = session_sub.add_parser("create", help="Create a session")
|
|
96
102
|
create_parser.add_argument(
|
|
97
103
|
"name",
|
|
98
|
-
nargs="
|
|
99
|
-
|
|
100
|
-
help="Optional session name",
|
|
104
|
+
nargs="+",
|
|
105
|
+
help="One or more session names to create",
|
|
101
106
|
)
|
|
102
107
|
create_parser.add_argument(
|
|
103
108
|
"--proxy",
|
|
@@ -115,6 +120,9 @@ def _build_session_parser():
|
|
|
115
120
|
help="Session identifier to destroy",
|
|
116
121
|
)
|
|
117
122
|
|
|
123
|
+
# session clear
|
|
124
|
+
session_sub.add_parser("clear", help="Destroy all sessions")
|
|
125
|
+
|
|
118
126
|
return parser
|
|
119
127
|
|
|
120
128
|
|
|
@@ -181,11 +189,10 @@ def _build_request_parser():
|
|
|
181
189
|
help="Return only cookies, omitting the response body",
|
|
182
190
|
)
|
|
183
191
|
parser.add_argument(
|
|
184
|
-
"--
|
|
185
|
-
dest="
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
help="Include a Base64 PNG screenshot in the response",
|
|
192
|
+
"--screenshot",
|
|
193
|
+
dest="screenshot",
|
|
194
|
+
default=None,
|
|
195
|
+
help="Write PNG screenshot of the final rendered page after all challenges and waits are completed to given path",
|
|
189
196
|
)
|
|
190
197
|
parser.add_argument(
|
|
191
198
|
"--wait",
|
|
@@ -208,14 +215,16 @@ def _handle_session(rpc, args):
|
|
|
208
215
|
action = args.session_action
|
|
209
216
|
|
|
210
217
|
if action == "create":
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
)
|
|
218
|
+
names = getattr(args, "name", None)
|
|
219
|
+
proxy = getattr(args, "proxy", None)
|
|
220
|
+
return [rpc.session.create(session_id=n, proxy=proxy) for n in names]
|
|
215
221
|
elif action == "list":
|
|
216
222
|
return rpc.session.list()
|
|
217
223
|
elif action == "destroy":
|
|
218
224
|
return rpc.session.destroy(args.session_id)
|
|
225
|
+
elif action == "clear":
|
|
226
|
+
payload = rpc.session.list()
|
|
227
|
+
return [rpc.session.destroy(s) for s in payload["sessions"]]
|
|
219
228
|
else:
|
|
220
229
|
raise ValueError("Unknown session action: %s" % action)
|
|
221
230
|
|
|
@@ -247,7 +256,8 @@ def _handle_request(rpc, args):
|
|
|
247
256
|
kwargs["session_ttl_minutes"] = session_ttl_minutes
|
|
248
257
|
if getattr(args, "return_only_cookies", False):
|
|
249
258
|
kwargs["return_only_cookies"] = True
|
|
250
|
-
|
|
259
|
+
screenshot_path = getattr(args, "screenshot", None)
|
|
260
|
+
if screenshot_path:
|
|
251
261
|
kwargs["return_screenshot"] = True
|
|
252
262
|
wait_in_seconds = getattr(args, "wait_in_seconds", None)
|
|
253
263
|
if wait_in_seconds is not None:
|
|
@@ -271,21 +281,30 @@ def _handle_request(rpc, args):
|
|
|
271
281
|
with open(output_file, "wb") as f:
|
|
272
282
|
f.write(content)
|
|
273
283
|
|
|
284
|
+
# Write screenshot to file if requested
|
|
285
|
+
if screenshot_path:
|
|
286
|
+
screenshot_b64 = result["solution"]["screenshot"]
|
|
287
|
+
data = base64.b64decode(screenshot_b64)
|
|
288
|
+
with open(screenshot_path, "wb") as f:
|
|
289
|
+
f.write(data)
|
|
290
|
+
|
|
274
291
|
return result
|
|
275
292
|
|
|
276
293
|
|
|
277
294
|
def _truncate_response_body(data, max_length=200):
|
|
278
|
-
solution = data
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
body = solution.get("response", "")
|
|
282
|
-
if body and len(body) > max_length:
|
|
295
|
+
solution = data["solution"]
|
|
296
|
+
body = solution["response"]
|
|
297
|
+
if len(body) > max_length:
|
|
283
298
|
solution["response"] = body[:max_length] + "...[%d letters]" % len(body)
|
|
299
|
+
if solution.get("screenshot"):
|
|
300
|
+
solution["screenshot"] = "[%d bytes of PNG data]" % len(solution["screenshot"])
|
|
284
301
|
return data
|
|
285
302
|
|
|
286
303
|
|
|
287
|
-
def
|
|
288
|
-
|
|
304
|
+
def format_output(data, file=None):
|
|
305
|
+
if file is None:
|
|
306
|
+
file = sys.stdout
|
|
307
|
+
print(json.dumps(data, indent=2), file=file)
|
|
289
308
|
|
|
290
309
|
|
|
291
310
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"FlareSolverrError",
|
|
7
|
+
"FlareSolverrResponseError",
|
|
8
|
+
"FlareSolverrChallengeError",
|
|
9
|
+
"FlareSolverrUnsupportedMethodError",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class FlareSolverrError(requests.RequestException):
|
|
14
|
+
"""Base exception for FlareSolverr errors."""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class FlareSolverrResponseError(FlareSolverrError):
|
|
18
|
+
"""Raised when FlareSolverr returns a non-ok response.
|
|
19
|
+
|
|
20
|
+
Attributes:
|
|
21
|
+
message (str): The error message from FlareSolverr.
|
|
22
|
+
response_data (dict or None): The original FlareSolverr response dict.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, message, response_data=None, **kwargs):
|
|
26
|
+
super(FlareSolverrResponseError, self).__init__(message, **kwargs)
|
|
27
|
+
self.message = message or ""
|
|
28
|
+
self.response_data = response_data
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class FlareSolverrChallengeError(FlareSolverrResponseError):
|
|
32
|
+
"""Raised when a challenge could not be solved."""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class FlareSolverrUnsupportedMethodError(FlareSolverrError):
|
|
36
|
+
"""Raised when an unsupported HTTP method or content type is used."""
|
flaresolverr_cli-0.2.0/flaresolverr_rpc.py → flaresolverr_cli-0.2.2/flaresolverr_session/rpc.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
from __future__ import print_function
|
|
3
3
|
|
|
4
|
+
import json
|
|
4
5
|
import os
|
|
5
6
|
|
|
6
7
|
try:
|
|
@@ -10,10 +11,69 @@ except ImportError:
|
|
|
10
11
|
|
|
11
12
|
import requests
|
|
12
13
|
|
|
13
|
-
from flaresolverr_session import
|
|
14
|
+
from flaresolverr_session.exceptions import FlareSolverrError, FlareSolverrResponseError
|
|
14
15
|
|
|
16
|
+
__all__ = [
|
|
17
|
+
"RPC",
|
|
18
|
+
"SessionCommand",
|
|
19
|
+
"RequestCommand",
|
|
20
|
+
"FlareSolverrError",
|
|
21
|
+
"FlareSolverrResponseError",
|
|
22
|
+
]
|
|
15
23
|
|
|
16
|
-
|
|
24
|
+
|
|
25
|
+
class RPC(object):
|
|
26
|
+
"""RPC client for FlareSolverr.
|
|
27
|
+
|
|
28
|
+
Provides two sub-command namespaces:
|
|
29
|
+
|
|
30
|
+
- :attr:`session` -- :class:`SessionCommand` for session management.
|
|
31
|
+
- :attr:`request` -- :class:`RequestCommand` for HTTP requests.
|
|
32
|
+
|
|
33
|
+
Parameters:
|
|
34
|
+
flaresolverr_url (str): The FlareSolverr API endpoint
|
|
35
|
+
(e.g. ``"http://localhost:8191/v1"``).
|
|
36
|
+
api_session (requests.Session or None): An optional pre-configured
|
|
37
|
+
session to use for API calls.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, flaresolverr_url=None, api_session=None):
|
|
41
|
+
if flaresolverr_url is None:
|
|
42
|
+
flaresolverr_url = os.environ.get(
|
|
43
|
+
"FLARESOLVERR_URL", "http://localhost:8191/v1"
|
|
44
|
+
)
|
|
45
|
+
if api_session is None:
|
|
46
|
+
api_session = requests.Session()
|
|
47
|
+
|
|
48
|
+
self._flaresolverr_url = flaresolverr_url
|
|
49
|
+
self._api_session = api_session
|
|
50
|
+
self.session = SessionCommand(self)
|
|
51
|
+
self.request = RequestCommand(self)
|
|
52
|
+
|
|
53
|
+
def send(self, payload):
|
|
54
|
+
"""Send a JSON payload to the FlareSolverr endpoint.
|
|
55
|
+
|
|
56
|
+
Parameters:
|
|
57
|
+
payload (dict): The JSON-serialisable payload to send.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
dict: The parsed JSON response from FlareSolverr.
|
|
61
|
+
|
|
62
|
+
Raises:
|
|
63
|
+
FlareSolverrResponseError: If the response status is
|
|
64
|
+
not ``"ok"``.
|
|
65
|
+
"""
|
|
66
|
+
headers = {"Content-Type": "application/json"}
|
|
67
|
+
resp = self._api_session.post(
|
|
68
|
+
self._flaresolverr_url,
|
|
69
|
+
headers=headers,
|
|
70
|
+
data=json.dumps(payload),
|
|
71
|
+
)
|
|
72
|
+
data = resp.json()
|
|
73
|
+
status = data.get("status", "")
|
|
74
|
+
if status != "ok":
|
|
75
|
+
raise FlareSolverrResponseError(data.get("message"), data, response=resp)
|
|
76
|
+
return data
|
|
17
77
|
|
|
18
78
|
|
|
19
79
|
class SessionCommand(object):
|
|
@@ -59,7 +119,7 @@ class SessionCommand(object):
|
|
|
59
119
|
payload["proxy"] = proxy
|
|
60
120
|
else:
|
|
61
121
|
payload["proxy"] = {"url": proxy}
|
|
62
|
-
return self._rpc.
|
|
122
|
+
return self._rpc.send(payload)
|
|
63
123
|
|
|
64
124
|
def list(self):
|
|
65
125
|
"""List all active FlareSolverr browser sessions.
|
|
@@ -78,7 +138,7 @@ class SessionCommand(object):
|
|
|
78
138
|
timestamp (ms).
|
|
79
139
|
"""
|
|
80
140
|
payload = {"cmd": "sessions.list"}
|
|
81
|
-
return self._rpc.
|
|
141
|
+
return self._rpc.send(payload)
|
|
82
142
|
|
|
83
143
|
def destroy(self, session_id):
|
|
84
144
|
"""Destroy an existing FlareSolverr browser session.
|
|
@@ -102,7 +162,7 @@ class SessionCommand(object):
|
|
|
102
162
|
"cmd": "sessions.destroy",
|
|
103
163
|
"session": session_id,
|
|
104
164
|
}
|
|
105
|
-
return self._rpc.
|
|
165
|
+
return self._rpc.send(payload)
|
|
106
166
|
|
|
107
167
|
|
|
108
168
|
class RequestCommand(object):
|
|
@@ -344,43 +404,4 @@ class RequestCommand(object):
|
|
|
344
404
|
elif cmd == "request.post":
|
|
345
405
|
# FlareSolverr requires postData for request.post; send empty string
|
|
346
406
|
payload["postData"] = ""
|
|
347
|
-
return self._rpc.
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
class RPC(object):
|
|
351
|
-
"""RPC client for FlareSolverr.
|
|
352
|
-
|
|
353
|
-
Provides two sub-command namespaces:
|
|
354
|
-
|
|
355
|
-
- :attr:`session` -- :class:`SessionCommand` for session management.
|
|
356
|
-
- :attr:`request` -- :class:`RequestCommand` for HTTP requests.
|
|
357
|
-
|
|
358
|
-
The underlying transport reuses
|
|
359
|
-
:meth:`flaresolverr_session.Session.send`, which is the same
|
|
360
|
-
low-level method used by the high-level
|
|
361
|
-
:class:`~flaresolverr_session.Session`.
|
|
362
|
-
|
|
363
|
-
Parameters:
|
|
364
|
-
flaresolverr_url (str): The FlareSolverr API endpoint
|
|
365
|
-
(e.g. ``"http://localhost:8191/v1"``).
|
|
366
|
-
api_session (requests.Session or None): An optional pre-configured
|
|
367
|
-
session to use for API calls.
|
|
368
|
-
"""
|
|
369
|
-
|
|
370
|
-
def __init__(self, flaresolverr_url=None, api_session=None):
|
|
371
|
-
if flaresolverr_url is None:
|
|
372
|
-
flaresolverr_url = os.environ.get(
|
|
373
|
-
"FLARESOLVERR_URL", "http://localhost:8191/v1"
|
|
374
|
-
)
|
|
375
|
-
if api_session is None:
|
|
376
|
-
api_session = requests.Session()
|
|
377
|
-
|
|
378
|
-
self._session = Session(flaresolverr_url, session=api_session)
|
|
379
|
-
self.session = SessionCommand(self)
|
|
380
|
-
self.request = RequestCommand(self)
|
|
381
|
-
|
|
382
|
-
def __enter__(self):
|
|
383
|
-
return self
|
|
384
|
-
|
|
385
|
-
def __exit__(self, *args):
|
|
386
|
-
pass
|
|
407
|
+
return self._rpc.send(payload)
|