Skip to content

Commit eee06d8

Browse files
Refactor Reddit scrapers into a more reasonable code structure
Cf. #328
1 parent 4dd3ee6 commit eee06d8

File tree

1 file changed

+31
-23
lines changed

1 file changed

+31
-23
lines changed

snscrape/modules/reddit.py

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -202,33 +202,41 @@ def _setup_parser_opts(cls, subparser):
202202
subparser.add_argument('--after', metavar = 'TIMESTAMP', type = int, help = 'Fetch results after a Unix timestamp')
203203

204204

205-
def _make_scraper(name_, validationFunc, apiField):
206-
class Scraper(RedditPushshiftScraper):
207-
name = f'reddit-{name_}'
205+
class RedditScraper(RedditPushshiftScraper):
206+
def __init__(self, name, **kwargs):
207+
super().__init__(**kwargs)
208+
self._name = name
209+
if not type(self)._validationFunc(self._name):
210+
raise ValueError(f'invalid {type(self).name.split("-", 1)[1]} name')
211+
212+
def get_items(self):
213+
yield from self._iter_api_submissions_and_comments({type(self)._apiField: self._name})
208214

209-
def __init__(self, name, **kwargs):
210-
super().__init__(**kwargs)
211-
self._name = name
212-
if not validationFunc(self._name):
213-
raise ValueError(f'invalid {name_} name')
215+
@classmethod
216+
def setup_parser(cls, subparser):
217+
super()._setup_parser_opts(subparser)
218+
name = cls.name.split('-', 1)[1]
219+
subparser.add_argument(name, type = snscrape.base.nonempty_string(name))
220+
221+
@classmethod
222+
def from_args(cls, args):
223+
name = cls.name.split('-', 1)[1]
224+
return cls._construct(args, getattr(args, name), submissions = not args.noSubmissions, comments = not args.noComments, before = args.before, after = args.after)
214225

215-
def get_items(self):
216-
yield from self._iter_api_submissions_and_comments({apiField: self._name})
217226

218-
@classmethod
219-
def setup_parser(cls, subparser):
220-
super()._setup_parser_opts(subparser)
221-
subparser.add_argument(name_, type = snscrape.base.nonempty_string(name_))
227+
class RedditUserScraper(RedditScraper):
228+
name = 'reddit-user'
229+
_validationFunc = lambda x: re.match('^[A-Za-z0-9_-]{3,20}$', x)
230+
_apiField = 'author'
222231

223-
@classmethod
224-
def from_args(cls, args):
225-
return cls._construct(args, getattr(args, name_), submissions = not args.noSubmissions, comments = not args.noComments, before = args.before, after = args.after)
226232

227-
Scraper.__name__ = f'Reddit{name_.capitalize()}Scraper'
228-
Scraper.__qualname__ = Scraper.__name__
229-
globals()[Scraper.__name__] = Scraper
233+
class RedditSubredditScraper(RedditScraper):
234+
name = 'reddit-subreddit'
235+
_validationFunc = lambda x: re.match('^[A-Za-z0-9][A-Za-z0-9_]{2,20}$', x)
236+
_apiField = 'subreddit'
230237

231238

232-
_make_scraper('user', lambda x: re.match('^[A-Za-z0-9_-]{3,20}$', x), 'author')
233-
_make_scraper('subreddit', lambda x: re.match('^[A-Za-z0-9][A-Za-z0-9_]{2,20}$', x), 'subreddit')
234-
_make_scraper('search', lambda x: True, 'q')
239+
class RedditSearchScraper(RedditScraper):
240+
name = 'reddit-search'
241+
_validationFunc = lambda x: True
242+
_apiField = 'q'

0 commit comments

Comments
 (0)