Krixter commited on
Commit
b094e4a
·
verified ·
1 Parent(s): fdec6bc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -11
app.py CHANGED
@@ -64,9 +64,15 @@ def extract_synopsis(description: str) -> str:
64
 
65
 
66
  def extract_title_and_description(html: str) -> tuple[str, str]:
67
- """Pull the best available title and synopsis/description from a page's HTML."""
 
 
 
 
 
68
  soup = BeautifulSoup(html, "html.parser")
69
 
 
70
  title = ""
71
  og_title = soup.find("meta", property="og:title")
72
  if og_title and og_title.get("content"):
@@ -74,20 +80,47 @@ def extract_title_and_description(html: str) -> tuple[str, str]:
74
  if not title and soup.title and soup.title.string:
75
  title = soup.title.string.strip()
76
 
77
- description = ""
78
- meta_desc = soup.find("meta", attrs={"name": "description"})
79
- if meta_desc and meta_desc.get("content"):
80
- description = meta_desc["content"].strip()
81
- if not description:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  og_desc = soup.find("meta", property="og:description")
83
  if og_desc and og_desc.get("content"):
84
- description = og_desc["content"].strip()
85
 
86
- # Keep everything on a single line in the combined output
87
- title = re.sub(r"\s+", " ", title)
88
- description = re.sub(r"\s+", " ", description)
89
 
90
- synopsis = extract_synopsis(description)
91
  return title, synopsis
92
 
93
 
 
64
 
65
 
66
  def extract_title_and_description(html: str) -> tuple[str, str]:
67
+ """Pull the best available title and synopsis/description from a page's HTML.
68
+
69
+ For WebNovel pages the meta description is deliberately truncated with '...'.
70
+ The full synopsis lives inside a <div class="... j_synopsis ..."> in the body.
71
+ We prefer that element; the meta tags are only a fallback for other sites.
72
+ """
73
  soup = BeautifulSoup(html, "html.parser")
74
 
75
+ # --- Title ---
76
  title = ""
77
  og_title = soup.find("meta", property="og:title")
78
  if og_title and og_title.get("content"):
 
80
  if not title and soup.title and soup.title.string:
81
  title = soup.title.string.strip()
82
 
83
+ # --- Synopsis: try full body element first (WebNovel and similar sites) ---
84
+ synopsis = ""
85
+
86
+ # 1. WebNovel: <div class="... j_synopsis ...">
87
+ j_syn = soup.find(class_=lambda c: c and "j_synopsis" in c.split())
88
+ if j_syn:
89
+ # Replace <br> tags with newlines before extracting text
90
+ for br in j_syn.find_all("br"):
91
+ br.replace_with("\n")
92
+ # Remove the "read more" toggle span that WebNovel appends
93
+ for rm in j_syn.find_all("span", class_="_readmore"):
94
+ rm.decompose()
95
+ synopsis = j_syn.get_text(separator=" ").strip()
96
+
97
+ # 2. Fallback: any element whose class contains common synopsis keywords
98
+ if not synopsis:
99
+ for cls_hint in ("book-intro", "book_intro", "bookIntro",
100
+ "detail-desc", "book-desc", "bookDesc",
101
+ "synopsis", "j_intro"):
102
+ el = soup.find(class_=lambda c: c and cls_hint in c)
103
+ if el:
104
+ for br in el.find_all("br"):
105
+ br.replace_with("\n")
106
+ synopsis = el.get_text(separator=" ").strip()
107
+ if synopsis:
108
+ break
109
+
110
+ # 3. Last resort: meta tags (always truncated on WebNovel, but better than nothing)
111
+ if not synopsis:
112
+ meta_desc = soup.find("meta", attrs={"name": "description"})
113
+ if meta_desc and meta_desc.get("content"):
114
+ synopsis = extract_synopsis(meta_desc["content"].strip())
115
+ if not synopsis:
116
  og_desc = soup.find("meta", property="og:description")
117
  if og_desc and og_desc.get("content"):
118
+ synopsis = extract_synopsis(og_desc["content"].strip())
119
 
120
+ # Normalise whitespace: collapse runs of spaces/tabs but keep newlines
121
+ title = re.sub(r"[ \t]+", " ", title).strip()
122
+ synopsis = re.sub(r"[ \t]+", " ", synopsis).strip()
123
 
 
124
  return title, synopsis
125
 
126