Use the Shinki Bus navigation site to resolve a Japanese bus-stop name, inspect the site's timetable-search link and submitted form parameters, discover the timetable endpoint's tcode, pcode, and generation values, and return published schedule data in a structured form suitable for checking times or personal-use API research.
Use Cases
Use when the caller provides a stop name or other stop description and needs departure times, route or destination information, applicable operating-day or schedule notes, or the site's timetable-search URL and request parameters. The caller may optionally provide a direction, route, date, or other visible timetable filter.
Automation Flow
For timetable/API investigation, navigate directly to
https://navi.shinkibus.jp/s/jikoku. For stop resolution, start athttps://navi.shinkibus.jp/s/because the stop resolver and timetable link are initialized there.On the initial search page, inspect the direct timetable link and form metadata in the same evaluation:
(()=>({
timetableHref:document.querySelector('#jousha_jikoku')?.getAttribute('href'),
maxDate:document.querySelector('#max_date')?.value||null,
formAction:document.querySelector('form[name="f1"]')?.action||null,
formMethod:(document.querySelector('form[name="f1"]')?.method||'').toUpperCase()||null
}))()The observed direct timetable target is /s/jikoku. Prefer that URL over navigating through the homepage when the caller only needs the timetable form or link structure.
- Resolve the stop without guessing an ID. The site's reusable search endpoint is:
GET /busstop-search/?limit=100&text={url-encoded-stop-name}
Use one same-origin evaluation to inspect the response and choose the result whose displayed Japanese name and surrounding context best match {stop-name}:
(async()=>{
const query={stop-name};
const r=await fetch('/busstop-search/?limit=100&text='+encodeURIComponent(query));
const text=await r.text();
let body=text;
try{body=JSON.parse(text)}catch{}
return {url:r.url,status:r.status,contentType:r.headers.get('content-type'),body};
})()If the endpoint response is not directly usable, type {stop-name} into input#que_start_text and inspect #que_start_text_auto for the same result data. Retain both the opaque stop ID and displayed label.
- Set the resolved stop using the site's resolver and verify the hidden fields:
(()=>{
window.setStartBusstop({stop-id},{stop-label});
return {
id:document.querySelector('#from_busstop')?.value||null,
name:document.querySelector('#from_busstop_name')?.value||null
};
})()Enter the boarding/departure timetable flow. The relevant link is
a#jousha_jikoku. The page uses an additional mode-setting function: callset_jikoku('jousha')when available before activating the timetable link/search control. If the initial link activation only changes the mode panel, activatea#jousha_jikokuagain after the mode is set. This ordering is required by the observed page behavior.Before submitting a personal-use request, inspect the final timetable form in one evaluation rather than guessing parameter names. Capture every
inputandselectname/value, selected option, button type/text/onclick, and the form action/method. Exclude only CSRF values from returned diagnostics, and do not transmit credentials or tokens. Use the page's own search button (button[type="button"]in this flow) after applying optional{date},{direction}, or{route}filters. The page's#max_datevalue indicates the available date ceiling.Discover the timetable request identifiers from the loaded timetable page rather than inventing them. Inspect the page's inline JavaScript and controls for the site's generation loader and timetable navigation functions:
(()=>({
loadGeneration:typeof window.loadGenaration==='function'?window.loadGenaration.toString():null,
moveTimeTable:typeof window.moveTimeTable==='function'?window.moveTimeTable.toString():null,
controls:[...document.querySelectorAll('input,select,button,a')].map(e=>({
tag:e.tagName,
id:e.id||null,
name:e.getAttribute('name'),
value:e.value||null,
href:e.getAttribute('href'),
onclick:e.getAttribute('onclick'),
text:(e.innerText||'').trim()
})).filter(x=>x.id||x.name||x.value||x.href||x.onclick||x.text)
}))()The reusable same-origin endpoint pattern is:
GET /jikoku/generation?tcode={tcode}&pcode={pcode}
Use the resolved stop/timetable code as {tcode} and the pcode exposed by the loaded timetable page or its navigation JavaScript. Do not assume that pcode is globally constant; the observed flow used pcode=1 for one timetable. Parse the successful generation response and select the applicable generation value instead of guessing a date or generation identifier.
- Fetch the timetable only after obtaining a generation value:
GET /jikoku/timetable?tcode={tcode}&pcode={pcode}&generation={generation}
Check status and content type, preserve the response URL, and parse the returned HTML with the extractor below. The observed endpoint accepted a date-like generation value, but generation values are site data and must be obtained from /jikoku/generation for each timetable context.
- On the resulting timetable page, run this single-page extractor:
(()=>{
const clean=s=>String(s??'').replace(/\u00a0/g,' ').replace(/[ \t]+/g,' ').replace(/\n[ \t]+/g,'\n').trim();
const visible=e=>!!e&&getComputedStyle(e).display!=='none'&&getComputedStyle(e).visibility!=='hidden';
const tables=[...document.querySelectorAll('table')].filter(visible).map((table,index)=>{
const rows=[...table.querySelectorAll('tr')].filter(visible).map(tr=>[...tr.querySelectorAll('th,td')].map(td=>clean(td.innerText)));
const caption=clean(table.querySelector('caption')?.innerText);
const headers=[...table.querySelectorAll('thead th')].map(th=>clean(th.innerText)).filter(Boolean);
return {index,caption,headers,rows};
}).filter(x=>x.rows.length);
const notes=[...document.querySelectorAll('h1,h2,h3,h4,p,li,dt,dd,.notice,.note,.attention,[class*="note"],[class*="caution"]')]
.filter(visible).map(e=>clean(e.innerText)).filter(Boolean)
.filter((v,i,a)=>a.indexOf(v)===i);
const headings=[...document.querySelectorAll('h1,h2,h3,h4')].filter(visible).map(e=>clean(e.innerText)).filter(Boolean);
return {url:location.href,title:clean(document.title),headings,timetables:tables,notes,extractedAt:new Date().toISOString()};
})()Possible Friction Points
- The stop name is not itself the timetable key. Resolve it through
/busstop-search/?limit=100&text={query}or the autocomplete result, then retain the returned opaque ID and displayed label; never invent an ID. - The bus-stop endpoint is a same-origin site endpoint rather than documented public API. Treat its response format as implementation detail, check the HTTP status and content type, and do not assume it is stable or suitable for unrestricted redistribution.
- The relevant hidden fields are
#from_busstopand#from_busstop_name; verify both before opening the timetable flow. - The direct timetable path is
/s/jikoku, and the initial page exposes it througha#jousha_jikoku. Inspect the link and form metadata instead of relying on homepage clicks. set_jikoku('jousha')may need to run before the timetable link/search action; the observed flow could require activatinga#jousha_jikokuagain after this mode change.- The timetable API uses
/jikoku/generation?tcode={tcode}&pcode={pcode}followed by/jikoku/timetable?tcode={tcode}&pcode={pcode}&generation={generation}.pcodeis a request parameter exposed by the timetable context, not an ID that should be fabricated;pcode=1was observed for one context only. - Inspect actual form controls and the form action/method on the loaded page before documenting or reproducing request parameters. Parameter names and submission behavior are implementation details and may change.
- The hidden
#max_datevalue can constrain date filters; do not request dates beyond it without checking the current page. - Do not treat every visible number as a departure: preserve table headers and row grouping so hour/minute cells, destinations, route labels, and service-day notes remain associated.
- Keep timetable notes such as weekdays, weekends, holidays, seasonal operation, suspension, or date-specific exceptions in the output; they are necessary for determining whether a listed time applies.