webcrawlerapi 2.0.7__tar.gz → 2.0.9__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.
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/PKG-INFO +3 -1
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/README.md +3 -1
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/setup.py +1 -1
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/webcrawlerapi/client.py +91 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/webcrawlerapi/models.py +2 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/webcrawlerapi.egg-info/PKG-INFO +3 -1
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/pyproject.toml +0 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/setup.cfg +0 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/tests/__init__.py +0 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/tests/test_client.py +0 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/tests/test_models.py +0 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/webcrawlerapi/__init__.py +0 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/webcrawlerapi.egg-info/SOURCES.txt +0 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/webcrawlerapi.egg-info/dependency_links.txt +0 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/webcrawlerapi.egg-info/requires.txt +0 -0
- {webcrawlerapi-2.0.7 → webcrawlerapi-2.0.9}/webcrawlerapi.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: webcrawlerapi
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.9
|
|
4
4
|
Summary: Python SDK for WebCrawler API
|
|
5
5
|
Home-page: https://github.com/webcrawlerapi/webcrawlerapi-python-sdk
|
|
6
6
|
Author: Andrew
|
|
@@ -124,6 +124,8 @@ Starts a new crawling job and waits for its completion. This method will continu
|
|
|
124
124
|
### crawl_async()
|
|
125
125
|
Starts a new crawling job and returns immediately with a job ID. Use this when you want to handle polling and status checks yourself, or when using webhooks.
|
|
126
126
|
|
|
127
|
+
Use `crawl_raw_markdown()` when you need the combined `/job/{id}/markdown` output after a crawl finishes.
|
|
128
|
+
|
|
127
129
|
### get_job()
|
|
128
130
|
Retrieves the current status and details of a specific job.
|
|
129
131
|
|
|
@@ -103,6 +103,8 @@ Starts a new crawling job and waits for its completion. This method will continu
|
|
|
103
103
|
### crawl_async()
|
|
104
104
|
Starts a new crawling job and returns immediately with a job ID. Use this when you want to handle polling and status checks yourself, or when using webhooks.
|
|
105
105
|
|
|
106
|
+
Use `crawl_raw_markdown()` when you need the combined `/job/{id}/markdown` output after a crawl finishes.
|
|
107
|
+
|
|
106
108
|
### get_job()
|
|
107
109
|
Retrieves the current status and details of a specific job.
|
|
108
110
|
|
|
@@ -181,4 +183,4 @@ Each JobItem object represents a crawled page and contains:
|
|
|
181
183
|
|
|
182
184
|
## License
|
|
183
185
|
|
|
184
|
-
MIT License
|
|
186
|
+
MIT License
|
|
@@ -50,6 +50,7 @@ class WebCrawlerAPI:
|
|
|
50
50
|
actions: Optional[Union[Action, List[Action]]] = None,
|
|
51
51
|
respect_robots_txt: bool = False,
|
|
52
52
|
main_content_only: bool = False,
|
|
53
|
+
max_depth: Optional[int] = None,
|
|
53
54
|
) -> CrawlResponse:
|
|
54
55
|
"""
|
|
55
56
|
Start a new crawling job asynchronously.
|
|
@@ -65,6 +66,7 @@ class WebCrawlerAPI:
|
|
|
65
66
|
actions (Action or List[Action], optional): Actions to perform during crawling
|
|
66
67
|
respect_robots_txt (bool): Whether to respect robots.txt file (default: False)
|
|
67
68
|
main_content_only (bool): Whether to extract only main content (default: False)
|
|
69
|
+
max_depth (int, optional): Maximum depth of crawl (0 for seed URL only, 1 for one level deep, etc.)
|
|
68
70
|
|
|
69
71
|
Returns:
|
|
70
72
|
CrawlResponse: Response containing the job ID
|
|
@@ -87,6 +89,8 @@ class WebCrawlerAPI:
|
|
|
87
89
|
payload["whitelist_regexp"] = whitelist_regexp
|
|
88
90
|
if blacklist_regexp:
|
|
89
91
|
payload["blacklist_regexp"] = blacklist_regexp
|
|
92
|
+
if max_depth is not None:
|
|
93
|
+
payload["max_depth"] = max_depth
|
|
90
94
|
if actions:
|
|
91
95
|
# Convert single action to list if needed
|
|
92
96
|
action_list = [actions] if not isinstance(actions, list) else actions
|
|
@@ -118,6 +122,42 @@ class WebCrawlerAPI:
|
|
|
118
122
|
response.raise_for_status()
|
|
119
123
|
return Job(response.json())
|
|
120
124
|
|
|
125
|
+
def get_job_markdown(self, job_id: str) -> str:
|
|
126
|
+
"""
|
|
127
|
+
Get combined markdown content for a completed markdown job.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
job_id (str): The unique identifier of the job
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
str: Combined markdown content
|
|
134
|
+
|
|
135
|
+
Raises:
|
|
136
|
+
requests.exceptions.RequestException: If the API request fails
|
|
137
|
+
"""
|
|
138
|
+
response = self.session.get(
|
|
139
|
+
urljoin(self.base_url, f"/{CRAWLER_VERSION}/job/{job_id}/markdown")
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
if not response.ok:
|
|
143
|
+
try:
|
|
144
|
+
error_payload = response.json()
|
|
145
|
+
detail = (
|
|
146
|
+
error_payload.get("message")
|
|
147
|
+
or error_payload.get("error_message")
|
|
148
|
+
or error_payload.get("error")
|
|
149
|
+
)
|
|
150
|
+
except ValueError:
|
|
151
|
+
detail = response.text
|
|
152
|
+
|
|
153
|
+
try:
|
|
154
|
+
response.raise_for_status()
|
|
155
|
+
except requests.exceptions.HTTPError as exc:
|
|
156
|
+
raise requests.exceptions.HTTPError(f"{exc}: {detail}") from exc
|
|
157
|
+
|
|
158
|
+
response.raise_for_status()
|
|
159
|
+
return response.text
|
|
160
|
+
|
|
121
161
|
def cancel_job(self, job_id: str) -> Dict[str, str]:
|
|
122
162
|
"""
|
|
123
163
|
Cancel a running job. All items that are not in progress and not done
|
|
@@ -150,6 +190,7 @@ class WebCrawlerAPI:
|
|
|
150
190
|
actions: Optional[Union[Action, List[Action]]] = None,
|
|
151
191
|
respect_robots_txt: bool = False,
|
|
152
192
|
main_content_only: bool = False,
|
|
193
|
+
max_depth: Optional[int] = None,
|
|
153
194
|
max_polls: int = 100,
|
|
154
195
|
) -> Job:
|
|
155
196
|
"""
|
|
@@ -170,6 +211,7 @@ class WebCrawlerAPI:
|
|
|
170
211
|
actions (Action or List[Action], optional): Actions to perform during crawling
|
|
171
212
|
respect_robots_txt (bool): Whether to respect robots.txt file (default: False)
|
|
172
213
|
main_content_only (bool): Whether to extract only main content (default: False)
|
|
214
|
+
max_depth (int, optional): Maximum depth of crawl (0 for seed URL only, 1 for one level deep, etc.)
|
|
173
215
|
max_polls (int): Maximum number of status checks before returning (default: 100)
|
|
174
216
|
|
|
175
217
|
Returns:
|
|
@@ -190,6 +232,7 @@ class WebCrawlerAPI:
|
|
|
190
232
|
actions=actions,
|
|
191
233
|
respect_robots_txt=respect_robots_txt,
|
|
192
234
|
main_content_only=main_content_only,
|
|
235
|
+
max_depth=max_depth,
|
|
193
236
|
)
|
|
194
237
|
|
|
195
238
|
job_id = response.id
|
|
@@ -215,6 +258,54 @@ class WebCrawlerAPI:
|
|
|
215
258
|
# Return the last known state if max_polls is reached
|
|
216
259
|
return job
|
|
217
260
|
|
|
261
|
+
def crawl_raw_markdown(
|
|
262
|
+
self,
|
|
263
|
+
url: str,
|
|
264
|
+
scrape_type: str = "markdown",
|
|
265
|
+
items_limit: int = 10,
|
|
266
|
+
webhook_url: Optional[str] = None,
|
|
267
|
+
allow_subdomains: bool = False,
|
|
268
|
+
whitelist_regexp: Optional[str] = None,
|
|
269
|
+
blacklist_regexp: Optional[str] = None,
|
|
270
|
+
actions: Optional[Union[Action, List[Action]]] = None,
|
|
271
|
+
respect_robots_txt: bool = False,
|
|
272
|
+
main_content_only: bool = False,
|
|
273
|
+
max_depth: Optional[int] = None,
|
|
274
|
+
max_polls: int = 100,
|
|
275
|
+
) -> str:
|
|
276
|
+
"""
|
|
277
|
+
Run a crawl job and return the combined markdown output when finished.
|
|
278
|
+
|
|
279
|
+
Raises:
|
|
280
|
+
requests.exceptions.RequestException: If any API request fails
|
|
281
|
+
"""
|
|
282
|
+
job = self.crawl(
|
|
283
|
+
url=url,
|
|
284
|
+
scrape_type=scrape_type,
|
|
285
|
+
items_limit=items_limit,
|
|
286
|
+
webhook_url=webhook_url,
|
|
287
|
+
allow_subdomains=allow_subdomains,
|
|
288
|
+
whitelist_regexp=whitelist_regexp,
|
|
289
|
+
blacklist_regexp=blacklist_regexp,
|
|
290
|
+
actions=actions,
|
|
291
|
+
respect_robots_txt=respect_robots_txt,
|
|
292
|
+
main_content_only=main_content_only,
|
|
293
|
+
max_depth=max_depth,
|
|
294
|
+
max_polls=max_polls,
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
if job.scrape_type != "markdown":
|
|
298
|
+
raise requests.exceptions.HTTPError(
|
|
299
|
+
"crawl_raw_markdown requires scrape_type to be markdown"
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
if job.status != "done":
|
|
303
|
+
raise requests.exceptions.HTTPError(
|
|
304
|
+
f"Job finished with status {job.status}"
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
return self.get_job_markdown(job.id)
|
|
308
|
+
|
|
218
309
|
def scrape_async(
|
|
219
310
|
self,
|
|
220
311
|
url: str,
|
|
@@ -125,6 +125,7 @@ class JobItem:
|
|
|
125
125
|
self.referred_url: Optional[str] = data.get("referred_url")
|
|
126
126
|
self.last_error: Optional[str] = data.get("last_error")
|
|
127
127
|
self.error_code: Optional[str] = data.get("error_code")
|
|
128
|
+
self.depth: Optional[int] = data.get("depth")
|
|
128
129
|
|
|
129
130
|
# Optional content URLs based on scrape_type
|
|
130
131
|
self.raw_content_url: Optional[str] = data.get("raw_content_url")
|
|
@@ -201,6 +202,7 @@ class Job:
|
|
|
201
202
|
self.blacklist_regexp: Optional[str] = data.get("blacklist_regexp")
|
|
202
203
|
self.allow_subdomains: bool = data.get("allow_subdomains", False)
|
|
203
204
|
self.items_limit: int = data["items_limit"]
|
|
205
|
+
self.max_depth: Optional[int] = data.get("max_depth")
|
|
204
206
|
self.created_at: datetime = parse_datetime(data["created_at"])
|
|
205
207
|
self.updated_at: datetime = parse_datetime(data["updated_at"])
|
|
206
208
|
self.webhook_url: Optional[str] = data.get("webhook_url")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: webcrawlerapi
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.9
|
|
4
4
|
Summary: Python SDK for WebCrawler API
|
|
5
5
|
Home-page: https://github.com/webcrawlerapi/webcrawlerapi-python-sdk
|
|
6
6
|
Author: Andrew
|
|
@@ -124,6 +124,8 @@ Starts a new crawling job and waits for its completion. This method will continu
|
|
|
124
124
|
### crawl_async()
|
|
125
125
|
Starts a new crawling job and returns immediately with a job ID. Use this when you want to handle polling and status checks yourself, or when using webhooks.
|
|
126
126
|
|
|
127
|
+
Use `crawl_raw_markdown()` when you need the combined `/job/{id}/markdown` output after a crawl finishes.
|
|
128
|
+
|
|
127
129
|
### get_job()
|
|
128
130
|
Retrieves the current status and details of a specific job.
|
|
129
131
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|