Merge pull request #170 from Techwolfy/upstream-misc-fixes

Add 6 comics, fix 10 others
This commit is contained in:
Tobias Gruetzmacher 2020-08-19 12:19:03 +02:00 committed by GitHub
commit 550c8d8e8b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 191 additions and 63 deletions

View file

@ -101,8 +101,9 @@ class Beetlebum(_BasicScraper):
class Bethellium(_WPWebcomic):
stripUrl = 'http://dbcomics.darkblueworkshop.com/bethellium/%s/'
firstStripUrl = stripUrl % 'chapter-1/webcomic-bethellium-chapter-1-cover'
firstStripUrl = stripUrl % 'chapter-1/cover'
url = firstStripUrl
latestSearch = '//main' + _WPWebcomic.latestSearch
starter = indirectStarter
def getPrevUrl(self, url, data):

View file

@ -215,6 +215,7 @@ class ComicFury(_ParserScraper):
cls('BioSyte', 'biosyte'),
cls('Birdman', 'birdman'),
cls('BlankLifeInsertPlayerRokulily', 'blanklife'),
cls('BlackTapestries', 'blacktapestries', adult=True),
cls('BlitzPhoenix', 'blinix'),
cls('BlobWorld', 'blobworld'),
cls('BloodLegaciesEternity', 'bloodlegacieseternity'),
@ -445,6 +446,7 @@ class ComicFury(_ParserScraper):
cls('FrostFire', 'frostfire'),
cls('FullmetalBrothers', 'fullmetalbrothers', 'es'),
cls('FurAndN3rdy', 'furnerdy'),
cls('FurryExperience', 'furryexperience'),
cls('Fusion', 'fusion'),
cls('FutureRegrets', 'futureregrets'),
cls('FuzzballAndScuzzball', 'fuzzballandscuzzball'),
@ -644,6 +646,7 @@ class ComicFury(_ParserScraper):
cls('LuckyHazard', 'luckyhazard'),
cls('Lukewarm', 'lukewarm'),
cls('LunaStar', 'lunastar'),
cls('LustAndIre', 'lustandire', adult=True),
cls('MadGirl', 'madgirl'),
cls('MagicElDesencuentro', 'magiceldesencuentro', 'es'),
cls('MagicTheScattering', 'magicthescattering'),
@ -1038,6 +1041,7 @@ class ComicFury(_ParserScraper):
cls('TheQuantumKid', 'thequantumkid'),
cls('TheQuestForCoitus', 'acomicstudios'),
cls('TheRathNexus', 'rath'),
cls('TheRealmOfKaerwyn', 'kaerwyn'),
cls('TheRebels', 'rebels'),
cls('TheRedeemers', 'theredeemers'),
cls('TheRestlessDead', 'therestlessdead'),

View file

@ -133,8 +133,8 @@ class DerTodUndDasMaedchen(_ParserScraper):
class DesertFox(_WPWebcomic):
url = 'https://www.desertfoxcomics.net/'
stripUrl = url + 'desertfox/comic/%s/'
url = 'https://desertfoxcomics.net/'
stripUrl = url + 'comics/%s/'
firstStripUrl = stripUrl % 'origins-1'
def namer(self, imageUrl, pageUrl):

View file

@ -41,13 +41,22 @@ class LastResort(_WordPressScraper):
class LazJonesAndTheMayfieldRegulators(_ParserScraper):
url = 'https://www.lazjones.com/'
stripUrl = url + 'comic/%s'
baseUrl = 'https://www.lazjones.com/'
url = baseUrl + 'regulators'
stripUrl = baseUrl + 'comic/%s'
firstStripUrl = stripUrl % 'chapter1_00'
imageSearch = '//img[contains(@src, "comic/pages/")]'
prevSearch = '//a[contains(text(), "Previous")]'
class LazJonesAndTheMayfieldRegulatorsSideStories(LazJonesAndTheMayfieldRegulators):
name = 'LazJonesAndTheMayfieldRegulators/SideStories'
baseUrl = 'https://www.lazjones.com/'
url = baseUrl + 'sidestories'
stripUrl = baseUrl + 'comic/%s'
firstStripUrl = stripUrl % 'journal01'
class LeastICouldDo(_ParserScraper):
url = 'https://leasticoulddo.com/'
stripUrl = url + 'comic/%s'
@ -116,7 +125,7 @@ class LifeAsRendered(_ParserScraper):
def getPrevUrl(self, url, data):
# Fix broken navigation links
page = url.rstrip('/').rsplit('/', 1)[-1]
if self.nav and page in self.nav:
if page in self.nav:
return self.stripUrl % self.nav[page]
return super(LifeAsRendered, self).getPrevUrl(url, data)

