Skip to content

Fix HizoManga showing no chapters - #269

Merged
Rojikku merged 5 commits into
NovelSourcery:mainfrom
hamedhani1998:fix/hizomanga-chapters
Oct 2, 2026
Merged

Rojikku merged 5 commits into
NovelSourcery:mainfrom
hamedhani1998:fix/hizomanga-chapters

Conversation

@hamedhani1998

Copy link
Copy Markdown
Contributor

Problem

The HizoManga source (hizomanga.net) returned an empty chapter list, so no chapters showed at all.

Cause

Madara normally fetches chapters from a separate ajax endpoint rather than from the novel page. On this host every chapter endpoint is rejected at the CDN:

Endpoint Result
POST /content/<id>/ajax/chapters/ 403 (nginx error_docs)
POST /ajax/chapters/?t=1 403
POST /wp-admin/admin-ajax.php + action=manga_get_chapters 400 (body 0)

Tried with a desktop browser UA, Referer, Origin, X-Requested-With, Sec-Fetch-*, and a cookie jar primed from the novel page — the 403 persists on every combination. The novel page itself returns 200 throughout, so this is a targeted block of the ajax paths, not of the site.

Fix

The novel page already renders the complete chapter list server-side, so the list is read straight from it:

override val useNewChapterEndpointDefault = false   // stop calling the blocked endpoint
override suspend fun fetchMangaUpdate(...)           // parse .wp-manga-chapter from the page HTML

Chapter parsing mirrors the theme's own logic — number-prefix stripping, relative URL normalisation, release-date parsing, and 🔒 marking of premium-block entries.

Verification

Simulated the parser against live pages:

Series Chapters in page Parsed
42898 239 (contiguous 1..239, no pagination) 239
42370 130 (contiguous 1..130) 130
183916 3 3
183858 0 (لم يتم نشر أي فصل بعد) 0, no crash

All parsed URLs are relative and well-formed. The 239-chapter list confirms the site does not paginate the chapter list, so a single page request is sufficient.

Note

mangaDetailsParse and parseChaptersFromHtml are private in the shared theme, so the detail parsing is mirrored locally (URLs taken from the existing SManga as fallback). This is scoped to src/ar/hizomanga — the shared madaranovel template is untouched.

🤖 Generated with Claude Code

hamedhani1998 and others added 5 commits September 26, 2026 09:27
Cloudflare answers every GalaxyNovels request with a hard WAF 403
("Sorry, you have been blocked"), not a solvable JS challenge, so
cf_clearance/WebView solving cannot help. Two independent request
signatures trigger it, both measured against the live site:

1. OkHttp's default `okhttp/x.y.z` User-Agent is rejected on every path.
   The source sent no User-Agent of its own, so the app-wide default was
   used and even list pages that the site serves fine to a real browser
   came back 403.
2. `Accept-Language` sent together with BOTH `Sec-Fetch-Dest: document`
   AND `Sec-Fetch-Mode: navigate`. Either Sec-Fetch header alone passes,
   and Accept-Language alone passes, but the combination does not.

The interceptor now pins a desktop Chrome User-Agent and stops sending
Sec-Fetch-Dest/Sec-Fetch-Mode. Referer and Origin already come from
KeiSource's headersBuilder(), so the hand-rolled copies in the interceptor
and in fetchPageText are gone - fetchPageText had the same broken set and
so 403'd on every chapter.

This also unblocks the chapter list: because the detail page 403'd, the
data-novel-id was never parsed, so the WorReader manifest/pack fetch never
ran and every novel fell back to the ~30 chapters in the detail page HTML.
With the detail page reachable, the manifest+pack path is used again and
returns the full list (verified: 790 chapters for one novel, 939 for
another). The legacy per-novel JSON endpoint is removed - it is now dead
(403 even with a browser UA), so it only cost a wasted request.

Finally, fetchPageText looked for WordPress-style containers, none of
which exist on the current WorReader theme, so it fell through to <article>
and returned the whole page. It now selects `div.wor-reader-text-surface`,
the reader's actual text container (verified: 52 paragraphs, ~6.4k chars),
keeping the old selectors as a fallback.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Reading a chapter showed sentences that are not part of the novel. The
site interleaves anti-piracy notice lines *inside* the chapter body --
"اقرأ من galaxynovels.com", "لا تدعم من يسرق الروايات وينسبها لنفسه" and
rotations of the same idea -- one every few paragraphs. They are plain
inline elements (<small>/<b>/<i>) that a real browser hides, so the site
itself never shows them, but a raw HTML scrape keeps them.

Each carries data-wor-decoy="1" plus hidden/aria-hidden="true" and an
inline style that collapses it to zero size, so on the measured chapter
17 of the 69 children of div.wor-reader-text-surface were decoys: 1323 of
7667 characters, roughly 17% of the extracted text.

Dropped by attribute rather than by wording, since the site rotates the
sentence. data-wor-decoy is the theme's own marker and is matched first;
the accessibility attributes are kept as a fallback in case a future theme
drops it. No real prose carries these attributes, so all 52 real
paragraphs survive.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
hizomanga.net rejects every Madara chapter endpoint at the CDN:
POST /content/<id>/ajax/chapters/ answers 403 and the legacy
admin-ajax.php?action=manga_get_chapters answers 400, so the shared
implementation returned an empty list.

The novel page itself answers 200 and already renders the complete list
into .listing-chapters_wrap .wp-manga-chapter, so parse it from there
instead. Verified on a 239-chapter series (contiguous 1..239 in the
initial HTML, no pagination), a 130-chapter one, a 3-chapter one, and
a series with no chapters yet.

Co-Authored-By: Claude <noreply@anthropic.com>
@Rojikku
Rojikku merged commit e8544f6 into NovelSourcery:main Oct 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants