PDF変換で得た汚いHTMLからきれいなリンクがほしい
Thank you, ChatGPT!
PDFからの変換でHTMLを得ると、そのHTMLではリンクが崩壊していたりします。
アンカーテキストのないリンク要素がposition: absoluteで表示されていて、アンカーテキストと分離されているなど。
そこで、HTML上での座標をもとに本来のアンカーテキストを特定し、本来のリンクをなるべく再現するコードを書いてみました。
既知の問題
ほとんどテストしていません。
既存のウェブサイトでも一応使えるみたいです。
用途はあまりなさそうですが。。。
code:script.js
function getLinkedText() {
let anchors = document.querySelectorAll("a");
let results = [];
for (let anchor of anchors) {
let combinedText = "";
// アンカーの子要素ごとに処理を適用
anchor.childNodes.forEach((child) => {
let textContent = "";
if (
child.nodeType === Node.TEXT_NODE &&
child.textContent.trim() !== ""
) {
textContent = child.textContent.trim();
} else if (child.nodeType === Node.ELEMENT_NODE) {
let rect = child.getBoundingClientRect();
let elementsAtPosition = document.elementsFromPoint(
rect.left + rect.width / 2,
rect.top + rect.height / 2
);
let textElement = Array.from(elementsAtPosition).find(
(e) => e.textContent.trim() !== ""
);
if (textElement) {
for (let node of textElement.childNodes) {
if (node.nodeType === Node.TEXT_NODE) {
textContent += node.data.trim();
} else if (
node.nodeType === Node.ELEMENT_NODE &&
/^\s*$/.test(node.textContent)
) {
continue;
} else {
break;
}
}
}
}
if (textContent) {
combinedText += textContent.trim();
}
});
if (combinedText) {
results.push({
anchor: anchor,
text: combinedText.trim(),
});
}
}
return results;
}
function makeAnchorsfromDirty() {
let linkedData = getLinkedText();
const anchors = [];
for (let data of linkedData) {
let anchor = document.createElement("a");
anchor.href = data.anchor.href;
anchor.textContent = data.text;
anchors.push(anchor);
}
return anchors;
}
function main() {
let anchors = makeAnchorsfromDirty();
let htmlString = `
<html>
<head>
<title>Extracted Anchors</title>
<meta charset="UTF-8">
</head>
<body>
`;
anchors.forEach((anchor) => {
htmlString += anchor.outerHTML + "<br>";
});
htmlString += "</body></html>";
let blob = new Blob(htmlString, { type: "text/html;charset=utf-8" }); // charset=utf-8 を追加 let blobURL = URL.createObjectURL(blob);
window.open(blobURL, "_blank");
}
main(); // main関数を実行