View file

@ -177,11 +177,12 @@ class Moonlace(_WPWebcomic):
stripUrl = 'http://dbcomics.darkblueworkshop.com/moonlace/%s/'
firstStripUrl = stripUrl % 'prologue/page-1'
url = firstStripUrl
latestSearch = '//main' + _WPWebcomic.latestSearch
adult = True
def starter(self):
# Set age-gate cookie
self.session.get(self.firstStripUrl + '?webcomic_birthday=1')
self.session.cookies.set('age_gate', '1', domain='darkblueworkshop.com')
return indirectStarter(self)
def namer(self, imageUrl, pageUrl):

View file

@ -74,13 +74,16 @@ class MangaDex(_ParserScraper):
cls('DeliciousinDungeon', 13871),
cls('DrStone', 20882),
cls('DragonDrive', 5165),
cls('HangingOutWithAGamerGirl', 42490),
cls('HeavensDesignTeam', 27811),
cls('HoriMiya', 6770),
cls('InterspeciesReviewers', 20796),
cls('JingaiNoYomeToIchaIchaSuru', 22651),
cls('KawaiiJoushiWoKomarasetai', 17910),
cls('KanojoOkarishimasu', 22151),
cls('ModernMoGal', 30308),
cls('OMaidensinYourSavageSeason', 22030),
cls('OokamiShounenWaKyouMoUsoOKasaneru', 14569),
cls('OokamiToKoshinryou', 1168),
cls('OtomeYoukaiZakuro', 4533),
cls('PleaseDontBullyMeNagatoro', 22631),
@ -91,6 +94,7 @@ class MangaDex(_ParserScraper):
cls('SPYxFAMILY', 35705),
cls('SwordArtOnline', 1360),
cls('SwordArtOnlineProgressive', 9604),
cls('TheWolfAndRedRidingHood', 31079),
cls('TomoChanWaOnnanoko', 15722),
cls('TonikakuKawaii', 23439),
cls('YotsubaAnd', 311),

View file

@ -102,31 +102,29 @@ class Nicky510(_WPNavi):
endOfLife = True
class Nightshift(_ParserScraper):
class Nightshift(_WPWebcomic):
url = 'https://poecatcomix.com/nightshift-static/'
stripUrl = 'https://poecatcomix.com/comic/%s/'
firstStripUrl = stripUrl % 'ns1-page-cover'
imageSearch = '//div[@class="mangapress-media-img"]/img'
prevSearch = '//li[@class="link-prev"]/a'
latestSearch = '//li[@class="link-last"]/a/@href'
stripUrl = 'https://poecatcomix.com/nightshift/%s/'
firstStripUrl = stripUrl % 'ns-cover'
imageSearch = '//div[contains(@class, "webcomic-media")]//img'
adult = True
def starter(self):
# Build list of chapters for navigation
# Build list of chapters for naming
indexPage = self.getPage(self.url)
self.chapters = indexPage.xpath('//a[./img[contains(@class, "attachment-large")]]/@href')
chapterPage = self.getPage(self.chapters[-1])
return chapterPage.xpath(self.latestSearch)[0]
def getPrevUrl(self, url, data):
# Retrieve previous chapter from list
if url in self.chapters:
chapterPage = self.getPage(self.chapters[self.chapters.index(url) - 1])
return chapterPage.xpath(self.latestSearch)[0]
return super(Nightshift, self).getPrevUrl(url, data)
latestPage = self.chapters[0]
self.chapters = self.chapters[1:]
self.currentChapter = len(self.chapters)
return latestPage
def namer(self, imageUrl, pageUrl):
return pageUrl.rstrip('/').rsplit('/', 1)[-1] + '.' + imageUrl.rsplit('.', 1)[-1]
page = pageUrl.rstrip('/').rsplit('/', 1)[-1]
page = page.replace('blood-brothers', 'bloodbrothers').replace('bb-2', 'bb2').replace('ns7-', 'page-')
filename = 'ns%d-%s.%s' % (self.currentChapter, page, imageUrl.rsplit('.', 1)[-1])
if pageUrl in self.chapters:
self.currentChapter = self.currentChapter - 1
return filename
class Nimona(_ParserScraper):

