Browse Source

Scrape insects. Add env file

Tatiana Inama 6 years ago
parent
commit
aa610cd48f
84 changed files with 110 additions and 46 deletions
  1. 11 0
      package-lock.json
  2. 3 0
      scraper/.env
  3. BIN
      scraper/public/images/insects/Agrias-butterfly.png
  4. BIN
      scraper/public/images/insects/Ant.png
  5. BIN
      scraper/public/images/insects/Atlas-moth.png
  6. BIN
      scraper/public/images/insects/Bagworm.png
  7. BIN
      scraper/public/images/insects/Banded-dragonfly.png
  8. BIN
      scraper/public/images/insects/Bell-cricket.png
  9. BIN
      scraper/public/images/insects/Blue-weevil beetle.png
  10. BIN
      scraper/public/images/insects/Brown-cicada.png
  11. BIN
      scraper/public/images/insects/Centipede.png
  12. BIN
      scraper/public/images/insects/Cicada-shell.png
  13. BIN
      scraper/public/images/insects/Citrus-long-horned beetle.png
  14. BIN
      scraper/public/images/insects/Common-bluebottle.png
  15. BIN
      scraper/public/images/insects/Common-butterfly.png
  16. BIN
      scraper/public/images/insects/Cricket.png
  17. BIN
      scraper/public/images/insects/Cyclommatus-stag.png
  18. BIN
      scraper/public/images/insects/Damselfly.png
  19. BIN
      scraper/public/images/insects/Darner-dragonfly.png
  20. BIN
      scraper/public/images/insects/Diving-beetle.png
  21. BIN
      scraper/public/images/insects/Drone-beetle.png
  22. BIN
      scraper/public/images/insects/Dung-beetle.png
  23. BIN
      scraper/public/images/insects/Earth-boring-dung beetle.png
  24. BIN
      scraper/public/images/insects/Emperor-butterfly.png
  25. BIN
      scraper/public/images/insects/Evening-cicada.png
  26. BIN
      scraper/public/images/insects/Firefly.png
  27. BIN
      scraper/public/images/insects/Flea.png
  28. BIN
      scraper/public/images/insects/Fly.png
  29. BIN
      scraper/public/images/insects/Giant-cicada.png
  30. BIN
      scraper/public/images/insects/Giant-stag.png
  31. BIN
      scraper/public/images/insects/Giant-water bug.png
  32. BIN
      scraper/public/images/insects/Giraffe-stag.png
  33. BIN
      scraper/public/images/insects/Golden-stag.png
  34. BIN
      scraper/public/images/insects/Goliath-beetle.png
  35. BIN
      scraper/public/images/insects/Grasshopper.png
  36. BIN
      scraper/public/images/insects/Great-purple emperor.png
  37. BIN
      scraper/public/images/insects/Hermit-crab.png
  38. BIN
      scraper/public/images/insects/Honeybee.png
  39. BIN
      scraper/public/images/insects/Horned-atlas.png
  40. BIN
      scraper/public/images/insects/Horned-dynastid.png
  41. BIN
      scraper/public/images/insects/Horned-elephant.png
  42. BIN
      scraper/public/images/insects/Horned-hercules.png
  43. BIN
      scraper/public/images/insects/Jewel-beetle.png
  44. BIN
      scraper/public/images/insects/Ladybug.png
  45. BIN
      scraper/public/images/insects/Long-locust.png
  46. BIN
      scraper/public/images/insects/Madagascan-sunset moth.png
  47. BIN
      scraper/public/images/insects/Man-faced-stink bug.png
  48. BIN
      scraper/public/images/insects/Mantis.png
  49. BIN
      scraper/public/images/insects/Migratory-locust.png
  50. BIN
      scraper/public/images/insects/Miyama-stag.png
  51. BIN
      scraper/public/images/insects/Mole-cricket.png
  52. BIN
      scraper/public/images/insects/Monarch-butterfly.png
  53. BIN
      scraper/public/images/insects/Mosquito.png
  54. BIN
      scraper/public/images/insects/Moth.png
  55. BIN
      scraper/public/images/insects/Orchid-mantis.png
  56. BIN
      scraper/public/images/insects/Paper-kite butterfly.png
  57. BIN
      scraper/public/images/insects/Peacock-butterfly.png
  58. BIN
      scraper/public/images/insects/Pill-bug.png
  59. BIN
      scraper/public/images/insects/Pondskater.png
  60. BIN
      scraper/public/images/insects/Queen-Alexandra's birdwing.png
  61. BIN
      scraper/public/images/insects/Rainbow-stag.png
  62. BIN
      scraper/public/images/insects/Rajah-Brooke's birdwing.png
  63. BIN
      scraper/public/images/insects/Red-dragonfly.png
  64. BIN
      scraper/public/images/insects/Rice-grasshopper.png
  65. BIN
      scraper/public/images/insects/Robust-cicada.png
  66. BIN
      scraper/public/images/insects/Rosalia-batesi beetle.png
  67. BIN
      scraper/public/images/insects/Saw-stag.png
  68. BIN
      scraper/public/images/insects/Scarab-beetle.png
  69. BIN
      scraper/public/images/insects/Scorpion.png
  70. BIN
      scraper/public/images/insects/Snail.png
  71. BIN
      scraper/public/images/insects/Spider.png
  72. BIN
      scraper/public/images/insects/Stinkbug.png
  73. BIN
      scraper/public/images/insects/Tarantula.png
  74. BIN
      scraper/public/images/insects/Tiger-beetle.png
  75. BIN
      scraper/public/images/insects/Tiger-butterfly.png
  76. BIN
      scraper/public/images/insects/Violin-beetle.png
  77. BIN
      scraper/public/images/insects/Walker-cicada.png
  78. BIN
      scraper/public/images/insects/Walking-leaf.png
  79. BIN
      scraper/public/images/insects/Walking-stick.png
  80. BIN
      scraper/public/images/insects/Wasp.png
  81. BIN
      scraper/public/images/insects/Wharf-roach.png
  82. BIN
      scraper/public/images/insects/Yellow-butterfly.png
  83. 15 11
      scraper/server.ts
  84. 81 35
      scraper/src/scraper.ts

