Added product page fetching

This commit is contained in:
2025-02-08 22:31:30 -05:00
parent b4536d72cf
commit 60adf4e0af
10 changed files with 140 additions and 0 deletions

8
.idea/.gitignore generated vendored Normal file
View 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

View 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>

View 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
View 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
View 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
View 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
View 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
View File

1
surugaya_api/consts.py Normal file
View 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
View 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