View file

@ -134,6 +134,7 @@ class OriginalLife(_ParserScraper):
imageSearch = '//img[contains(@src, "/originallife/comic/")]'
prevSearch = '//a[contains(text(), "Previous")]'
adult = True
endOfLife = True
help = 'Index format: yyyy/mm/<your guess>'

View file

@ -753,6 +753,9 @@ class Renamed(Scraper):
cls('ZebraGirl', 'ComicFury/ZebraGirl'),
# Renamed in 3.0
cls('SmackJeeves/BlackTapestries', 'ComicFury/BlackTapestries'),
cls('SmackJeeves/FurryExperience', 'ComicFury/FurryExperience'),
cls('SmackJeeves/GrowingTroubles', 'ComicFury/GrowingTroubles'),
cls('SmackJeeves/TheRealmOfKaerwyn', 'ComicFury/TheRealmOfKaerwyn'),
cls('StudioKhimera/Draconia', 'Draconia'),
)

View file

@ -30,6 +30,7 @@ class ProjectFuture(_ParserScraper):
cls('BookOfTenets', 'tenets', '01', last='45'),
cls('CriticalMass', 'criticalmass', 'cover', last='26'),
cls('DarkLordRising', 'darklord', '01-00', last='10-10'),
cls('Emily', 'emily', '01-00'),
cls('FishingTrip', 'fishing', '01-00'),
cls('HeadsYouLose', 'heads', '00-01', last='07-12'),
cls('NiallsStory', 'niall', '00'),

View file

@ -9,13 +9,36 @@ from urllib.parse import urljoin
from ..helpers import bounceStarter
from ..scraper import _BasicScraper, _ParserScraper
from ..util import tagre
from .common import _WordPressScraper, _WPWebcomic
from .common import _WordPressScraper, _WPNavi, _WPWebcomic
class RalfTheDestroyer(_WordPressScraper):
url = 'http://ralfthedestroyer.com/'
class RayFox(_WPNavi):
url = 'https://www.rayfoxthecomic.com/'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % 'not-a-super-hero/it-begins'
def namer(self, imageUrl, pageUrl):
filename = imageUrl.rsplit('/', 1)[-1].split('.', 1)[0]
ext = imageUrl.rsplit('.', 1)[-1]
if filename == 'j':
filename = 'RF_E3_P52'
elif filename == '46' or filename == '55' or filename == '61':
filename = 'RF_E3_P' + filename
elif 'chapter-3-cover' in filename:
filename = 'RF_E3_Cover'
elif 'Cover2' in filename:
filename = 'RF_E1_' + filename
elif 'Volume-1-Cover' in filename:
filename = filename.replace('Ray-Fox-Volume-1-', 'RF_E1_')
elif filename[0] == '0':
filename = 'RF_E1_P' + filename
return filename + '.' + ext
class RaynaOnTheRiver(_WordPressScraper):
url = 'http://www.catomix.com/rayna/'
firstStripUrl = url + 'archives/comic/teaser-poster'

View file