+ 11 - 0
package-lock.json

@@ -0,0 +1,11 @@
+{
+  "requires": true,
+  "lockfileVersion": 1,
+  "dependencies": {
+    "dotenv": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+      "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
+    }
+  }
+}

+ 3 - 0
scraper/.env

@@ -0,0 +1,3 @@
+PORT=3001
+AC_FISH='https://animalcrossing.fandom.com/wiki/Fish_(New_Horizons)'
+AC_INSECT='https://animalcrossing.fandom.com/wiki/Bugs_(New_Horizons)'

BIN
scraper/public/images/insects/Agrias-butterfly.png


BIN
scraper/public/images/insects/Ant.png


BIN
scraper/public/images/insects/Atlas-moth.png


BIN
scraper/public/images/insects/Bagworm.png


BIN
scraper/public/images/insects/Banded-dragonfly.png


BIN
scraper/public/images/insects/Bell-cricket.png


BIN
scraper/public/images/insects/Blue-weevil beetle.png


BIN
scraper/public/images/insects/Brown-cicada.png


BIN
scraper/public/images/insects/Centipede.png


BIN
scraper/public/images/insects/Cicada-shell.png


BIN
scraper/public/images/insects/Citrus-long-horned beetle.png


BIN
scraper/public/images/insects/Common-bluebottle.png


BIN
scraper/public/images/insects/Common-butterfly.png


BIN
scraper/public/images/insects/Cricket.png


BIN
scraper/public/images/insects/Cyclommatus-stag.png


BIN
scraper/public/images/insects/Damselfly.png


BIN
scraper/public/images/insects/Darner-dragonfly.png


BIN
scraper/public/images/insects/Diving-beetle.png


BIN
scraper/public/images/insects/Drone-beetle.png


BIN
scraper/public/images/insects/Dung-beetle.png


BIN
scraper/public/images/insects/Earth-boring-dung beetle.png


BIN
scraper/public/images/insects/Emperor-butterfly.png


BIN
scraper/public/images/insects/Evening-cicada.png


BIN
scraper/public/images/insects/Firefly.png


BIN
scraper/public/images/insects/Flea.png


BIN
scraper/public/images/insects/Fly.png


BIN
scraper/public/images/insects/Giant-cicada.png


BIN
scraper/public/images/insects/Giant-stag.png


BIN
scraper/public/images/insects/Giant-water bug.png


BIN
scraper/public/images/insects/Giraffe-stag.png


BIN
scraper/public/images/insects/Golden-stag.png


BIN
scraper/public/images/insects/Goliath-beetle.png


BIN
scraper/public/images/insects/Grasshopper.png


BIN
scraper/public/images/insects/Great-purple emperor.png


BIN
scraper/public/images/insects/Hermit-crab.png


BIN
scraper/public/images/insects/Honeybee.png


BIN
scraper/public/images/insects/Horned-atlas.png


BIN
scraper/public/images/insects/Horned-dynastid.png


BIN
scraper/public/images/insects/Horned-elephant.png


BIN
scraper/public/images/insects/Horned-hercules.png


BIN
scraper/public/images/insects/Jewel-beetle.png


