diff --git a/docs/supportedsites.md b/docs/supportedsites.md
index 47820537..2a77c006 100644
--- a/docs/supportedsites.md
+++ b/docs/supportedsites.md
@@ -667,6 +667,12 @@ Consider all listed sites to potentially be NSFW.
Chapters, Manga |
|
+
+ | MangaFreak |
+ https://ww2.mangafreak.me/ |
+ Chapters, Manga |
+ |
+
| MangaPark |
https://mangapark.net/ |
diff --git a/gallery_dl/extractor/__init__.py b/gallery_dl/extractor/__init__.py
index 4ec16766..5990fa7a 100644
--- a/gallery_dl/extractor/__init__.py
+++ b/gallery_dl/extractor/__init__.py
@@ -127,6 +127,7 @@ modules = [
"mangadex",
"mangafire",
"mangafox",
+ "mangafreak",
"mangahere",
"manganelo",
"mangapark",
diff --git a/gallery_dl/extractor/mangafreak.py b/gallery_dl/extractor/mangafreak.py
new file mode 100644
index 00000000..4e015563
--- /dev/null
+++ b/gallery_dl/extractor/mangafreak.py
@@ -0,0 +1,85 @@
+# -*- 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://ww2.mangafreak.me/"""
+
+from .common import ChapterExtractor, MangaExtractor
+from .. import text
+
+BASE_PATTERN = r"(?:https?://)?(?:ww[\dw]\.)?mangafreak\.me"
+
+
+class MangafreakBase():
+ """Base class for mangafreak extractors"""
+ category = "mangafreak"
+ root = "https://ww2.mangafreak.me"
+
+
+class MangafreakChapterExtractor(MangafreakBase, ChapterExtractor):
+ """Extractor for mangafreak manga chapters"""
+ pattern = BASE_PATTERN + r"(/Read1_([^/?#]+)_((\d+)([a-z])?))"
+ example = "https://ww2.mangafreak.me/Read1_Onepunch_Man_1"
+
+ def metadata(self, page):
+ manga = text.extr(page, "Read ", " Chapter ")
+ title = text.extr(page, 'selected="selected">', "<").partition(": ")[2]
+ _, manga_slug, chapter_string, chapter, minor = self.groups
+
+ return {
+ "manga" : text.unescape(manga),
+ "manga_slug" : manga_slug,
+ "title" : text.unescape(title) if title else "",
+ "chapter" : text.parse_int(chapter),
+ "chapter_minor": "" if minor is None else minor,
+ "chapter_string": chapter_string,
+ "lang" : "en",
+ "language" : "English",
+ }
+
+ def images(self, page):
+ base = "https://images.mangafreak.me/mangas/"
+ return [
+ (base + path, None)
+ for path in text.extract_iter(page, 'src="' + base, '"')
+ ]
+
+
+class MangafreakMangaExtractor(MangafreakBase, MangaExtractor):
+ """Extractor for mangafreak manga series"""
+ chapterclass = MangafreakChapterExtractor
+ pattern = BASE_PATTERN + r"(/Manga/([^/?#]+))"
+ example = "https://ww2.mangafreak.me/Manga/Onepunch_Man"
+
+ def chapters(self, page):
+ table = text.extr(page, "")
+ if not table:
+ return ()
+
+ data = {
+ "manga" : text.unescape(text.extr(page, "", " Manga")),
+ "manga_slug": self.groups[1],
+ "lang" : "en",
+ "language" : "English",
+ }
+
+ results = []
+ chapter_match = text.re(r"(\d+)(\w*)").match
+ for row in text.extract_iter(table, "", "
"):
+ href = text.extr(row, '', '<').partition(" - ")[2]
+ results.append((url, {
+ "chapter" : text.parse_int(chapter),
+ "chapter_minor" : minor,
+ "chapter_string": chapter_string,
+ "title" : text.unescape(title) if title else "",
+ **data,
+ }))
+ return results
diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py
index a731d171..9a167a45 100755
--- a/scripts/supportedsites.py
+++ b/scripts/supportedsites.py
@@ -115,6 +115,7 @@ CATEGORY_MAP = {
"kabeuchi" : "かべうち",
"kaliscan" : "KaliScan",
"mangafire" : "MangaFire",
+ "mangafreak" : "MangaFreak",
"mangareader" : "MangaReader",
"mangataro" : "MangaTaro",
"s3ndpics" : "S3ND",
diff --git a/test/results/mangafreak.py b/test/results/mangafreak.py
new file mode 100644
index 00000000..0478f8aa
--- /dev/null
+++ b/test/results/mangafreak.py
@@ -0,0 +1,95 @@
+# -*- 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.
+
+from gallery_dl.extractor import mangafreak
+
+
+__tests__ = (
+{
+ "#url" : "https://ww2.mangafreak.me/Read1_Onepunch_Man_1",
+ "#class" : mangafreak.MangafreakChapterExtractor,
+ "#pattern" : r"https://images\.mangafreak\.me/mangas/onepunch_man/onepunch_man_1/onepunch_man_1_\d+\.jpg",
+ "#count" : 24,
+
+ "chapter" : 1,
+ "chapter_minor": "",
+ "chapter_string": "1",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Onepunch Man",
+ "manga_slug" : "Onepunch_Man",
+},
+
+{
+ "#url" : "https://ww2.mangafreak.me/Read1_Onepunch_Man_167e",
+ "#class" : mangafreak.MangafreakChapterExtractor,
+
+ "chapter" : 167,
+ "chapter_minor": "e",
+ "chapter_string": "167e",
+},
+
+{
+ "#url" : "https://ww2.mangafreak.me/Read1_Sss_Rank_Dungeon_De_Knife_Ippon_Tewatasare_Tsuihou_Sareta_Shiro_Madoushi_Yggdrasil_No_Noroi_Ni_Yori_Jakuten_De_Aru_Maryoku_Fusoku_Wo_Kokufuku_Shi_Sekai_Saikyou_E_To_Itaru_23c",
+ "#class" : mangafreak.MangafreakChapterExtractor,
+ "#pattern" : r"https://images\.mangafreak\.me/mangas/sss_rank_dungeon_de_knife_ippon_tewatasare_tsuihou_sareta_shiro_madoushi_yggdrasil_no_noroi_ni_yori_jakuten_de_aru_maryoku_fusoku_wo_kokufuku_shi_sekai_saikyou_e_to_itaru/sss_rank_dungeon_de_knife_ippon_tewatasare_tsuihou_sareta_shiro_madoushi_yggdrasil_no_noroi_ni_yori_jakuten_de_aru_maryoku_fusoku_wo_kokufuku_shi_sekai_saikyou_e_to_itaru_23c/sss_rank_dungeon_de_knife_ippon_tewatasare_tsuihou_sareta_shiro_madoushi_yggdrasil_no_noroi_ni_yori_jakuten_de_aru_maryoku_fusoku_wo_kokufuku_shi_sekai_saikyou_e_to_itaru_23c_\d+\.jpg",
+ "#count" : 11,
+
+ "chapter" : 23,
+ "chapter_minor" : "c",
+ "chapter_string": "23c",
+ "count" : 11,
+ "page" : range(1, 11),
+ "filename" : str,
+ "extension" : "jpg",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Sss Rank Dungeon De Knife Ippon Tewatasare Tsuihou Sareta Shiro Madoushi Yggdrasil No Noroi Ni Yori Jakuten De Aru Maryoku Fusoku Wo Kokufuku Shi Sekai Saikyou E To Itaru",
+ "manga_slug" : "Sss_Rank_Dungeon_De_Knife_Ippon_Tewatasare_Tsuihou_Sareta_Shiro_Madoushi_Yggdrasil_No_Noroi_Ni_Yori_Jakuten_De_Aru_Maryoku_Fusoku_Wo_Kokufuku_Shi_Sekai_Saikyou_E_To_Itaru",
+ "title" : "",
+},
+
+{
+ "#url" : "https://ww2.mangafreak.me/Read1_Tensei_Shitara_Slime_Datta_Ken_62",
+ "#class" : mangafreak.MangafreakChapterExtractor,
+ "#count" : 19,
+
+ "chapter" : 62,
+ "count" : 19,
+ "manga" : "Tensei Shitara Slime Datta Ken",
+ "title" : "To be a Monster or Human",
+},
+
+{
+ "#url" : "https://ww2.mangafreak.me/Manga/Onepunch_Man",
+ "#class" : mangafreak.MangafreakMangaExtractor,
+ "#pattern" : mangafreak.MangafreakChapterExtractor.pattern,
+ "#count" : range(150, 250),
+
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Onepunch-Man",
+ "manga_slug" : "Onepunch_Man",
+ "chapter" : int,
+},
+
+{
+ "#url" : "https://ww2.mangafreak.me/Manga/Sss_Rank_Dungeon_De_Knife_Ippon_Tewatasare_Tsuihou_Sareta_Shiro_Madoushi_Yggdrasil_No_Noroi_Ni_Yori_Jakuten_De_Aru_Maryoku_Fusoku_Wo_Kokufuku_Shi_Sekai_Saikyou_E_To_Itaru",
+ "#class" : mangafreak.MangafreakMangaExtractor,
+ "#pattern" : mangafreak.MangafreakChapterExtractor.pattern,
+ "#count" : range(40, 80),
+
+ "chapter" : int,
+ "chapter_minor" : {"", "a", "b", "c"},
+ "chapter_string": str,
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "SSS Rank Dungeon de Knife Ippon Tewatasare Tsuihou Sareta Shiro Madoushi: Yggdrasil no Noroi ni yori Jakuten de aru Maryoku Fusoku wo Kokufuku-shi Sekai Saikyou e to Itaru",
+ "manga_slug" : "Sss_Rank_Dungeon_De_Knife_Ippon_Tewatasare_Tsuihou_Sareta_Shiro_Madoushi_Yggdrasil_No_Noroi_Ni_Yori_Jakuten_De_Aru_Maryoku_Fusoku_Wo_Kokufuku_Shi_Sekai_Saikyou_E_To_Itaru",
+ "title" : str,
+},
+
+)