Added product page fetching
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
16
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
16
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<value>
|
||||
<list size="3">
|
||||
<item index="0" class="java.lang.String" itemvalue="pymssql" />
|
||||
<item index="1" class="java.lang.String" itemvalue="Django" />
|
||||
<item index="2" class="java.lang.String" itemvalue="cffi" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
7
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
7
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
9
.idea/misc.xml
generated
Normal file
9
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.9 (surugaya_api)" />
|
||||
</component>
|
||||
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/surugaya_api.iml" filepath="$PROJECT_DIR$/.idea/surugaya_api.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
10
.idea/surugaya_api.iml
generated
Normal file
10
.idea/surugaya_api.iml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.9 (surugaya_api)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
0
surugaya_api/__init__.py
Normal file
0
surugaya_api/__init__.py
Normal file
1
surugaya_api/consts.py
Normal file
1
surugaya_api/consts.py
Normal file
@@ -0,0 +1 @@
|
||||
SURU_COOKIE_STRING = "safe_search_option=3; safe_search_expired=2; z_hyoji=0; p_adult=1; p_hyoji=0"
|
75
surugaya_api/product.py
Normal file
75
surugaya_api/product.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
import aiohttp
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from surugaya_api.consts import SURU_COOKIE_STRING
|
||||
|
||||
@dataclass
|
||||
class ProductStock:
|
||||
condition: str
|
||||
stock: str
|
||||
price: int
|
||||
on_sale_price: Optional[int]
|
||||
|
||||
@property
|
||||
def is_on_sale(self) -> bool:
|
||||
return self.on_sale_price is not None
|
||||
|
||||
@staticmethod
|
||||
def from_item_price(item_price):
|
||||
data: dict = json.loads(item_price.select_one("input").attrs["data-zaiko"])
|
||||
|
||||
return ProductStock(
|
||||
condition=item_price.select_one("label").attrs["data-label"].strip(),
|
||||
stock=data["zaiko"],
|
||||
price=data["baika"],
|
||||
on_sale_price=data.get("price_sale")
|
||||
)
|
||||
|
||||
@dataclass
|
||||
class Product:
|
||||
id: int
|
||||
name: str
|
||||
main_image_href: str
|
||||
stock: [ProductStock]
|
||||
|
||||
@property
|
||||
def in_stock(self):
|
||||
return not self.stock
|
||||
|
||||
|
||||
async def load_product(product_id, aiohttp_session=None):
|
||||
if not aiohttp_session:
|
||||
_aiohttp_session = aiohttp.ClientSession()
|
||||
else:
|
||||
_aiohttp_session = aiohttp_session
|
||||
|
||||
async with _aiohttp_session.get(
|
||||
url="https://www.suruga-ya.jp/product/detail/" + str(product_id),
|
||||
headers={
|
||||
"Cookie": SURU_COOKIE_STRING,
|
||||
},
|
||||
) as response:
|
||||
page = await response.text()
|
||||
|
||||
page_bs = BeautifulSoup(
|
||||
page, features="html.parser"
|
||||
)
|
||||
|
||||
product = Product(
|
||||
id=int(product_id),
|
||||
name=page_bs.select_one("#item_title").text.strip(),
|
||||
main_image_href=page_bs.select_one(".main-pro-img").attrs["src"],
|
||||
stock=[
|
||||
ProductStock.from_item_price(item_price)
|
||||
for item_price in page_bs.select(".item-price")
|
||||
]
|
||||
)
|
||||
|
||||
if not aiohttp_session:
|
||||
await _aiohttp_session.close()
|
||||
|
||||
return product
|
Reference in New Issue
Block a user