BIN
scraper/public/images/insects/Ladybug.png


BIN
scraper/public/images/insects/Long-locust.png


BIN
scraper/public/images/insects/Madagascan-sunset moth.png


BIN
scraper/public/images/insects/Man-faced-stink bug.png


BIN
scraper/public/images/insects/Mantis.png


BIN
scraper/public/images/insects/Migratory-locust.png


BIN
scraper/public/images/insects/Miyama-stag.png


BIN
scraper/public/images/insects/Mole-cricket.png


BIN
scraper/public/images/insects/Monarch-butterfly.png


BIN
scraper/public/images/insects/Mosquito.png


BIN
scraper/public/images/insects/Moth.png


BIN
scraper/public/images/insects/Orchid-mantis.png


BIN
scraper/public/images/insects/Paper-kite butterfly.png


BIN
scraper/public/images/insects/Peacock-butterfly.png


BIN
scraper/public/images/insects/Pill-bug.png


BIN
scraper/public/images/insects/Pondskater.png


BIN
scraper/public/images/insects/Queen-Alexandra's birdwing.png


BIN
scraper/public/images/insects/Rainbow-stag.png


BIN
scraper/public/images/insects/Rajah-Brooke's birdwing.png


BIN
scraper/public/images/insects/Red-dragonfly.png


BIN
scraper/public/images/insects/Rice-grasshopper.png


BIN
scraper/public/images/insects/Robust-cicada.png


BIN
scraper/public/images/insects/Rosalia-batesi beetle.png


BIN
scraper/public/images/insects/Saw-stag.png


BIN
scraper/public/images/insects/Scarab-beetle.png


BIN
scraper/public/images/insects/Scorpion.png


BIN
scraper/public/images/insects/Snail.png


BIN
scraper/public/images/insects/Spider.png


BIN
scraper/public/images/insects/Stinkbug.png


BIN
scraper/public/images/insects/Tarantula.png


BIN
scraper/public/images/insects/Tiger-beetle.png


BIN
scraper/public/images/insects/Tiger-butterfly.png


BIN
scraper/public/images/insects/Violin-beetle.png


BIN
scraper/public/images/insects/Walker-cicada.png


BIN
scraper/public/images/insects/Walking-leaf.png


BIN
scraper/public/images/insects/Walking-stick.png


BIN
scraper/public/images/insects/Wasp.png


BIN
scraper/public/images/insects/Wharf-roach.png


BIN
scraper/public/images/insects/Yellow-butterfly.png


+ 15 - 11
scraper/server.ts

@@ -1,24 +1,28 @@
 import express from 'express';
-
-import scrape, {saveImage} from './src/scraper';
+import dotenv from 'dotenv'
+import scrapeFishes, { saveImage, scrapeInsects } from './src/scraper';
 
 const app: express.Application = express();
-const port: number = 3001;
+
+dotenv.config();
 
 app.use(express.static('public'))
 
