Kage - เครื่องมือสำหรับลบ JavaScript ออกจากเว็บไซต์และเก็บถาวรแบบออฟไลน์
(github.com/tamnd)- เรนเดอร์หน้าเว็บด้วย Headless Chrome เพื่อสแนปช็อต DOM สุดท้ายตามที่ผู้ใช้เห็น จากนั้นลบ JavaScript ทั้งหมด และดาวน์โหลด CSS, รูปภาพ, ฟอนต์ มาไว้ในพาธภายในเครื่อง เพื่อสร้างสำเนาแบบสแตติกที่ทำงานได้โดยไม่ต้องมีโค้ด
- แก้ปัญหาหน้าเว็บที่บันทึกด้วย "Save As" แล้วเมื่อเวลาผ่านไปกลับพังเป็นหน้าจอว่าง, สปินเนอร์ค้าง, หรือพยายามเชื่อมต่อกับเซิร์ฟเวอร์ analytics ที่หายไป
- ให้ไฟล์
.htmlที่เปิดได้จากดิสก์โดยตรง โดยไม่มีการติดตาม, การเรียกเครือข่าย, หรือพฤติกรรมไม่คาดคิด
- ให้ไฟล์
- ใช้การครอว์ลแบบ breadth-first โดยอ่าน
robots.txt, ใช้sitemap.xmlเป็นจุดเริ่มต้น และอยู่ภายในโฮสต์ตั้งต้นเท่านั้น- ด้วยคุณสมบัติ idempotent จึงดึงหน้าเดียวกันเพียงครั้งเดียว ไม่ว่าจะเป็น http/https หรือมี/ไม่มี trailing slash
- เมื่อกด Ctrl-C จะบันทึกตำแหน่งไว้ และเมื่อรันใหม่จะทำต่อจากเดิม โดยใช้
--refreshเพื่อเรนเดอร์ใหม่ และ--forceเพื่อเริ่มต้นใหม่
- มี แฟล็กสำหรับควบคุมขอบเขตและพฤติกรรมการครอว์ล เช่น
--max-pages,--max-depth,--scope-prefix,--subdomains,--scroll,--workers - ใช้
kage packเพื่อบีบอัดสำเนาเป็นไฟล์เดียว โดยเลือกได้ระหว่าง ZIM archive หรือ ไฟล์ปฏิบัติการเดี่ยว ที่ทำงานเป็นเว็บไซต์ได้เอง- ZIM เข้ากันได้กับระบบนิเวศของ Kiwix จึงเปิดดูได้ผ่าน
kiwix-serveหรือแอป Kiwix บนเดสก์ท็อปและมือถือ - ไบนารีแบบสแตนด์อโลนทำให้ผู้รับไม่ต้องติดตั้งอะไรเพิ่มเติม และสามารถใช้
--baseเพื่อสร้าง viewer สำหรับ OS อื่นได้ (ประมาณ 13 MiB + ขนาดเว็บไซต์)
- ZIM เข้ากันได้กับระบบนิเวศของ Kiwix จึงเปิดดูได้ผ่าน
- ด้วย deterministic packing สำเนาเดียวกันจะสร้างไฟล์ที่ byte-identical เสมอ และ UUID ของ archive ถูกสร้างจากเนื้อหา จึงปลอดภัยต่อ checksum และ cache
- เมื่อบิลด์ด้วยแท็ก
webviewจะใช้ OS WebView (WKWebView, WebView2, WebKitGTK) เพื่อเปิดใน หน้าต่างแอปของตัวเองแทนแท็บเบราว์เซอร์ - ไปป์ไลน์การประมวลผล: seed URL → เรนเดอร์ด้วย headless Chrome → สแนปช็อต final DOM → strip JS → ทำให้แอสเซ็ตเป็นไฟล์ภายในเครื่อง → บันทึกลงดิสก์
- สัญญาอนุญาต MIT
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
สนใจเลยไปดูว่าเดโม GIF ใน README สร้างอย่างไร: https://github.com/tamnd/kage/blob/01e75b87ecc893bbba7943c63...
ปรากฏว่าใช้โปรเจ็กต์อีกตัวของผู้เขียนคนเดียวกันคือ https://github.com/tamnd/ascii-gif
สคริปต์ที่ใช้ในเดโมอยู่ที่ https://github.com/tamnd/kage/blob/01e75b87ecc893bbba7943c63... และมีคอมเมนต์บอกวิธีรันไว้ด้วย:
ascii-gif render docs/demo/kage.tape -o docs/static/demo.gifดูเหมือนเป็นแรปเปอร์ที่ครอบ https://github.com/charmbracelet/vhs แบบมีสไตล์เฉพาะตัวมาก
$HOME/bin/ของผมก็มีไบนารีส่วนตัวแนวนี้อยู่พอสมควร เช่นdelete-all-npm,clean-rust-cache,download-youtube-playlist,get-markdownซึ่งดีตรงไม่ต้องจำคำสั่งบางครั้งเอเจนต์เขียนโค้ดก็หาวิธีเรียกใช้เครื่องมือพวกนี้ได้เองด้วย
ถ้าอยากให้เข้าถึงวิกิของบริษัทได้ง่ายแม้ตอนออฟไลน์ ก็อาจใช้สิ่งนี้ได้ เช่น อาจมีเอกสารที่มีประโยชน์อยู่ในวิกิสำหรับใช้หน้างานที่สัญญาณมือถือเข้าไม่ถึง
การรวมทั้งเว็บไซต์เป็นไบนารีเดียวได้ถือว่าเจ๋งมาก แต่จะดียิ่งขึ้นถ้ามีเวอร์ชันที่ไม่ต้องใช้ serving process แยกต่างหาก
ดูเหมือนว่าน่าจะทำเป็น shim ที่มีจุดเข้าใช้งานเป็น HTML ไฟล์เดียว พร้อม JavaScript เล็กน้อยสำหรับค้นดูคลังเนื้อหาของเว็บไซต์ในรูปแบบที่ฝังมาในตัวได้ด้วย
ในหัวผมมีสคริปต์/โปรแกรมสำหรับแปลง HTML เป็น Markdown อยู่แล้ว ดังนั้นจริง ๆ อาจเก็บทุกอย่างลงดิสก์เป็น โฟลเดอร์ไฟล์ Markdown แล้ว commit เข้า Git repository ไปเลยก็ได้
อันนี้ยอดเยี่ยมมาก ผมอยากได้วิธีรับต้นแบบของใครสักคนที่ทำจาก Lovable หรืออะไรทำนองนั้นมาเป็นสำเนาออฟไลน์ แล้ว จัดการเวอร์ชันและแชร์ ได้ในรูปแบบที่ง่ายกว่า
วิธีที่เราเข้าถึงปัญหานี้เขียนไว้ที่นี่: https://productnow.ai/blogs/extracting-html-from-ai-prototyp...
ตอนนี้จะลองดูอันนี้และดูว่าสามารถดัดแปลงบางส่วนได้ไหม ชอบไอเดียเรื่องออฟไลน์มิเรอร์ และทำให้กรณีใช้งานด้านการทำงานร่วมกันง่ายขึ้นมาก
มีตัวอย่าง
kage serve $HOME/data/kage/paulgraham.comแต่ถ้าผลลัพธ์เป็นไฟล์สแตติก ก็ไม่เข้าใจว่าทำไมยังต้องมีเซิร์ฟเวอร์ จำเป็นต้องทำให้เปิดในเบราว์เซอร์ได้ตรง ๆ ไม่ได้หรือ?เช่นถ้าทำให้ใช้แบบ
$ firefox $HOME/data/kage/paulgraham.comได้ ก็จะใช้ผลลัพธ์นี้ได้แม้บน เครื่องที่ไม่ได้ติดตั้ง kagepython -m http.serverแทนได้ ยังไม่ได้ลองแต่คิดว่าน่าจะใช้ได้จริง ๆ แล้ว Kage มีอยู่สองส่วน ส่วนหนึ่งคือ crawler ที่ crawl หน้าเว็บหลังจาก Chrome/Chromium เรนเดอร์เสร็จ แล้วจับ DOM มาแปลงเป็น HTML ที่สะอาด อีกส่วนคือองค์ประกอบ pack/serve ที่แพ็กผลลัพธ์เป็นไฟล์ ZIM สำหรับ Kiwix หรือเป็นไฟล์ปฏิบัติการ
มองว่า SingleFile [0] เป็นเวอร์ชันที่แข็งแกร่งกว่านี้มาก
มันลบ JavaScript ออกทั้งหมดด้วย แต่จะรวมทุกอย่างเป็น ไฟล์ HTML เดียว ที่ส่งต่อได้ง่าย
แอสเซ็ตไบนารีอย่างเว็บฟอนต์หรือรูปภาพจะถูกใส่เป็นสตริง base64
และยังมี CLI ที่ทำงานบน Puppeteer ให้ด้วย [1]
[0]: https://github.com/gildas-lormeau/singlefile
[1]: https://github.com/gildas-lormeau/single-file-cli
แต่สิ่งที่กำลังทำตรงนี้คือ การมิเรอร์ทั้งเว็บไซต์ รวมถึงหน้าย่อยด้วย เลยท่องดูได้ทั้งหมดแม้ออฟไลน์ เช่น เรียงความทั้งหมดบน paulgraham.com
แต่ถ้า Kage สามารถรวมคุณภาพการเก็บหน้าแบบ SingleFile เข้ากับแนวทางการไต่เว็บแบบ HTTPTrack ได้ ก็ดูมีอนาคตมาก แอปหน้าเดียว นั้นเก็บถาวรค่อนข้างยาก เลยสงสัยว่า Kage จะจัดการได้ดีแค่ไหน
File -> Save asในเว็บเบราว์เซอร์ทั่วไปบนคอมพิวเตอร์อย่างไร?ลองคัดลอกเว็บไซต์ที่เป็น HTTP คือไม่ใช่ HTTPS แล้ว แต่ขึ้น
navigation failed: net::ERR_NAME_NOT_RESOLVEDแม้จะระบุโปรโตคอลเป็นhttp://แล้วก็ยังเหมือนเดิมตอนดาวน์โหลดวิกิไว้อ่านบนเครื่องบิน ผมใช้ httrack(https://www.httrack.com) มาตลอด ไม่ได้สมบูรณ์แบบ แต่ก็ดีกว่าตัวอื่นที่เคยหาเจอมาก่อน
จะลองอันนี้เหมือนกัน และถ้าผลออกมาดีก็คงดีใจมาก
https://wiki.openzim.org/wiki/Build_your_ZIM_file
EDIT: https://get.kiwix.org/en/solutions/applications/kiwix-reader...
หลายปีมานี้ผมสะสมคลังเว็บไซต์เก่าไว้พอสมควร เรื่องน่าสนใจก็คือ HTML dump ที่หน้าตาไม่สวยกลับมีประโยชน์มากกว่าอาร์ไคฟ์ที่ “สมบูรณ์แบบ”
นี่ก็เป็นหนึ่งในเหตุผลที่ยิ่งนานไปผมยิ่งชอบ RSS เพราะฟีดที่อายุสัก 10 ปีมักใช้งานได้ง่ายกว่าเว็บไซต์แบบแอปพลิเคชันที่ถูกเก็บรักษาอย่างประณีตในปัจจุบัน
จัดระเบียบอีกนิดแล้วจะปล่อยเป็นโอเพนซอร์สเร็ว ๆ นี้
ดูเหมือนว่านี่อาจสร้างภาระให้เว็บไซต์ค่อนข้างมาก มีการตั้งค่าให้หน่วงความเร็วในการคัดลอก หรือหลีกเลี่ยงรูปภาพ/วิดีโอไหม?
แล้วก็สงสัยว่ามี วิธีดึงมาแค่บางส่วนของเว็บไซต์ หรือเปล่า
เป็นโปรเจ็กต์ที่เรียบร้อยดีและผมชอบไอเดียนี้
อ่านผ่าน ๆ เห็นว่าเปิด Chrome ด้วย
--no-sandboxมีเหตุผลอะไรเป็นพิเศษไหม? ในแง่ความปลอดภัยนี่อาจไม่ใช่ความคิดที่ดีนัก ถ้าไม่มีเหตุผลก็แนะนำให้เปิด sandbox ไว้ยังไงก็เป็นงานที่เจ๋งมาก
--no-sandboxจำเป็นใน Docker อาจจะตั้งต้นจากสมมติฐานว่าส่วนใหญ่จะ รันใน Docker ก็ได้?