@ -111,8 +111,9 @@ class SchlockMercenary(_ParserScraper):
stripUrl = url + '%s'
firstStripUrl = stripUrl % '2000-06-12'
imageSearch = '//div[@class="strip-image-wrapper"]/img'
multipleImagesPerStrip = True
prevSearch = '//a[@class="previous-strip"]'
multipleImagesPerStrip = True
endOfLife = True
help = 'Index format: yyyy-mm-dd'
@ -335,6 +336,56 @@ class SodiumEyes(_WordPressScraper):
url = 'http://sodiumeyes.com/'
class SoloLeveling(_ParserScraper):
url = 'https://w1.sololeveling.net/'
stripUrl = url + 'manga/solo-leveling-chapter-%s/'
firstStripUrl = stripUrl % '1'
imageSearch = '//div[@class="img_container"]//img'
prevSearch = '//a[@rel="prev"]'
latestSearch = '//table[@class="chap_tab"]//a'
starter = indirectStarter
multipleImagesPerStrip = True
imageUrlFixes = {
'94-0_5dd574efda419/28.': '94-0_5dd574efda419/28a.',
'92-0_5dc2fcb9ed562/22.': '92-0_5dc2fcb9ed562/22s.',
'91-0_5db9b881ac2f0/20k.': '91-0_5db9b881ac2f0/20l.',
'91-0_5db9b881ac2f0/23.': '91-0_5db9b881ac2f0/23a.',
'90-0_5db08467ca2b1/07.': '90-0_5db08467ca2b1/07a.',
'90-0_5db08467ca2b1/09.': '90-0_5db08467ca2b1/09a.',
'90-0_5db08467ca2b1/13.': '90-0_5db08467ca2b1/13a.',
'90-0_5db08467ca2b1/14.': '90-0_5db08467ca2b1/14a.',
'90-0_5db08467ca2b1/21.': '90-0_5db08467ca2b1/21a.',
'90-0_5db08467ca2b1/22.': '90-0_5db08467ca2b1/22a.',
'88-0_5d9e0dedb942e/03.': '88-0_5d9e0dedb942e/03b.',
'88-0_5d9e0dedb942e/05.': '88-0_5d9e0dedb942e/05a.',
'88-0_5d9e0dedb942e/30.': '88-0_5d9e0dedb942e/30a.',
'87-0_5d94cdebd9df7/01a.': '87-0_5d94cdebd9df7/01c.'
}
def imageUrlModifier(self, imageUrl, data):
if 'url=' in imageUrl:
imageUrl = imageUrl.split('url=')[1].split('&')[0]
for fix in self.imageUrlFixes:
imageUrl = imageUrl.replace(fix, self.imageUrlFixes[fix])
return imageUrl
def fetchUrls(self, url, data, urlSearch):
# Save link order for position-based filenames
self.imageUrls = super(SoloLeveling, self).fetchUrls(url, data, urlSearch)
self.imageUrls = [self.imageUrlModifier(x, data) for x in self.imageUrls]
return self.imageUrls
def getPrevUrl(self, url, data):
return self.stripUrl % str(int(url.strip('/').rsplit('-', 1)[-1]) - 1)
def namer(self, imageUrl, pageUrl):
# Construct filename from episode number and image position on page
episodeNum = pageUrl.strip('/').rsplit('-', 1)[-1]
imageNum = self.imageUrls.index(imageUrl)
imageExt = imageUrl.rsplit('.', 1)[-1]
return "%s-%03d.%s" % (episodeNum, imageNum, imageExt)
class SomethingPositive(_ParserScraper):
url = 'https://www.somethingpositive.net/'
stripUrl = url + 'sp%s.shtml'
@ -500,26 +551,30 @@ class StarCrossdDestiny(_ParserScraper):
return directory + '-' + filename
class StarfireAgency(_WordPressScraper):
url = 'http://starfire.poecatcomix.com/'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % 'sfa-issue-1'
class StarfireAgency(_WPWebcomic):
url = 'https://poecatcomix.com/starfire-agency-static/'
stripUrl = 'https://poecatcomix.com/starfire-agency/%s/'
firstStripUrl = stripUrl % '2005-09-201'
imageSearch = '//div[contains(@class, "webcomic-media")]//img'
def starter(self):
# Build list of chapters for naming
indexPage = self.getPage(self.url)
self.chapters = indexPage.xpath('//a[./img[contains(@class, "attachment-large")]]/@href')
latestPage = self.chapters[0]
self.chapters = self.chapters[1:]
self.currentChapter = len(self.chapters)
return latestPage
def namer(self, imageUrl, pageUrl):
# Prepend chapter title to page filenames
page = self.getPage(pageUrl)
chapter = page.xpath('//div[@class="comic-chapter"]/a')
if len(chapter) > 0:
chapter = chapter[0].text.replace(' ', '-').lower()
else:
chapter = 'chapter-1'
# Fix inconsistent filenames
filename = imageUrl.rsplit('/', 1)[-1]
if 'cover' not in filename.lower():
filename = filename.replace('SFA', 'Page')
return chapter + '_' + filename
page = pageUrl.rstrip('/').rsplit('/', 1)[-1]
page = page.replace('3page00', 'cover3').replace('6429', 'cover7').replace('sfa-6-5-cover', 'cover6')
page = page.replace('sfa01', 'page01').replace('sfa03', 'page03').replace('sfa04', 'page04')
page = page.replace('sfa24', 'page24').replace('sfa07', 'page')
filename = 'sfa%d-%s.%s' % (self.currentChapter, page, imageUrl.rsplit('.', 1)[-1])
if pageUrl in self.chapters:
self.currentChapter = self.currentChapter - 1
return filename
class StarTrip(_ComicControlScraper):
url = 'https://www.startripcomic.com/'

