Weebly 網誌匯出:為何 ZIP 封存檔沒有網誌,以及如何列出缺失頁面
Exporting a Weebly blog: why the archive ZIP skips it, and how to list what's missing
Weebly 的網站封存檔不包含網誌文章或商店頁面,但可能保留指向這些頁面的連結;文章説明轉換器如何識別並確認缺失頁面。用戶可用 grep 列出封存檔中的網誌和商店連結,再逐一檢查目標是否存在。這些方法只能找出缺失頁面,不能從 ZIP 封存檔還原文章。
Weebly's site archive (Settings → General → Archive) doesn't contain your blog. Weebly says so on its Back Up Your Site page (last updated 2020-09-10, read 2026-10-26):
Blog and store pages aren’t included in the export as they rely directly on our database. Also, some components of your site may not work correctly outside of the Weebly editor, like the Contact Form and Slideshow elements.
The pages that link to the blog are still in the archive, though. So the menu in your exported index.html still has a Blog link, and the page it points to isn't in the ZIP. This post shows how our converter finds those links, and how to do the same with grep.
The deadline, if you're in one of the 67 countries
Weebly's global operations notice (last updated 2026-08-10, read 2026-10-26) says sites there "will be unpublished on 2026-09-27" and that "You will still have access to your Weebly account until 2026-12-26". Before that date it says to:
Download your site content and data from Account Settings > My Data > Download My Data to migrate your content to another website provider or to retain it for your records. [...] If you wish to just download data from a specific site in your account, you may also do so from Website > Edit Site > Settings > Archive
The notice doesn't say what the Download My Data package contains. If you need the blog posts, request it and check. It's also a different layout from the site archive, and our converter doesn't accept it. Its error text says: "An account-level “Download My Data” package is a different layout, and this tool cannot turn it into a website."
What a dangling blog link looks like
We have a real archive from our own four-page test site. It has no blog or store, so it can't show this. The synthetic fixture in our tests (tests/weebly/make-fixture.ts) has both, as plain menu links:
<li class="wsite-menu-item-wrap"><a href="/blog" class="wsite-menu-item">Blog</a></li>
<li class="wsite-menu-item-wrap"><a href="http://demo-garden.weebly.com/store" class="wsite-menu-item">Store</a></li>
One link is root-relative and one is absolute, pointing at the site's own weebly.com host. Neither target page exists in the ZIP.
Classifying the link
lib/weebly/paths.ts strips the query, the hash and any scheme and host, then matches on path segments:
export function looksBlog(href: string): boolean {
const path = href.split("?")[0]!.split("#")[0]!.replace(/^https?:\/\/[^/]+/i, "");
return /(?:^|\/)blog(?:\/|\.html?|$)/i.test(path);
}
export function looksStore(href: string): boolean {
const path = href.split("?")[0]!.split("#")[0]!.replace(/^https?:\/\/[^/]+/i, "");
return /(?:^|\/)(store|product)(?:s)?(?:\/|\.html?|$)/i.test(path);
}
Hrefs come from a plain regex over the HTML. It skips #…, mailto:, tel: and javascript: links:
export function collectInternalHrefs(html: string): string[] {
const out: string[] = [];
const re = /\bhref\s*=\s*["']([^"']+)["']/gi;
let m: RegExpExecArray | null;
while ((m = re.exec(html))) {
const href = m[1]!.trim();
if (!href || href.startsWith("#") || href.startsWith("mailto:") || href.startsWith("tel:")) {
continue;
}
if (/^javascript:/i.test(href)) continue;
out.push(href);
}
return out;
}
Checking whether the target exists
A blog-looking path isn't missing by itself. A page called blog.html could be in the archive. recordMissing() in lib/weebly/transform-html.ts resolves each href against the files in the ZIP first:
function recordMissing(html: string, ctx: TransformContext): void {
const seen = new Set<string>();
for (const href of collectInternalHrefs(html)) {
const blog = looksBlog(href);
const store = looksStore(href);
const target = resolveLocalTarget(href, ctx.filePath, ctx.hosts, ctx.pages);
const present =
!!target &&
(ctx.pages.has(target) ||
ctx.files.has(target) ||
ctx.pages.has(target.replace(/\/$/, "/index.html")));
if (blog && !present && !seen.has(href)) {
seen.add(href);
ctx.report.missingBlog.push(href);
ctx.report.missingPages.push({ href, note: "not in your archive" });
continue;
}
// same for store, then any other internal .html link that isn't present
}
}
resolveLocalTarget() handles the absolute form. It parses the URL and treats it as local only if the hostname is one of the site's own hosts. Otherwise it returns null, and the link counts as external. Root-relative and relative hrefs are resolved from the current file's folder.
The hrefs land in the generated RESCUE-REPORT.html under "Missing blog posts" and "Missing store / products". Above that, the report shows the fixed note: "The site-archive export does not include blog posts or store pages. This tool cannot recover them."
The test runs the synthetic fixture and asserts both lists:
it("reports missing blog, store, forms, App Center widgets, and swf files", async () => {
const result = await runArchive();
assert.ok(result.report.missingBlog.some((h) => /blog/i.test(h)));
assert.ok(result.report.missingStore.some((h) => /store/i.test(h)));
// ...
const reportPage = new TextDecoder().decode(result.files["RESCUE-REPORT.html"]);
assert.match(reportPage, /not in your archive|Missing blog/i);
});
By hand
List the blog and store links in every page, using the same path rule:
unzip -q weebly-archive.zip -d site
grep -rhoE 'href="[^"]+"' site --include='*.html' \
| sed -E 's/^href="//; s/"$//' \
| grep -iE '(^|/)(blog|stores?|products?)(/|\.html?|$)' \
| sort -u
Unlike the TypeScript, this doesn't strip ?query or #hash first, so /blog?page=2 won't match. Check each result against the files in site/. Anything that isn't there is a page you have to get some other way. On our own real archive, which has no blog, the pipeline prints nothing.
What the code can't do
It lists missing pages. It doesn't recover them. The posts aren't in the archive, so no converter working from that ZIP can bring them back. If the blog matters, request Download My Data before your access ends, and check it for your posts.
Our free browser tool runs this check and turns the rest of the archive into a static site: https://archive-to-static.pages.dev/?utm_source=devto&utm_medium=article&utm_campaign=weebly-blog-archive
Written with AI assistance from our own source code, tests and test export, and Weebly's help pages, and checked against them.
來源:DEV Community · dev.to