diff --git a/docs/supportedsites.md b/docs/supportedsites.md
index cd9d5675..d8cf7aa6 100644
--- a/docs/supportedsites.md
+++ b/docs/supportedsites.md
@@ -529,6 +529,12 @@ Consider all sites to be NSFW unless otherwise known.
Chapters, Manga |
|
+
+ | MangaRead |
+ https://mangaread.org/ |
+ Chapters, Manga |
+ |
+
| MangaSee |
https://mangasee123.com/ |
diff --git a/gallery_dl/extractor/__init__.py b/gallery_dl/extractor/__init__.py
index 5475fea6..049732f6 100644
--- a/gallery_dl/extractor/__init__.py
+++ b/gallery_dl/extractor/__init__.py
@@ -92,6 +92,7 @@ modules = [
"mangakakalot",
"manganelo",
"mangapark",
+ "mangaread",
"mangasee",
"mangoxo",
"misskey",
diff --git a/gallery_dl/extractor/mangaread.py b/gallery_dl/extractor/mangaread.py
new file mode 100644
index 00000000..4af90e09
--- /dev/null
+++ b/gallery_dl/extractor/mangaread.py
@@ -0,0 +1,189 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+"""Extractors for https://mangaread.org/"""
+
+from .common import ChapterExtractor, MangaExtractor
+from .. import text, exception
+import re
+
+
+class MangareadBase():
+ """Base class for Mangaread extractors"""
+ category = "mangaread"
+ root = "https://www.mangaread.org"
+
+ @staticmethod
+ def parse_chapter_string(chapter_string, data):
+ match = re.match(
+ r"(?:(.+)\s*-\s*)?[Cc]hapter\s*(\d+)(\.\d+)?(?:\s*-\s*(.+))?",
+ text.unescape(chapter_string).strip())
+ manga, chapter, minor, title = match.groups()
+ manga = manga.strip() if manga else ""
+ data["manga"] = data.pop("manga", manga)
+ data["chapter"] = text.parse_int(chapter)
+ data["chapter_minor"] = minor or ""
+ data["title"] = title or ""
+ data["lang"] = "en"
+ data["language"] = "English"
+
+
+class MangareadChapterExtractor(MangareadBase, ChapterExtractor):
+ """Extractor for manga-chapters from mangaread.org"""
+ pattern = (r"(?:https?://)?(?:www\.)?mangaread\.org"
+ r"(/manga/[^/?#]+/[^/?#]+)")
+ test = (
+ ("https://www.mangaread.org/manga/one-piece/chapter-1053-3/", {
+ "pattern": (r"https://www\.mangaread\.org/wp-content/uploads"
+ r"/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+"),
+ "count": 11,
+ "keyword": {
+ "manga" : "One Piece",
+ "title" : "",
+ "chapter" : 1053,
+ "chapter_minor": ".3",
+ "tags" : ["Oda Eiichiro"],
+ "lang" : "en",
+ "language": "English",
+ }
+ }),
+ ("https://www.mangaread.org/manga/one-piece/chapter-1000000/", {
+ "exception": exception.NotFoundError,
+ }),
+ (("https://www.mangaread.org"
+ "/manga/kanan-sama-wa-akumade-choroi/chapter-10/"), {
+ "pattern": (r"https://www\.mangaread\.org/wp-content/uploads"
+ r"/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+"),
+ "count": 9,
+ "keyword": {
+ "manga" : "Kanan-sama wa Akumade Choroi",
+ "title" : "",
+ "chapter" : 10,
+ "chapter_minor": "",
+ "tags" : list,
+ "lang" : "en",
+ "language": "English",
+ }
+ }),
+ # 'Chapter146.5'
+ # ^^ no whitespace
+ ("https://www.mangaread.org/manga/above-all-gods/chapter146-5/", {
+ "pattern": (r"https://www\.mangaread\.org/wp-content/uploads"
+ r"/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+"),
+ "count": 6,
+ "keyword": {
+ "manga" : "Above All Gods",
+ "title" : "",
+ "chapter" : 146,
+ "chapter_minor": ".5",
+ "tags" : list,
+ "lang" : "en",
+ "language": "English",
+ }
+ }),
+ )
+
+ def metadata(self, page):
+ data = {"tags": list(text.extract_iter(page, 'class="">', "<"))}
+ info = text.extr(page, '', "
")
+ if not info:
+ raise exception.NotFoundError("chapter")
+ self.parse_chapter_string(info, data)
+ return data
+
+ def images(self, page):
+ page = text.extr(
+ page, '', '", page.index("summary__content"))[0])),
+ "rating" : text.parse_float(
+ extr('total_votes">', "").strip()),
+ "manga_alt" : text.remove_html(
+ extr("Alternative \n
", "")).split("; "),
+ "author" : list(text.extract_iter(
+ extr('class="author-content">', ""), '"tag">', "")),
+ "artist" : list(text.extract_iter(
+ extr('class="artist-content">', ""), '"tag">', "")),
+ "genres" : list(text.extract_iter(
+ extr('class="genres-content">', ""), '"tag">', "")),
+ "type" : text.remove_html(
+ extr("Type \n", "")),
+ "release" : text.parse_int(text.remove_html(
+ extr("Release \n", ""))),
+ "status" : text.remove_html(
+ extr("Status \n", "")),
+ }
diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py
index e38771a1..034a4d3b 100755
--- a/scripts/supportedsites.py
+++ b/scripts/supportedsites.py
@@ -77,6 +77,7 @@ CATEGORY_MAP = {
"mangalife" : "MangaLife",
"manganelo" : "Manganato",
"mangapark" : "MangaPark",
+ "mangaread" : "MangaRead",
"mangasee" : "MangaSee",
"mastodon.social": "mastodon.social",
"mememuseum" : "meme.museum",