fix: 校验 PDD 采集商品链接 (#28)
This commit is contained in:
@@ -507,9 +507,27 @@ def _raise_special_page(labels: Sequence[str]) -> None:
|
|||||||
raise PddCollectError("PDD_PAGE_LOGIN_REQUIRED", "PDD 登录已失效,需要人工重新登录")
|
raise PddCollectError("PDD_PAGE_LOGIN_REQUIRED", "PDD 登录已失效,需要人工重新登录")
|
||||||
|
|
||||||
|
|
||||||
def _goods_id_from_url(goods_url: str) -> str:
|
def _validate_goods_url(goods_url: str, task_goods_id: str) -> str:
|
||||||
value = parse_qs(urlparse(goods_url).query).get("goods_id", [""])[0].strip()
|
parsed = urlparse(goods_url)
|
||||||
if not value:
|
host = (parsed.hostname or "").lower()
|
||||||
|
allowed_host = host == "yangkeduo.com" or host.endswith(".yangkeduo.com")
|
||||||
|
allowed_host = allowed_host or host == "pinduoduo.com" or host.endswith(
|
||||||
|
".pinduoduo.com"
|
||||||
|
)
|
||||||
|
if parsed.scheme not in ("http", "https") or not allowed_host:
|
||||||
|
raise PddCollectError(
|
||||||
|
"PDD_DATA_GOODS_URL_INVALID",
|
||||||
|
"商品链接不是受支持的 PDD 链接",
|
||||||
|
)
|
||||||
|
|
||||||
|
url_goods_id = parse_qs(parsed.query).get("goods_id", [""])[0].strip()
|
||||||
|
if task_goods_id and url_goods_id and task_goods_id != url_goods_id:
|
||||||
|
raise PddCollectError(
|
||||||
|
"PDD_DATA_GOODS_ID_MISMATCH",
|
||||||
|
"任务商品编号与商品链接中的 goods_id 不一致",
|
||||||
|
)
|
||||||
|
value = task_goods_id or url_goods_id
|
||||||
|
if not value or not value.isdigit():
|
||||||
raise PddCollectError("PDD_DATA_GOODS_ID_MISSING", "商品链接中没有 goods_id")
|
raise PddCollectError("PDD_DATA_GOODS_ID_MISSING", "商品链接中没有 goods_id")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@@ -566,7 +584,7 @@ class PddCollectService:
|
|||||||
if not goods_url:
|
if not goods_url:
|
||||||
raise PddCollectError("PDD_DATA_GOODS_URL_MISSING", "采集任务缺少商品链接")
|
raise PddCollectError("PDD_DATA_GOODS_URL_MISSING", "采集任务缺少商品链接")
|
||||||
goods_id = str(getattr(task, "goods_id", "") or "").strip()
|
goods_id = str(getattr(task, "goods_id", "") or "").strip()
|
||||||
goods_id = goods_id or _goods_id_from_url(goods_url)
|
goods_id = _validate_goods_url(goods_url, goods_id)
|
||||||
self._check_cancelled()
|
self._check_cancelled()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -165,9 +165,34 @@ class PddCollectParserTest(unittest.TestCase):
|
|||||||
"client-001",
|
"client-001",
|
||||||
)
|
)
|
||||||
with self.assertRaises(PddCollectError) as raised:
|
with self.assertRaises(PddCollectError) as raised:
|
||||||
service.collect(FakeTask("https://example.com/goods.html"))
|
service.collect(FakeTask("https://mobile.yangkeduo.com/goods.html"))
|
||||||
self.assertEqual(raised.exception.code, "PDD_DATA_GOODS_ID_MISSING")
|
self.assertEqual(raised.exception.code, "PDD_DATA_GOODS_ID_MISSING")
|
||||||
|
|
||||||
|
def test_non_pdd_goods_url_is_rejected_before_opening_device(self):
|
||||||
|
service = PddCollectService(
|
||||||
|
PddDeviceService(lambda _serial: object()),
|
||||||
|
"USB-001",
|
||||||
|
"client-001",
|
||||||
|
)
|
||||||
|
with self.assertRaises(PddCollectError) as raised:
|
||||||
|
service.collect(FakeTask("https://example.com/goods.html?goods_id=123"))
|
||||||
|
self.assertEqual(raised.exception.code, "PDD_DATA_GOODS_URL_INVALID")
|
||||||
|
|
||||||
|
def test_task_goods_id_must_match_url(self):
|
||||||
|
service = PddCollectService(
|
||||||
|
PddDeviceService(lambda _serial: object()),
|
||||||
|
"USB-001",
|
||||||
|
"client-001",
|
||||||
|
)
|
||||||
|
with self.assertRaises(PddCollectError) as raised:
|
||||||
|
service.collect(
|
||||||
|
FakeTask(
|
||||||
|
"https://mobile.yangkeduo.com/goods.html?goods_id=123",
|
||||||
|
goods_id="456",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(raised.exception.code, "PDD_DATA_GOODS_ID_MISMATCH")
|
||||||
|
|
||||||
def test_page_timeout_has_specific_error_code(self):
|
def test_page_timeout_has_specific_error_code(self):
|
||||||
device = LoadingDevice(self.home_xml, self.spec_xml)
|
device = LoadingDevice(self.home_xml, self.spec_xml)
|
||||||
ticks = iter((0.0, 2.0))
|
ticks = iter((0.0, 2.0))
|
||||||
|
|||||||
Reference in New Issue
Block a user