View file

@ -135,7 +135,6 @@ class SmackJeeves(_ParserScraper):
cls('Blackdemon', 117183),
cls('BlackDragon', 131654),
cls('BlackFridayRule', 94517),
cls('BlackTapestries', 171490, adult=True),
cls('BlackSheepcomic', 91663),
cls('BleachRedux', 94169),
cls('BlindandBlue', 110850),
@ -240,7 +239,6 @@ class SmackJeeves(_ParserScraper):
cls('FromnowonImagirl', 99018),
cls('FruitloopAndMrDownbeat', 82798),
cls('FullSpectrumTherapy', 156285),
cls('FurryExperience', 62354),
cls('GamerCafe', 138841),
cls('GamesPeoplePlayUpdatedWeekly', 72207),
cls('GardenofHearts', 106504),
@ -574,7 +572,6 @@ class SmackJeeves(_ParserScraper):
cls('ThePremise', 118125),
cls('ThePrincessAndTheGiant', 59629, endOfLife=True),
cls('ThePropertyofHate', 117970),
cls('TheRealmOfKaerwyn', 156193),
cls('TheReborn', 1898),
cls('TheSearchForHenryJekyll', 139257),
cls('TheSilverLeague', 110008),

View file

@ -2,6 +2,7 @@
# Copyright (C) 2019-2020 Tobias Gruetzmacher
# Copyright (C) 2019-2020 Daniel Ring
from ..scraper import _ParserScraper
from .common import _WordPressScraper
class StudioKhimera(_ParserScraper):
@ -39,20 +40,25 @@ class StudioKhimera(_ParserScraper):
return None
return self.chapters[index - 1]
def namer(self, imageUrl, pageUrl):
# Fix inconsistent filenames
filename = imageUrl.rsplit('/', 1)[-1]
if 'uberquest' in pageUrl:
filename = filename.replace('Page', 'UberQuest')
filename = filename.replace('UberQuest01.', 'UberQuest001.')
filename = filename.replace('UberQuest98.', 'UberQuest098.')
filename = filename.replace('UberQuest99.', 'UberQuest099.')
return filename
@classmethod
def getmodules(cls):
return (
cls('Eorah', 'eorah'),
cls('Mousechievous', 'mousechievous'),
cls('UberQuest', 'uberquest'),
)
class UberQuest(_WordPressScraper):
name = 'StudioKhimera/UberQuest'
url = 'https://uberquest.studiokhimera.com/'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % 'chapter-1-cover'
def namer(self, imageUrl, pageUrl):
# Fix inconsistent filenames
filename = imageUrl.rsplit('/', 1)[-1]
filename = filename.replace('Page', 'UberQuest')
filename = filename.replace('UberQuest01.', 'UberQuest001.')
filename = filename.replace('UberQuest98.', 'UberQuest098.')
filename = filename.replace('UberQuest99.', 'UberQuest099.')
return filename

View file

@ -28,11 +28,8 @@ class Tamberlane(_WPWebcomic):
url = baseUrl + 'latest/'
stripUrl = baseUrl + 'tamberlane/%s/'
firstStripUrl = stripUrl % 'page-1'
def namer(self, imageUrl, pageUrl):
# Fix inconsistent filenames
filename = imageUrl.rsplit('/', 1)[-1]
return filename.replace('ai4zCWaA', 'Page_152')
imageSearch = '//div[@id="comic-page"]/img/@src'
prevSearch = '//a[@class="previous-link"]'
class TheBrads(_ParserScraper):
@ -129,6 +126,17 @@ class TheMelvinChronicles(_WordPressScraper):
url = 'http://melvin.jeaniebottle.com/'
class TheNightBelongsToUs(_ParserScraper):
url = 'https://tnbtu.com/'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % '01-00'
imageSearch = '//div[@id="spliced-comic"]//img'
prevSearch = '//a[./img[contains(@src, "nav-prev")]]'
latestSearch = '//a[contains(@class, "main-link")]'
starter = indirectStarter
adult = True
class TheNoob(_WordPressScraper):
url = 'http://thenoobcomic.com/'
stripUrl = url + 'comic/%s/'

