feat(zto): cross-month calendar navigation instead of fallback to today
When the offset target date falls outside the current two-month view, flip .prev months (1 month/step) until the target day cell enters month1 view, instead of silently falling back to today. JS-dispatched clicks avoid the .date-range-length-tip hover interception. Also switch the expected (#beginDate) day-cell click to _dom_click (matching actual #daterange): the range-length tooltip intercepts the second click on non-today cells during single-day range selection, causing timeouts. Verified end-to-end: offset=45 (-> 2026-06-14, cross-month) expected task succeeded and downloaded 6-14 data without fallback. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -93,6 +93,22 @@ def _dom_click(locator):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _zto_flip_to_target_month(frame_locator, page, target_time, max_flips=12):
|
||||||
|
"""中通日历(jQuery-Date-Range-Picker 双月视图)跨月导航:目标日期不在当前视窗时,
|
||||||
|
循环点 .prev 把目标月翻进 month1 视窗。offset 恒指向过去,故只往前翻;步长 1 月/次。
|
||||||
|
用 JS 派发点击(.evaluate("el=>el.click()"))避开 .date-range-length-tip 等 hover 遮挡。
|
||||||
|
返回 True 若目标格子最终可见。"""
|
||||||
|
sel = f"td div.day[time='{target_time}']"
|
||||||
|
for _ in range(max_flips):
|
||||||
|
if frame_locator.locator(sel).first.is_visible():
|
||||||
|
return True
|
||||||
|
frame_locator.locator(".date-picker-wrapper .prev").first.evaluate(
|
||||||
|
"el => el.click()"
|
||||||
|
)
|
||||||
|
page.wait_for_timeout(450)
|
||||||
|
return frame_locator.locator(sel).first.is_visible()
|
||||||
|
|
||||||
|
|
||||||
def zto_smart_menu_click(page, menu_path):
|
def zto_smart_menu_click(page, menu_path):
|
||||||
"""中通菜单导航"""
|
"""中通菜单导航"""
|
||||||
print(f">> 正在导航: {' -> '.join(menu_path)}")
|
print(f">> 正在导航: {' -> '.join(menu_path)}")
|
||||||
@@ -158,15 +174,19 @@ def zto_expected_download_impl(page, force=False):
|
|||||||
target_time = today_time - offset * 86400000
|
target_time = today_time - offset * 86400000
|
||||||
target_cell = ewb_frame.locator(f"td div.day[time='{target_time}']").first
|
target_cell = ewb_frame.locator(f"td div.day[time='{target_time}']").first
|
||||||
|
|
||||||
if target_cell.is_visible():
|
# 偏移日期跨月时目标格子不在当前双月视窗 → 向前翻月把它带进视窗,不再降级为当天
|
||||||
target_cell.click()
|
if not target_cell.is_visible():
|
||||||
page.wait_for_timeout(300)
|
print(" ℹ️ 偏移日期跨月,正在向前翻月导航到目标 ...")
|
||||||
target_cell.click()
|
if not _zto_flip_to_target_month(ewb_frame, page, target_time):
|
||||||
else:
|
raise RuntimeError(
|
||||||
print(" ⚠️ 偏移日期不在当前日历视窗内,自动降级为查询当天。")
|
f"翻月后仍无法定位目标日期格子(time={target_time})"
|
||||||
today_cell.click()
|
)
|
||||||
page.wait_for_timeout(300)
|
# 日期格子用 _dom_click 直接派发事件(同实到):.click() 会先 hover 格子,触发
|
||||||
today_cell.click()
|
# “范围长度”提示气泡(.date-range-length-tip)盖住格子导致点击被遮挡超时,
|
||||||
|
# 跨月选中非今日格子时尤为明显。
|
||||||
|
_dom_click(target_cell)
|
||||||
|
page.wait_for_timeout(300)
|
||||||
|
_dom_click(target_cell)
|
||||||
else:
|
else:
|
||||||
today_cell.click()
|
today_cell.click()
|
||||||
page.wait_for_timeout(300)
|
page.wait_for_timeout(300)
|
||||||
@@ -404,14 +424,16 @@ def zto_actual_download_impl(page):
|
|||||||
|
|
||||||
# 日期格子用 _dom_click 直接派发事件:Playwright 的 .click() 会先 hover 格子,
|
# 日期格子用 _dom_click 直接派发事件:Playwright 的 .click() 会先 hover 格子,
|
||||||
# 触发“范围长度”提示气泡(.date-range-length-tip)盖住格子,导致点击被判遮挡而超时。
|
# 触发“范围长度”提示气泡(.date-range-length-tip)盖住格子,导致点击被判遮挡而超时。
|
||||||
if target_cell.is_visible():
|
# 偏移日期跨月时目标格子不在当前双月视窗 → 向前翻月把它带进视窗,不再降级为当天。
|
||||||
_dom_click(target_cell)
|
if not target_cell.is_visible():
|
||||||
page.wait_for_timeout(300)
|
print(" ℹ️ 偏移日期跨月,正在向前翻月导航到目标 ...")
|
||||||
_dom_click(target_cell)
|
if not _zto_flip_to_target_month(arr_frame, page, target_time):
|
||||||
else:
|
raise RuntimeError(
|
||||||
_dom_click(today_cell)
|
f"翻月后仍无法定位目标日期格子(time={target_time})"
|
||||||
page.wait_for_timeout(300)
|
)
|
||||||
_dom_click(today_cell)
|
_dom_click(target_cell)
|
||||||
|
page.wait_for_timeout(300)
|
||||||
|
_dom_click(target_cell)
|
||||||
else:
|
else:
|
||||||
_dom_click(today_cell)
|
_dom_click(today_cell)
|
||||||
page.wait_for_timeout(300)
|
page.wait_for_timeout(300)
|
||||||
|
|||||||
Reference in New Issue
Block a user