I have written a webscraper in Python that grabs data from ~10 different websites (they have confirmed that this is ok). Most of the websites are a little bit different, but the general idea of getting data from each is the same:
- Load the site's URL
- Press anywhere from 0 to 3 buttons (depending on the site).
- Enter a site-specific search phrase.
- Grab data from any result which contains yet another site specific phrase.
- Record the data in a file, specific to the site.
Obviously, most of this can be abstracted away, but steps 3 and 4 are too different between sites to abstract the whole process. So there is an abstract scraper, extended by a site-specific scraper for each site which handles steps 3 and 4.
My problem is that there's a lot of site-specific information to keep track of. I could put each site-specific configuration in its own class, but I'd like to keep it all in one place so I can make mass changes (digging through 10 classes to make the same change sounds terrible).
What I did was create a class I called "ScraperData", which looks like this:
class ScraperData:
scrapers = {
"Website1": Website1Scraper(),
"Website2": Website2Scraper(),
...
}
URLs = {
"Website1": "www.website1.com",
"Website2": "www.website2.com",
...
}
buttonsToPress = {
"Website1": None,
"Website2": ["Button1", "Button2"],
...
}
....
I know I could achieve something a bit less wordy by restructuring this (I could have a configuration class and initialize one for each site in here), but I like that this approach lumps like data together.
I have a config file as well which has one line:
Website1, Website2, Website5, ...
Where I pick which sites to get data from (we don't always want to do all 10).
Lastly, there is a main class which loads the websites from the config into an array, sitesToScrape
, and does roughly the following:
data = ScraperData()
for site in sitesToScrape:
scraper = data.scrapers[site]
scraper.load(data.URLs[site], data.buttonsToPress[site])
scrapedData = scraper.scrape(data.searchStrings[site])
self.write(site, data.files[site], scrapedData)
Each morning I just pick which sites to grab data of off, start the whole thing up, then leave it alone for a few hours.
The way I see it, this makes it really easy to plug in new sites, take out old ones, or edit the configuration of one or multiple sites. The whole project feels weirdly compartmentalized though, but I feel like each compartment serves one specific purpose.
My question is: Is this an easily maintainable approach to this problem? Performance is not a factor at all.