ikare adlı üyeden alıntı:
mesajı görüntüle
PDF'lerin Tümünü İndirme
15
●290
- Bugün, 13:49:21Hocam, teşekkürler. çok uğraşmışsınız.
Çok teşekkür ederim. Elinize sağlık
fatihanily adlı üyeden alıntı: mesajı görüntüleSelam,
console'a yazacağımız basit bir kodla yapabiliriz.
F12'ye basın. --> Console kısmına gelin. --> Aşağıdaki kodu yapıştırın. !! "Allow pasting" uyarısı alırsanız kodu yapıştırmadan önce "allow pasting" yazıp enter'a basın.
Açılan ekranda Küb ve Kt kısımlarının ineceği yeri seçin. --> Bu yoruma beğeni atın ve yorumun sağ altındaki doğru cevap düğmesine basın
Belki farklı yerlere indirmeniz gerekiyor diye farklı kaydetme yerleri var. İsterseniz aynı yere kaydedin. Size kalmış.
Ayrıca "bekleme süresi" de var. Bunu da ayarlayabilirsiniz.
Ai'nin de yardımıyla yapıldı... işinize yarar umarım.
https://i.ibb.co/Z62SYCSt/image.png
Kod :
/* * TİTCK KÜB / KT toplu PDF indirici * Kullanım: [url]https://titck.gov.tr/kubkt[/url] sayfasında F12 > Console'a tamamını yapıştırın. * Chrome / Microsoft Edge (File System Access API) gerekir. * Dosyalar seçilen ana klasörün KUB ve KT alt klasörlerine ayrı ayrı kaydedilir. */ (() => { 'use strict'; if (window.__TITCK_PDF_TOPLU__?.panel?.isConnected) { window.__TITCK_PDF_TOPLU__.panel.style.display = 'block'; console.info('TİTCK indirme paneli zaten açık.'); return; } if (location.hostname !== 'titck.gov.tr' || location.pathname.replace(/\/$/, '') !== '/kubkt') { alert('Önce [url]https://titck.gov.tr/kubkt[/url] adresini açın.'); return; } if (!('showDirectoryPicker' in window)) { alert('Klasör seçerek kaydetme için güncel Chrome veya Microsoft Edge kullanmalısınız.'); return; } const table = document.querySelector('#posts'); const $jq = window.jQuery; if (!table || !$jq?.fn?.dataTable?.isDataTable(table)) { alert('DataTables tablosu hazır değil. Sayfa tam yüklendikten sonra tekrar deneyin.'); return; } const dt = $jq(table).DataTable(); let rootFolder = null; let kubFolder = null; let ktFolder = null; let running = false; let paused = false; let stopRequested = false; let activeController = null; let currentPage = 1; let stats = { saved: 0, skipped: 0, failed: 0, missing: 0, rows: 0 }; const style = document.createElement('style'); style.id = 'titck-pdf-panel-style'; style.textContent = ` #titck-pdf-panel { all: initial; position:fixed; top:18px; right:18px; width:370px; max-width:calc(100vw - 36px); max-height:calc(100vh - 36px); overflow:auto; z-index:2147483647; background:#111827; color:#f9fafb; border:1px solid #4b5563; border-radius:14px; box-shadow:0 18px 55px #0009; font:13px/1.5 Arial,sans-serif; box-sizing:border-box; padding:18px; } #titck-pdf-panel * { box-sizing:border-box; font-family:Arial,sans-serif; } #titck-pdf-panel h2 { margin:0 0 8px; font-size:18px; color:#fff; } #titck-pdf-panel p { margin:7px 0 12px; font-size:12px; color:#cbd5e1; } #titck-pdf-panel .trow { display:grid; grid-template-columns:1fr 1fr; gap:9px; margin:10px 0; } #titck-pdf-panel label { display:block; font-size:12px; color:#e2e8f0; } #titck-pdf-panel input { display:block; width:100%; margin-top:4px; padding:8px 7px; font-size:13px; color:#111827; background:#fff; border:1px solid #9ca3af; border-radius:7px; } #titck-pdf-panel button { border:0; border-radius:8px; background:#374151; color:white; font-size:12px; font-weight:bold; padding:10px 9px; cursor:pointer; } #titck-pdf-panel button:hover { filter:brightness(1.18); } #titck-pdf-panel button:disabled { opacity:.45; cursor:not-allowed; } #titck-pdf-panel .full { width:100%; } #titck-pdf-panel .action { display:grid; grid-template-columns:1fr 1fr 1fr; gap:7px; margin:12px 0; } #titck-pdf-panel #titck-start { background:#047857; } #titck-pdf-panel #titck-pause { background:#b45309; } #titck-pdf-panel #titck-stop { background:#b91c1c; } #titck-pdf-panel #titck-folder { background:#1d4ed8; } #titck-pdf-panel #titck-log { background:#030712; border:1px solid #374151; min-height:90px; max-height:180px; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere; color:#d1d5db; font:11px/1.5 Consolas,monospace; padding:8px; border-radius:7px; } #titck-pdf-panel #titck-stats { white-space:pre-line; margin:10px 0; font:12px/1.6 Consolas,monospace; color:#bfdbfe; } #titck-pdf-panel #titck-status { color:#fef08a; font-weight:700; margin:7px 0; } `; document.head.appendChild(style); const panel = document.createElement('section'); panel.id = 'titck-pdf-panel'; panel.innerHTML = ` <h2>📥 TİTCK KÜB / KT İndirici</h2> <p>Seçtiğiniz klasöre <b>KUB/</b> ve <b>KT/</b> alt klasörleri oluşturulur. Her ilaç için iki ayrı PDF indirilir (sitede varsa).</p> <button type="button" class="full" id="titck-folder">📁 Kayıt klasörünü seç</button> <p id="titck-folder-label">Henüz klasör seçilmedi.</p> <div class="trow"> <label>Başlangıç sayfası<input id="titck-first" type="number" min="1" step="1" value="1"></label> <label>Bitiş sayfası<input id="titck-last" type="number" min="1" step="1" value="1"></label> </div> <div class="trow"> <label>PDF arası bekleme (ms)<input id="titck-pdf-delay" type="number" min="0" step="100" value="1000"></label> <label>Sayfa arası bekleme (ms)<input id="titck-page-delay" type="number" min="0" step="100" value="1500"></label> </div> <div class="trow"> <label>PDF zaman aşımı (sn)<input id="titck-timeout" type="number" min="10" step="10" value="120"></label> <label>Hata sonrası ek deneme<input id="titck-retries" type="number" min="0" max="8" step="1" value="2"></label> </div> <div class="action"> <button type="button" id="titck-start">▶ Başlat</button> <button type="button" id="titck-pause" disabled>⏸ Duraklat</button> <button type="button" id="titck-stop" disabled>■ Durdur</button> </div> <div id="titck-status">Hazır</div> <div id="titck-stats"></div> <div id="titck-log" aria-live="polite"></div> <p>Not: Sekmeyi kapatmayın. Durdurup yeniden başlattığınızda aynı isimdeki mevcut PDF'ler atlanır.</p> `; document.body.appendChild(panel); const el = id => panel.querySelector('#' + id); const setStatus = s => { el('titck-status').textContent = s; }; const n = (id, fallback = 0) => { const v = Number(el(id).value); return Number.isFinite(v) ? v : fallback; }; const maxPages = () => Math.max(1, dt.page.info().pages || 1); el('titck-last').value = maxPages(); const log = message => { const now = new Date().toLocaleTimeString('tr-TR'); const node = document.createElement('div'); node.textContent = `[${now}] ${message}`; el('titck-log').appendChild(node); while (el('titck-log').childNodes.length > 180) el('titck-log').firstChild.remove(); el('titck-log').scrollTop = el('titck-log').scrollHeight; console.log('[TİTCK]', message); }; const updateStats = () => { el('titck-stats').textContent = `Sayfa: ${currentPage}/${maxPages()}\n` + `İncelenen ilaç: ${stats.rows}\n` + `Kaydedilen PDF: ${stats.saved} | Atlanan: ${stats.skipped}\n` + `Eksik bağlantı: ${stats.missing} | Başarısız: ${stats.failed}`; }; const updateButtons = () => { el('titck-start').disabled = running; el('titck-folder').disabled = running; el('titck-pause').disabled = !running; el('titck-stop').disabled = !running; el('titck-pause').textContent = paused ? '▶ Devam et' : '⏸ Duraklat'; }; updateStats(); el('titck-folder').addEventListener('click', async () => { try { rootFolder = await window.showDirectoryPicker({ mode: 'readwrite', id: 'titck-kub-kt' }); kubFolder = await rootFolder.getDirectoryHandle('KUB', { create: true }); ktFolder = await rootFolder.getDirectoryHandle('KT', { create: true }); el('titck-folder-label').textContent = `Seçili klasör: ${rootFolder.name} → KUB / KT`; log('Kayıt klasörü seçildi: ' + rootFolder.name); } catch (err) { if (err.name !== 'AbortError') log('Klasör seçilemedi: ' + err.message); } }); function stoppedError() { const error = new Error('İşlem durduruldu'); error.name = 'StoppedError'; return error; } async function checkPauseAndStop() { if (stopRequested) throw stoppedError(); while (paused && !stopRequested) { await new Promise(resolve => setTimeout(resolve, 200)); } if (stopRequested) throw stoppedError(); } async function waitMs(ms) { const until = performance.now() + Math.max(0, ms); do { await checkPauseAndStop(); const left = until - performance.now(); if (left <= 0) break; await new Promise(resolve => setTimeout(resolve, Math.min(200, left))); } while (true); } async function gotoPage(zeroBasedPage) { await checkPauseAndStop(); if (dt.page.info().page === zeroBasedPage) return; await new Promise((resolve, reject) => { const timer = setTimeout(() => { cleanup(); reject(new Error('Tablonun sayfa değiştirmesi zaman aşımına uğradı (60 sn)')); }, 60000); function cleanup() { clearTimeout(timer); $jq(table).off('draw.dt.titckbulk', onDraw); } function onDraw() { if (dt.page.info().page === zeroBasedPage) { cleanup(); resolve(); } } $jq(table).on('draw.dt.titckbulk', onDraw); try { dt.page(zeroBasedPage).draw('page'); } catch (err) { cleanup(); reject(err); } }); } function safeFileName(str) { return String(str || 'Bilinmeyen_ilac') .normalize('NFC') .replace(/[\\/:*?"<>|\x00-\x1f]/g, '_') .replace(/\s+/g, ' ') .replace(/[. ]+$/g, '') .slice(0, 105) || 'Bilinmeyen_ilac'; } function shortHash(str) { let h = 2166136261; for (let i = 0; i < str.length; i++) { h ^= str.charCodeAt(i); h = Math.imul(h, 16777619); } return (h >>> 0).toString(16).padStart(8, '0'); } function jobsOnCurrentPage() { const trList = Array.from(table.tBodies[0]?.querySelectorAll('tr') || []); const jobs = []; for (const tr of trList) { const cells = tr.cells; if (cells.length < 7) continue; const drug = cells[0].textContent.trim() || 'Bilinmeyen_ilac'; stats.rows++; for (const [col, type] of [[5, 'KUB'], [6, 'KT']]) { const anchor = cells[col].querySelector('a[href]'); if (!anchor) { stats.missing++; continue; } try { const url = new URL(anchor.getAttribute('href'), location.href); if (url.origin !== location.origin || !url.pathname.toLowerCase().endsWith('.pdf')) { stats.missing++; log(`PDF bağlantısı desteklenmiyor: ${drug} (${type})`); continue; } const name = `${safeFileName(drug)}_${shortHash(url.href)}.pdf`; jobs.push({ type, drug, name, url: url.href }); } catch (_) { stats.missing++; } } } return jobs; } // Büyük PDF'leri RAM'e yüklemeden parça parça dosyaya yazar. async function fetchAndSave(job, folder) { const controller = new AbortController(); activeController = controller; const timeoutMs = Math.max(10, n('titck-timeout', 120)) * 1000; const timer = setTimeout(() => controller.abort(), timeoutMs); let writer = null; let fileWasCreated = false; let reader = null; try { const response = await fetch(job.url, { method: 'GET', credentials: 'same-origin', mode: 'same-origin', cache: 'no-store', signal: controller.signal }); if (!response.ok) { const error = new Error(`HTTP ${response.status}`); error.httpStatus = response.status; throw error; } if (!response.body) throw new Error('Sunucu PDF veri akışı döndürmedi'); reader = response.body.getReader(); // Hata / giriş / HTML sayfasını yanlışlıkla .pdf olarak kaydetmeyelim. const headChunks = []; let headSize = 0; while (headSize < 1024) { const part = await reader.read(); if (part.done) break; headChunks.push(part.value); headSize += part.value.byteLength; } const prefix = new Uint8Array(Math.min(headSize, 1024)); let offset = 0; for (const piece of headChunks) { if (offset >= prefix.length) break; const chunk = piece.subarray(0, prefix.length - offset); prefix.set(chunk, offset); offset += chunk.length; } if (!new TextDecoder('latin1').decode(prefix).includes('%PDF-')) { throw new Error('Gelen içerik PDF değil (HTML/hata yanıtı olabilir)'); } const file = await folder.getFileHandle(job.name, { create: true }); fileWasCreated = true; writer = await file.createWritable(); for (const piece of headChunks) await writer.write(piece); while (true) { const { value, done } = await reader.read(); if (done) break; await writer.write(value); } await writer.close(); writer = null; } catch (err) { if (reader) { try { await reader.cancel(); } catch (_) {} } if (writer) { try { await writer.abort(); } catch (_) {} } if (fileWasCreated) { try { await folder.removeEntry(job.name); } catch (_) {} } throw err; } finally { clearTimeout(timer); if (activeController === controller) activeController = null; } } async function saveJob(job) { const folder = job.type === 'KUB' ? kubFolder : ktFolder; try { const existing = await folder.getFileHandle(job.name, { create: false }); if ((await existing.getFile()).size > 0) { stats.skipped++; updateStats(); return; } } catch (err) { if (err.name !== 'NotFoundError') throw err; } const retries = Math.min(8, Math.max(0, Math.floor(n('titck-retries', 2)))); for (let attempt = 0; attempt <= retries; attempt++) { await checkPauseAndStop(); try { await fetchAndSave(job, folder); stats.saved++; updateStats(); return; } catch (err) { if (stopRequested) throw stoppedError(); const permanent = [400, 401, 403, 404, 410].includes(err.httpStatus); if (attempt < retries && !permanent) { const retryWait = err.httpStatus === 429 ? 30000 : 2500 * (attempt + 1); log(`${job.type} deneme ${attempt + 1} başarısız: ${job.drug} (${err.message}), ${retryWait / 1000} sn sonra tekrar...`); await waitMs(retryWait); } else { stats.failed++; log(`BAŞARISIZ [${job.type}]: ${job.drug} — ${err.message}`); updateStats(); return; } } } } el('titck-pause').addEventListener('click', () => { if (!running) return; paused = !paused; setStatus(paused ? 'Duraklatıldı (aktif PDF bitince)' : 'Çalışıyor'); updateButtons(); }); el('titck-stop').addEventListener('click', () => { stopRequested = true; paused = false; if (activeController) activeController.abort(); setStatus('Durduruluyor...'); updateButtons(); }); el('titck-start').addEventListener('click', async () => { if (running) return; if (!rootFolder || !kubFolder || !ktFolder) { alert('Önce kayıt klasörünü seçin.'); return; } const totalPages = maxPages(); const first = Math.floor(n('titck-first', 1)); const last = Math.floor(n('titck-last', totalPages)); if (first < 1 || last < first || last > totalPages) { alert(`Sayfa aralığı 1-${totalPages} arasında olmalı.`); return; } if (n('titck-pdf-delay') < 0 || n('titck-page-delay') < 0) { alert('Bekleme süreleri negatif olamaz.'); return; } running = true; paused = false; stopRequested = false; stats = { saved: 0, skipped: 0, failed: 0, missing: 0, rows: 0 }; currentPage = first; updateButtons(); updateStats(); log(`Başladı: ${first}-${last}. sayfalar, PDF bekleme ${n('titck-pdf-delay')} ms.`); try { for (let page = first; page <= last; page++) { await checkPauseAndStop(); currentPage = page; setStatus(`Sayfa yükleniyor: ${page}/${last}`); await gotoPage(page - 1); await checkPauseAndStop(); const jobs = jobsOnCurrentPage(); log(`Sayfa ${page}/${last}: ${jobs.length} PDF bağlantısı bulundu.`); updateStats(); for (const job of jobs) { await checkPauseAndStop(); setStatus(`Sayfa ${page}/${last}: ${job.type} → ${job.drug.slice(0, 45)}`); const before = stats.skipped; await saveJob(job); if (before === stats.skipped) await waitMs(n('titck-pdf-delay', 1000)); } // Elle devam etmek için başlangıç sayfasını hazır tut. el('titck-first').value = Math.min(page + 1, last); if (page < last) await waitMs(n('titck-page-delay', 1500)); } setStatus(`Tamamlandı. Kaydedilen: ${stats.saved} | Hata: ${stats.failed}`); log('BİTTİ. Toplam kaydedilen PDF: ' + stats.saved); } catch (err) { if (err.name === 'StoppedError' || stopRequested) { el('titck-first').value = currentPage; setStatus(`Durduruldu. ${currentPage}. sayfadan yeniden başlayabilirsiniz.`); log(`Durduruldu. ${currentPage}. sayfadan devam edebilirsiniz; mevcut dosyalar atlanır.`); } else { el('titck-first').value = currentPage; setStatus('Hata oluştu: ' + err.message); log(`GENEL HATA: ${err.stack || err.message}`); } } finally { running = false; paused = false; stopRequested = false; updateButtons(); updateStats(); } }); window.__TITCK_PDF_TOPLU__ = { panel, getStats: () => ({ ...stats }), stop: () => el('titck-stop').click() }; log(`Panel hazır. Sitede ${maxPages()} sayfa algılandı.`); console.info('TİTCK KÜB / KT indirme paneli sayfanın sağ üstünde açıldı.'); })(); - Bugün, 13:50:13tüm linkleri açıp indir mi demek gerekiyor anlamadım?newQne adlı üyeden alıntı: mesajı görüntüleEvet hocam ortalama 15-20gb yer kaplar indirirseniz bunları ne yapıyorsun hocam merak ettim
- Bugün, 14:10:06yok hocam tek tek açmana gerek yok. listeyi txt yapıp wget -i verince hepsini kendi çekiyor zaten vallaikare adlı üyeden alıntı: mesajı görüntületüm linkleri açıp indir mi demek gerekiyor anlamadım?
- Bugün, 14:18:49İnternet download manager gibi toplu indirme uygulamasına linkleri yapıştırın hocam
ikare adlı üyeden alıntı: mesajı görüntületüm linkleri açıp indir mi demek gerekiyor anlamadım? - Bugün, 16:46:34benim kodumda ayri klasore kaydoluyor ikisi de. Sorun hata vs varsa duzenleyebilirizzikare adlı üyeden alıntı: mesajı görüntüleHocam, teşekkürler. çok uğraşmışsınız.
Çok teşekkür ederim. Elinize sağlık
Beğeniler
Değerlendirmeler