View file

@ -82,6 +82,7 @@ class WebToons(_ParserScraper):
cls('Backchannel', 'super-hero/backchannel', 1456),
cls('BadSigns', 'comedy/bad-signs', 1623),
cls('Bastard', 'thriller/bastard', 485),
cls('BeforeWeKnewIt', 'romance/before-we-knew-it', 1972),
cls('BehindTheGIFs', 'comedy/behind-the-gifs', 658),
cls('BigJo', 'romance/big-jo', 854),
cls('BiteMe', 'thriller/bite-me', 1019),
@ -106,6 +107,7 @@ class WebToons(_ParserScraper):
cls('CherryBlossoms', 'romance/cherry-blossoms', 1005),
cls('Chiller', 'thriller/chiller', 536),
cls('ChocoLatte', 'romance/choco-latte', 1691),
cls('CityOfBlank', 'sf/city-of-blank', 1895),
cls('CityOfWalls', 'drama/city-of-wall', 505),
cls('ClusterFudge', 'slice-of-life/cluster-fudge', 355),
cls('CodeAdam', 'action/code-adam', 1657),
@ -163,6 +165,7 @@ class WebToons(_ParserScraper):
cls('Gepetto', 'sf/gepetto', 81),
cls('GhostsAmongTheWildFlowers', 'fantasy/ghosts-over-wild-flowers', 718),
cls('GhostTeller', 'horror/ghost-teller', 1307),
cls('GhostTheater', 'drama/ghost-theater', 1911),
cls('GhostWife', 'romance/ghost-wife', 1471),
cls('GirlsHaveABlog', 'slice-of-life/girls-have-a-blog', 1052),
cls('GirlsOfTheWilds', 'action/girls-of-the-wilds', 93),
@ -185,8 +188,10 @@ class WebToons(_ParserScraper):
cls('Hooky', 'fantasy/hooky', 425),
cls('HoovesOfDeath', 'fantasy/hooves-of-death', 1535),
cls('HouseOfStars', 'fantasy/house-of-stars', 1620),
cls('HowToBecomeADragon', 'fantasy/how-to-become-a-dragon', 1973),
cls('HowToLove', 'slice-of-life/how-to-love', 472),
cls('IDontWantThisKindOfHero', 'super-hero/i-dont-want-this-kind-of-hero', 98),
cls('IF', 'action/if', 1925),
cls('IllusionsOfAdulting', 'slice-of-life/illusions-of-adulting', 922),
cls('IllustratedInternet', 'comedy/illustrated-internet', 750),
cls('ILoveYoo', 'drama/i-love-yoo', 986),
@ -194,12 +199,15 @@ class WebToons(_ParserScraper):
cls('ImTheGrimReaper', 'supernatural/im-the-grim-reaper', 1697),
cls('Inarime', 'super-hero/inarime', 675),
cls('InternetExplorer', 'challenge/internet-explorer', 219164),
cls('InTheBleakMidwinter', 'sf/in-the-bleak-midwinter', 1946),
cls('ItsMine', 'drama/its-mine', 2010),
cls('JackieRose', 'supernatural/jackie-rose', 613),
cls('JingleJungle', 'slice-of-life/jingle-jungle', 282),
cls('JustAskYuli', 'slice-of-life/just-ask-yuli', 402),
cls('JustForKicks', 'slice-of-life/just-for-kicks', 1152),
cls('JustPancakes', 'comedy/just-pancakes', 1651),
cls('KidsAreAllRight', 'drama/kids-are-all-right', 283),
cls('Killstagram', 'thriller/killstagram', 1971),
cls('KindOfConfidential', 'romance/kind-of-confidential', 663),
cls('KindOfLove', 'slice-of-life/kind-of-love', 1850),
cls('KnightRun', 'sf/knight-run', 67),
@ -216,9 +224,11 @@ class WebToons(_ParserScraper):
cls('LittleMatchaGirl', 'fantasy/little-matcha-girl', 1665),
cls('LiveForever', 'thriller/live-forever', 1312),
cls('LiveWithYourself', 'comedy/live-with-yourself', 919),
cls('Lone', 'fantasy/lone', 1929),
cls('Lookism', 'drama/lookism', 1049),
cls('LoreOlympus', 'romance/lore-olympus', 1320),
cls('Lorna', 'slice-of-life/lorna', 1284),
cls('LostInTranslation', 'drama/lost-in-translation', 1882),
cls('LoveAdviceFromTheGreatDukeOfHell', 'comedy/love-advice', 1498),
cls('Lozolz', 'tiptoon/lozolz', 1268),
cls('LUFF', 'romance/luff', 1489),
@ -228,6 +238,8 @@ class WebToons(_ParserScraper):
cls('MageAndDemonQueen', 'comedy/mage-and-demon-queen', 1438),
cls('Magical12thGraders', 'super-hero/magical-12th-graders', 90),
cls('Magician', 'fantasy/magician', 70),
cls('MagicSodaPop', 'fantasy/magic-soda-pop', 1947),
cls('MarryMe', 'romance/marry-me', 1951),
cls('MatchmakerHero', 'sf/matchmaker-hero', 1569),
cls('MelvinasTherapy', 'horror/melvinas-therapy', 1021),
cls('MeowMan', 'comedy/meow-man', 1677),
@ -317,12 +329,14 @@ class WebToons(_ParserScraper):
cls('SpiritFingers', 'drama/spirit-fingers', 1577),
cls('Spirits', 'fantasy/spirits-re', 1348),
cls('STARCROSS', 'super-hero/star-cross', 1599),
cls('StayingHealthyTogether', 'tiptoon/staying-healthy-together', 1963),
cls('StrawberrySeafoam', 'fantasy/strawberry-seafoam', 1248),
cls('SubtleDisaster', 'drama/subtle-disaster', 350),
cls('SubZero', 'romance/subzero', 1468),
cls('SuperSecret', 'romance/super-secret', 666),
cls('SupersonicGirl', 'super-hero/supersonic-girl', 633),
cls('SweetHome', 'thriller/sweethome', 1285),
cls('SwimmingLessonsForAMermaid', 'romance/swimming-lessons-for-a-mermaid', 1912),
cls('SwordInterval', 'supernatural/sword-interval', 486),
cls('TalesOfTheUnusual', 'horror/tales-of-the-unusual', 68),
cls('TheBadguys', 'super-hero/the-bad-guys', 701),
@ -331,6 +345,7 @@ class WebToons(_ParserScraper):
cls('TheCroaking', 'fantasy/the-croaking', 1494),
cls('TheDaneMen', 'comedy/the-danemen', 395),
cls('TheDevilIsAHandsomeMan', 'drama/the-devil-is-a-handsome-man', 1311),
cls('TheDoctorsAreOut', 'romance/the-doctors-are-out', 1910),
cls('TheFeverKing', 'super-hero/the-fever-king', 1659),
cls('TheFourOfThem', 'drama/the-four-of-them', 1524),
cls('TheGamer', 'action/the-gamer', 88),
@ -358,6 +373,7 @@ class WebToons(_ParserScraper):
cls('ThirdShiftSociety', 'supernatural/third-shift-society', 1703),
cls('Thornstone', 'fantasy/thornstone', 1612),
cls('TickleTown', 'comedy/tickle-town', 428),
cls('ToasterDude', 'comedy/toaster-dude', 1983),
cls('TowerOfGod', 'fantasy/tower-of-god', 95),
cls('TrailerParkWarlock', 'comedy/trailer-park-warlock', 1512),
cls('TrashBird', 'comedy/trash-bird', 473),
@ -381,6 +397,7 @@ class WebToons(_ParserScraper):
cls('WarningLabel', 'romance/warning-label', 1051),
cls('Watermelon', 'fantasy/watermelon', 1435),
cls('WeakHero', 'action/weakhero', 1726),
cls('WEBTOONGREENLiGHT', 'action/webtoon-greenlight', 1988),
cls('WestwoodVibrato', 'drama/westwood-vibrato', 537),
cls('WhereTangentsMeet', 'romance/where-tangents-meet', 421),
cls('WindBreaker', 'sports/wind-breaker', 372),