-app.get('/', (req, res) => {
-  scrape();
-  res.send('Hello World!')
-});
+app.get('/', (req, res) => { res.send('Hello World!') });
 
 app.get('/fishes', (req, res) => {
-  return scrape().then(saveImage).then((fishes => {
+  return scrapeFishes().then(saveImage('images/fishes/')).then((fishes => {
     return res.send(fishes);
   }))
 })
 
-app.listen(port, () => {
-  console.log(`Scrapper app listening at http://localhost:${port}`);
-  scrape();
+app.get('/insects', (req, res) => {
+  return scrapeInsects().then(saveImage('images/insects/')).then((insects => {
+    return res.send(insects);
+  }))
+})
+
+app.listen(process.env.PORT, () => {
+  console.log(`Scrapper app listening at http://localhost:${process.env.PORT}`);
+  scrapeFishes();
 });

+ 81 - 35
scraper/src/scraper.ts

@@ -1,21 +1,28 @@
 import cheerio from 'cheerio';
 import axios from 'axios';
-import { splitAt } from 'ramda';
+import { splitAt, reject } from 'ramda';
 import fs from 'fs';
-import express from 'express';
+
 
 type DataParser = (td: Cheerio) => ({
   [x: string]: number | string | [number, number][]
 });
 
-type Fish = {
+interface Critter {
   name: string,
   img: string,
   price: number,
   location: string,
-  shadowSize: number,
   time: [number, number][],
-  months: number[],
+  months: number[]
+}
+
+interface Fish extends Critter {
+  shadowSize: number,
+}
+
+interface Insect extends Critter {
+  flickPrice: number,
 }
 
 const mkLocation = (location: string): string => {
@@ -45,7 +52,7 @@ const mkTime = (time: string): [number, number][] => {
 }
 
 const fishPropMap: DataParser[] = [
-  td => ({name: td.text().trim()}),
+  td => ({ name: td.text().trim()}),
   td => ({ img: td.find('a').attr('href') || '' }),
   td => ({ price: parseInt(td.text().trim())}),
   td => ({ location: mkLocation(td.text().trim())}),
@@ -53,43 +60,51 @@ const fishPropMap: DataParser[] = [
   td => ({ time: mkTime(td.text().trim())})
 ]
 
+const insectPropMap: DataParser[] = [
+  td => ({ name: td.text().trim()}),
+  td => ({ img: td.find('a').attr('href') || '' }),
+  td => ({ price: parseInt(td.text().trim())}),
+  td => ({ location: td.text().trim()}),
+  td => ({ time: mkTime(td.text().trim())})
+];
+
 const parseMonths = (tr: CheerioElement[]) => {
   return tr.reduce<number[]>((calendar, td, month) => {
     return td.firstChild.data?.trim() === '✓' ? [ ...calendar, month+1 ] : [ ...calendar ]
   }, [])
 }
 
-export const saveImage = (fishes: Fish[]) => {
-  return Promise.all(fishes.map(async fish => {
-    const location = `images/fishes/${fish.name.replace(' ', '-')}.png`;
-    
-    const writer = fs.createWriteStream(`${__dirname}/../public/${location}`)
-    
-    const response = await axios.get(fish.img, {
-      responseType: 'stream'
-    });
-  
-    response.data.pipe(writer)
-    
-    return new Promise((resolve, reject) => {
-      writer.on('finish', resolve)
-      writer.on('error', reject)
-    }).then(result => {
-      return {
-        ...fish,
-        img: location
-      }
-    })
+const isFish = (critter: Fish | Insect): critter is Fish => {
+  return (critter as Fish).shadowSize !== undefined;
+}
+
+const downloadImg = async (url: string, destinationPath: string) => {
+  const writer = fs.createWriteStream(`${__dirname}/../public/${destinationPath}`);
+  const response = await axios.get(url, { responseType: 'stream' });
+  response.data.pipe(writer);
+
+  return new Promise((resolve, reject) => {
+    writer.on('finish', resolve)
+    writer.on('error', reject)
+  })
+}
+
+export const saveImage = (path: string) => (critters: Critter[]) => {
+  return Promise.all(critters.map(critter => {
+    const _path = `${path}${critter.name.replace(' ', '-')}.png`;
+    return downloadImg(critter.img, _path).then(result => ({
+      ...critter,
+      img: _path
+    }))
   })).catch(error => {
     console.error(error)
-    return fishes
+    return critters
   })
 }
 
-const scrape = async () => {
-  const html = await axios.get('https://animalcrossing.fandom.com/wiki/Fish_(New_Horizons)');
-  const $ = cheerio.load(html.data, { normalizeWhitespace: true });
-  
+const scrapeFishes = async () => {
+  const $ = await scraper(process.env.AC_FISH);
+
   const rows = $('[title="Northern Hemisphere"] table.roundy.sortable tbody tr').toArray().slice(1);
   const fishes = rows.reduce((fishes, rowData) => {
     const [ fishData, months ] = splitAt(6, rowData.children.slice(1));
@@ -98,12 +113,11 @@ const scrape = async () => {
       ...fishData.reduce(( fish, td, i ) => {
         return {
           ...fish,
-          ...fishPropMap[i]($(td))
+          ...fishPropMap[i]($(td)),
         };
       }, {} as Fish),
       months: parseMonths(months)
     };
-
     return [
       ...fishes,
       fish
@@ -113,4 +127,36 @@ const scrape = async () => {
   return fishes;
 }
 
-export default scrape;
+export const scrapeInsects = async () => {
+  const $ = await scraper(process.env.AC_INSECT);
+
+  const rows = $('[title="Northern Hemisphere"] table.sortable tbody tr').toArray().slice(1);
+  const insects = rows.reduce((insects, rowData) => {
+    const [ insectData, months ] = splitAt(4, rowData.children.slice(1))
+    
+    const _insect = insectData.reduce(( insect, td, i ) => {
+      return {
+        ...insect,
+        ...insectPropMap[i]($(td))
+      }
+    }, {} as Insect);
+
+    return [
+      ...insects,
+      {
+        ..._insect,
+        flickPrice: _insect.price * 1.5,
+        months: parseMonths(months)
+      }
+    ]
+  }, [] as Insect[])
+
+  return insects;
+}
+
+const scraper = async (url?: string) => {
+  const html = await axios.get(url||'');
+  return cheerio.load(html.data, { normalizeWhitespace: true });
+}
+
+export default scrapeFishes;