1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/** @jsxImportSource https://esm.sh/react */
import React, { useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
//last stable version is 47
function App() {
const [url, setUrl] = useState("");
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
console.log(`Submitting URL for scraping: ${url}`);
const maxRetries = 3;
let retries = 0;
while (retries < maxRetries) {
try {
const response = await fetch("/scrape", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ url }),
});
console.log(`Received response for URL: ${url}. Status: ${response.status}`);
if (!response.ok) {
if (response.status === 404) {
setResult({ error: "The requested URL was not found. Please check the URL and try again." });
} else if (response.status === 500) {
setResult({ error: "The server encountered an error. Please try again later." });
} else {
throw new Error(`HTTP error! status: ${response.status}`);
}
} else {
const data = await response.json();
setResult(data);
}
break; // Exit the loop if successful
} catch (error) {
console.log(`Error occurred while scraping URL: ${url}. Error details: ${error.message}`);
if (error.name === 'TypeError' && error.message === 'Failed to fetch') {
setResult({ error: "Network error. Please check your internet connection and try again." });
} else if (retries === maxRetries - 1) {
setResult({ error: `An unexpected error occurred: ${error.message}. Please try again later.` });
}
retries++;
if (retries < maxRetries) {
console.log(`Retrying... Attempt ${retries + 1} of ${maxRetries}`);
await new Promise(resolve => setTimeout(resolve, 1000 * retries)); // Wait before retrying
}
}
}
setLoading(false);
};
return (
<div>
<h1>FanFic Scraper</h1>
<form onSubmit={handleSubmit}>
<input
type="url"
value={url}
onChange={(e) => setUrl(e.target.value)}
placeholder="Enter URL to scrape"
required
/>
<button type="submit" disabled={loading}>
{loading ? "Scraping..." : "Scrape"}
</button>
</form>
{result && (
<div>
<h2>Result:</h2>
<h3>{result.title}</h3>
<h3>Content:</h3>
<div dangerouslySetInnerHTML={{ __html: result.content }} />
<h3>Chapters:</h3>
<ul>
{result.articles && result.articles.map((article, index) => (
<li key={index}>
<p>Threadmark: {article.threadmark}</p>
<p>Date: {article.date}</p>
<p>Author: {article.author}</p>
<div dangerouslySetInnerHTML={{ __html: article.content }} />
</li>
))}
</ul>
{result.error && <p>Error: {result.error}</p>}
</div>
)}
</div>
);