yad2-scraper 0.5.1__py3-none-any.whl → 0.5.3__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.
- yad2_scraper/exceptions.py +0 -3
- yad2_scraper/next_data.py +1 -0
- yad2_scraper/query.py +1 -0
- yad2_scraper/vehicles/category.py +4 -2
- yad2_scraper/vehicles/next_data.py +9 -5
- yad2_scraper/vehicles/query.py +1 -0
- {yad2_scraper-0.5.1.dist-info → yad2_scraper-0.5.3.dist-info}/METADATA +14 -13
- yad2_scraper-0.5.3.dist-info/RECORD +18 -0
- {yad2_scraper-0.5.1.dist-info → yad2_scraper-0.5.3.dist-info}/WHEEL +1 -1
- yad2_scraper-0.5.1.dist-info/RECORD +0 -18
- {yad2_scraper-0.5.1.dist-info → yad2_scraper-0.5.3.dist-info}/LICENSE +0 -0
yad2_scraper/exceptions.py
CHANGED
@@ -6,7 +6,6 @@ class ResponseError(Exception):
|
|
6
6
|
"""Represents an error response from an HTTP request."""
|
7
7
|
|
8
8
|
def __init__(self, msg: str, request: httpx.Request, response: httpx.Response):
|
9
|
-
"""Initialize with an error message, request, and response objects."""
|
10
9
|
super().__init__(msg)
|
11
10
|
self.request = request
|
12
11
|
self.response = response
|
@@ -26,7 +25,6 @@ class MaxAttemptsExceededError(Exception):
|
|
26
25
|
"""Raised when the maximum number of attempts is exceeded."""
|
27
26
|
|
28
27
|
def __init__(self, msg: str, max_attempts: int, errors: List[BaseException] = None):
|
29
|
-
"""Initialize with an error message, max attempts, and optional errors."""
|
30
28
|
super().__init__(msg)
|
31
29
|
self.max_attempts = max_attempts
|
32
30
|
self.errors = errors
|
@@ -36,7 +34,6 @@ class MaxRequestAttemptsExceededError(MaxAttemptsExceededError):
|
|
36
34
|
"""Raised when all HTTP request attempts fail."""
|
37
35
|
|
38
36
|
def __init__(self, method: str, url: str, max_attempts: int, errors: List[Union[httpx.HTTPError, ResponseError]]):
|
39
|
-
"""Initialize with request method, URL, max attempts, and error list."""
|
40
37
|
msg = f"All {max_attempts} attempts for {method} request to '{url}' have failed"
|
41
38
|
super().__init__(msg, max_attempts, errors)
|
42
39
|
self.method = method
|
yad2_scraper/next_data.py
CHANGED
yad2_scraper/query.py
CHANGED
@@ -6,8 +6,10 @@ from yad2_scraper.vehicles.next_data import VehiclesNextData
|
|
6
6
|
|
7
7
|
|
8
8
|
class Yad2VehiclesCategory(Yad2Category):
|
9
|
-
|
10
|
-
|
9
|
+
"""Represents a Yad2 vehicles category parsed from an HTML page."""
|
10
|
+
|
11
|
+
def get_tags(self) -> List[VehicleTag]:
|
12
|
+
"""Retrieve and return a list of tags from the current vehicle page."""
|
11
13
|
tags = self.find_all_tags_by_class_substring("div", "feedItemBox")
|
12
14
|
return [VehicleTag(tag) for tag in tags]
|
13
15
|
|
@@ -14,7 +14,7 @@ from yad2_scraper.vehicles.urls import VEHICLES_URL
|
|
14
14
|
|
15
15
|
|
16
16
|
class VehicleData(metaclass=SafeAccessOptionalKeysMeta):
|
17
|
-
"""Represents
|
17
|
+
"""Represents the data for a single vehicle."""
|
18
18
|
|
19
19
|
def __init__(self, data: dict):
|
20
20
|
self.data = data
|
@@ -305,7 +305,12 @@ class VehicleData(metaclass=SafeAccessOptionalKeysMeta):
|
|
305
305
|
|
306
306
|
|
307
307
|
class VehiclesNextData(NextData):
|
308
|
-
|
308
|
+
"""Represents structured Next.js data of a specific vehicle category."""
|
309
|
+
|
310
|
+
def get_data(self) -> List[VehicleData]:
|
311
|
+
"""Extract and return a list of vehicle-data objects from the stored queries."""
|
312
|
+
data_list = []
|
313
|
+
|
309
314
|
for query in self.queries:
|
310
315
|
data = query["state"].get("data")
|
311
316
|
|
@@ -314,7 +319,6 @@ class VehiclesNextData(NextData):
|
|
314
319
|
|
315
320
|
for vehicle_data in itertools.chain.from_iterable(data.values()):
|
316
321
|
if isinstance(vehicle_data, dict):
|
317
|
-
|
322
|
+
data_list.append(VehicleData(vehicle_data))
|
318
323
|
|
319
|
-
|
320
|
-
return self.data[item]
|
324
|
+
return data_list
|
yad2_scraper/vehicles/query.py
CHANGED
@@ -5,6 +5,7 @@ from yad2_scraper.query import QueryFilters, OrderBy, NumberRange, format_number
|
|
5
5
|
|
6
6
|
|
7
7
|
class OrderVehiclesBy(int, Enum):
|
8
|
+
"""Enum representing different order options for sorting vehicles."""
|
8
9
|
DATE = OrderBy.DATE
|
9
10
|
PRICE_LOWEST_TO_HIGHEST = OrderBy.PRICE_LOWEST_TO_HIGHEST
|
10
11
|
PRICE_HIGHEST_TO_LOWEST = OrderBy.PRICE_HIGHEST_TO_LOWEST
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: yad2-scraper
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.3
|
4
4
|
Summary: Scrape Yad2 in Python.
|
5
5
|
License: LICENSE
|
6
6
|
Author: dav ost
|
@@ -59,9 +59,9 @@ To fetch any category, use the `fetch_category` function:
|
|
59
59
|
from yad2_scraper import fetch_category, Yad2Category
|
60
60
|
|
61
61
|
# Fetch real estate category (returns a generic Yad2Category object)
|
62
|
-
|
62
|
+
real_estate_page1 = fetch_category("https://www.yad2.co.il/realestate/forsale", page=1)
|
63
63
|
...
|
64
|
-
|
64
|
+
real_estate_page2 = fetch_category("https://www.yad2.co.il/realestate/forsale", page=2)
|
65
65
|
...
|
66
66
|
```
|
67
67
|
|
@@ -75,21 +75,21 @@ from yad2_scraper import fetch_vehicle_category, OrderVehiclesBy, Field
|
|
75
75
|
# Fetch cars category
|
76
76
|
cars_category = fetch_vehicle_category("cars")
|
77
77
|
|
78
|
-
for car_data in cars_category.load_next_data().
|
78
|
+
for car_data in cars_category.load_next_data().get_data():
|
79
79
|
print(car_data.model(Field.ENGLISH_TEXT))
|
80
80
|
print(car_data.test_date)
|
81
81
|
print(car_data.price)
|
82
82
|
...
|
83
83
|
|
84
84
|
# Fetch motorcycles category
|
85
|
-
|
85
|
+
motorcycle_category = fetch_vehicle_category(
|
86
86
|
"motorcycles",
|
87
87
|
price_range=(5000, 15000),
|
88
88
|
year_range=(2010, 2020),
|
89
89
|
order_by=OrderVehiclesBy.PRICE_LOWEST_TO_HIGHEST
|
90
90
|
)
|
91
91
|
|
92
|
-
for motorcycle_tag in
|
92
|
+
for motorcycle_tag in motorcycle_category.get_tags():
|
93
93
|
print(motorcycle_tag.page_link)
|
94
94
|
print(motorcycle_tag.hand)
|
95
95
|
print(motorcycle_tag.price)
|
@@ -129,22 +129,23 @@ from yad2_scraper.vehicles import (
|
|
129
129
|
get_vehicle_category_url
|
130
130
|
)
|
131
131
|
|
132
|
-
|
133
|
-
|
132
|
+
scraper = Yad2Scraper(request_defaults={"timeout": 5}, max_request_attempts=3)
|
133
|
+
|
134
|
+
# Fetch businesses-for-sale category with filters
|
134
135
|
url = "https://www.yad2.co.il/products/businesses-for-sale"
|
135
136
|
query_filters = QueryFilters(price_range=(10000, 250000), order_by=OrderBy.PRICE_LOWEST_TO_HIGHEST)
|
136
|
-
|
137
|
+
businesses_for_sale_category = scraper.fetch_category(url, Yad2Category, params=query_filters)
|
137
138
|
|
138
|
-
# Fetch watercraft
|
139
|
+
# Fetch watercraft category with filters
|
139
140
|
url = get_vehicle_category_url("watercraft")
|
140
141
|
query_filters = VehiclesQueryFilters(year_range=(2010, 2020), order_by=OrderVehiclesBy.DATE)
|
141
142
|
watercraft_category = scraper.fetch_category(url, Yad2VehiclesCategory, params=query_filters)
|
142
143
|
```
|
143
144
|
|
144
|
-
####
|
145
|
+
#### Features & Functionality
|
145
146
|
|
146
|
-
The `Yad2Scraper`
|
147
|
-
|
147
|
+
The `Yad2Scraper` class provides various attributes and methods to customize and extend its functionality.
|
148
|
+
For detailed usage and examples, refer to the code documentation.
|
148
149
|
|
149
150
|
## Contributing
|
150
151
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
yad2_scraper/__init__.py,sha256=oLANQo7jrtR5ex1tv4sM5ppaW9JpHS70Knsp0ZgVzm0,3708
|
2
|
+
yad2_scraper/category.py,sha256=SQ2eg0-fQ9hEaNryYpWVFaJqCx1d65t2_E_S3qpuw9g,1230
|
3
|
+
yad2_scraper/constants.py,sha256=8zXJ31fRqkDIOJp96BRK1PJofGXX8SG64YcfmJnVW8Q,910
|
4
|
+
yad2_scraper/exceptions.py,sha256=CC7LUy5hMQRTI48UqLZBvYJAYkVZD6n05HXeGWAIO5w,1283
|
5
|
+
yad2_scraper/next_data.py,sha256=k8Hkd_fMaAvVWHC6cizuv2osi9c_pJoKjo6mKqfJNEY,2037
|
6
|
+
yad2_scraper/query.py,sha256=6-Xc2qvHYLbejEUij85xWB4mHX3MF1XxPup9oUIkU3w,1503
|
7
|
+
yad2_scraper/scraper.py,sha256=VA-P24Gvn1y5Pkn_n3hDdpVl1aeEnLoC82eBYteAbWQ,11816
|
8
|
+
yad2_scraper/utils.py,sha256=UDpFKel_TJa0dJv1FV-CVqA8-uaFo_hDcooiFAkSZI8,1578
|
9
|
+
yad2_scraper/vehicles/__init__.py,sha256=dxjZcNv3ExnN3fKW-m1oqKiX9YC7gj8lqpIa3uWo9iI,242
|
10
|
+
yad2_scraper/vehicles/category.py,sha256=_INkTv2Svpj3zytOMANFoBAmTvzfkhdOUm0bs6HrrWI,805
|
11
|
+
yad2_scraper/vehicles/next_data.py,sha256=QHAa8AMz7NJ9r0tDVMZ0iLhhIxM2qWgnkV07t5RYjSQ,9330
|
12
|
+
yad2_scraper/vehicles/query.py,sha256=N0kA1Ci_MexPXfNpa9EUkXf8XLYOr6np9jMMMpVOlaM,986
|
13
|
+
yad2_scraper/vehicles/tag.py,sha256=Wj7v2c8IPQLYHVkfzP1UiulKKJE4yLqnbeh81nvWZhU,2052
|
14
|
+
yad2_scraper/vehicles/urls.py,sha256=zxipWjm0SXn2gGOBWw9VqKAJ59mhIGpzd_fTYitpW8c,715
|
15
|
+
yad2_scraper-0.5.3.dist-info/LICENSE,sha256=JCpnDxMx2kE40e0UQ1svSmifrLWg2Gni5VTkJR68thY,1065
|
16
|
+
yad2_scraper-0.5.3.dist-info/METADATA,sha256=X6MaY2hRMU-DO5F-bGmJUoBWOZ7doYgHdfR0_ZjnzFU,5259
|
17
|
+
yad2_scraper-0.5.3.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
18
|
+
yad2_scraper-0.5.3.dist-info/RECORD,,
|
@@ -1,18 +0,0 @@
|
|
1
|
-
yad2_scraper/__init__.py,sha256=oLANQo7jrtR5ex1tv4sM5ppaW9JpHS70Knsp0ZgVzm0,3708
|
2
|
-
yad2_scraper/category.py,sha256=SQ2eg0-fQ9hEaNryYpWVFaJqCx1d65t2_E_S3qpuw9g,1230
|
3
|
-
yad2_scraper/constants.py,sha256=8zXJ31fRqkDIOJp96BRK1PJofGXX8SG64YcfmJnVW8Q,910
|
4
|
-
yad2_scraper/exceptions.py,sha256=5yentEUBuEGItwRcjtZY89A19rvFErcTy4S4GUtY_WY,1526
|
5
|
-
yad2_scraper/next_data.py,sha256=OcZ7ingXSd6sLNkqQPz6NVTeEDbMkOai9QONFErc3FI,1977
|
6
|
-
yad2_scraper/query.py,sha256=HPBoLE6xFjsmvBFR2ULvPq96XXl-2zOqXt7LnHgetIk,1438
|
7
|
-
yad2_scraper/scraper.py,sha256=VA-P24Gvn1y5Pkn_n3hDdpVl1aeEnLoC82eBYteAbWQ,11816
|
8
|
-
yad2_scraper/utils.py,sha256=UDpFKel_TJa0dJv1FV-CVqA8-uaFo_hDcooiFAkSZI8,1578
|
9
|
-
yad2_scraper/vehicles/__init__.py,sha256=dxjZcNv3ExnN3fKW-m1oqKiX9YC7gj8lqpIa3uWo9iI,242
|
10
|
-
yad2_scraper/vehicles/category.py,sha256=HdUGCVpC1jw2V-2XvyAC4pPlVQR6cwHyVKDxS3pfQhc,744
|
11
|
-
yad2_scraper/vehicles/next_data.py,sha256=lEIWcTP7BOFDC3lL0FhBGp6u-7hsgGdbbrH0iw0Ux20,9203
|
12
|
-
yad2_scraper/vehicles/query.py,sha256=ieIJSGJELcgzqtJh6bQXalvDg743LnI2RYrAyHDIH80,912
|
13
|
-
yad2_scraper/vehicles/tag.py,sha256=Wj7v2c8IPQLYHVkfzP1UiulKKJE4yLqnbeh81nvWZhU,2052
|
14
|
-
yad2_scraper/vehicles/urls.py,sha256=zxipWjm0SXn2gGOBWw9VqKAJ59mhIGpzd_fTYitpW8c,715
|
15
|
-
yad2_scraper-0.5.1.dist-info/LICENSE,sha256=JCpnDxMx2kE40e0UQ1svSmifrLWg2Gni5VTkJR68thY,1065
|
16
|
-
yad2_scraper-0.5.1.dist-info/METADATA,sha256=SLeA6BPi1idJ20WWWbl7AW-hC_u1_vKPRmUTg4_VhVI,5225
|
17
|
-
yad2_scraper-0.5.1.dist-info/WHEEL,sha256=7dDg4QLnNKTvwIDR9Ac8jJaAmBC_owJrckbC0jjThyA,88
|
18
|
-
yad2_scraper-0.5.1.dist-info/RECORD,,
|
File without changes
|