{"id":15782462,"url":"https://github.com/jeroentvb/wind-scrape","last_synced_at":"2025-04-15T14:56:49.776Z","repository":{"id":40332637,"uuid":"158452363","full_name":"jeroentvb/wind-scrape","owner":"jeroentvb","description":"Node package for scraping wind forecast from a few websites","archived":false,"fork":false,"pushed_at":"2024-06-19T08:59:01.000Z","size":1546,"stargazers_count":32,"open_issues_count":3,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-15T14:56:41.876Z","etag":null,"topics":["forecast","nodejs","package","puppeteer","scraper","typescript","wind","windfinder","windguru","windy"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeroentvb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-20T21:17:39.000Z","updated_at":"2025-03-30T20:07:32.000Z","dependencies_parsed_at":"2023-09-21T20:04:41.935Z","dependency_job_id":"65153029-227e-4280-8751-f68c96f13316","html_url":"https://github.com/jeroentvb/wind-scrape","commit_stats":{"total_commits":169,"total_committers":5,"mean_commits":33.8,"dds":"0.29585798816568043","last_synced_commit":"6446a7fcc85203aa19f0189da59521df9f434ae2"},"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeroentvb%2Fwind-scrape","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeroentvb%2Fwind-scrape/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeroentvb%2Fwind-scrape/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeroentvb%2Fwind-scrape/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeroentvb","download_url":"https://codeload.github.com/jeroentvb/wind-scrape/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249094937,"owners_count":21211836,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["forecast","nodejs","package","puppeteer","scraper","typescript","wind","windfinder","windguru","windy"],"created_at":"2024-10-04T19:07:30.847Z","updated_at":"2025-04-15T14:56:49.753Z","avatar_url":"https://github.com/jeroentvb.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Disclaimer\nThis package scrapes websites. Web scraping is a grey area and may not be allowed by the website.  \nUse with caution and for *personal* use only!\n\nAs per windfinder's [Terms \u0026 Conditions](https://www.windfinder.com/contact/terms/)\n\u003e 1.4.2 The data are protected in our favor by copyright or related rights.\n\n\u003e 1.5.2 The data may be used without our consent only for the intended use within the scope of the services offered by us; in particular the data may not be used for own software, apps, web pages, etc., unless we have expressly agreed to this use.\n\nAs per windguru's [Terms and Conditions](https://www.windguru.cz/help.php?sec=terms)\n\u003e 3.2. It is forbidden to download website content by automated scripts.\n\nAs per windy's [General Terms of Use](https://account.windy.com/agreements/windy-terms-of-use)\n\u003e 5.6.1 The following activities are considered a misuse of the Services and material breach of the Agreements, and may lead to the termination of the provision of the Services:\n\u003e * continuous scanning of a significant amount of the Content and/or downloading of significant portions of the Content;\n\u003e * “crawling” of the Services or otherwise using any automated means to view, access, or collect information from the Services;\n\nThis basically means that you can't use any of the scrape functions in this package.  \n\n### Note\nIf you are going to use this package in a project I highly recommend implementing writing the scraped data to a file, and using this file if a website has been scraped within a certain amount of time. This avoids spamming a website with unnecessary requests.  \n\n# Wind scrape\n[![Maintainability](https://api.codeclimate.com/v1/badges/f9070ac5a17f58cd5bf0/maintainability)](https://codeclimate.com/github/jeroentvb/wind-scrape/maintainability)  \nWind-scrape can scrape wind forecasts from the following websites:\n* Windfinder (superforecast \u0026 observations)\n* Windguru (spots \u0026 custom spots (custom spots requires windguru PRO))\n* Windy\n\n## Table of contents\n* [Installation](#installation)\n* [Usage](#usage)\n  * [Windfinder](#windfinder)\n  * [Windguru](#windguru)\n  * [Windy](#windy)\n  * [Windfinder report](#windreport)\n\n## Installation\n```sh\nnpm install jeroentvb/wind-scrape#dist\n\n# Or get a specific version e.g. v3.0.1\n\nnpm install https://github.com/jeroentvb/wind-scrape/releases/download/{ VERSION }/dist.tgz\n```\nThe upper command always gets the newest version (on every `npm install`) from the dist branch. With the second command you can specify a release version (which won't be updated on every `npm install`).\nReleases can be found [here](https://github.com/jeroentvb/wind-scrape/releases).\n\n## Usage\n```js\nconst scrape = require('wind-scrape')\n\n// TypeScript\nimport * as scrape from 'wind-scrape'\n\n// Scrape windfinder spot\nscrape.windfinder('tarifa')\n  .then(data =\u003e console.log(data)\n  .catch(err =\u003e console.error(err)\n\n// Scrape windguru spot\nscrape.windguru(43)\n  .then(data =\u003e console.log(data)\n  .catch(err =\u003e console.error(err)\n\n// Scrape custom windguru spot\nscrape.customWindguru({\n    lat: 31.510627,\n    lon: -40.718838\n}, {\n    username: 'your windguru username',\n    password: 'your secondary windguru pasword'\n})\n  .then(data =\u003e console.log(data)\n  .catch(err =\u003e console.error(err)\n\n// Scrape windy spot\nscrape.windy(36.012, -5.611)\n  .then(data =\u003e console.log(data)\n  .catch(err =\u003e console.error(err)\n\n// Scrape windreport of a windguru spot\nscrape.windReport('tarifa')\n  .then(data =\u003e console.log(data)\n  .catch(err =\u003e console.error(err)\n```\n\n### windfinder\n```js\nscrape.windfinder(spotname)\n```\nScrapes data from a windfinder superforecast page. Returns a promise which resolves in an object with the following format:\n\u003cdetails\u003e\n \u003csummary\u003eWindfinder data format\u003c/summary\u003e\n \n ```json\n{\n    \"name\": \"Windfinder\",\n    \"spot\": \"Tarifa Centro\",\n    \"days\": [\n        {\n            \"date\": \"Sunday, Apr 07\",\n            \"hours\": [\n                {\n                    \"hour\": 0,\n                    \"windspeed\": 22,\n                    \"windgust\": 31,\n                    \"winddirectionDegrees\": 75,\n                    \"winddirectionLetters\": \"ENE\",\n                    \"temperature\": 18\n                }\n            ]\n        }\n    ]\n}\n```  \n\u003c/details\u003e\n\nIt also slices the data to only return day hours.\n\n#### spotname  \nA string. Name of the spot to scrape. This is the part after `https://www.windfinder.com/weatherforecast/`.  \nExample: to scrape data for Tarifa Centro, use `tarifa`.\n\n### windguru\n```js\nscrape.windguru(spot, model)\n```\nScrapes data from give windguru spot. Optionally get a specific model. Returns a promise which resolves in an object with the following format:\n\u003cdetails\u003e\n \u003csummary\u003eWindguru data format\u003c/summary\u003e\n \n```json\n{\n    \"spot\": {\n        \"name\": \"Spain - Tarifa\",\n        \"coordinates\": {\n            \"lat\": \"36\",\n            \"lng\": \"-5.65\"\n        },\n        \"temperature\": \"16 C\"\n    },\n    \"models\": [\n        {\n            \"name\": \"GFS 27 km\",\n            \"days\": [\n                {\n                    \"date\": \"Tue 4\",\n                    \"hours\": [\n                        {\n                            \"wspd\": \"1\",\n                            \"gust\": \"2\",\n                            \"wdirn\": \"N\",\n                            \"wdeg\": \"352\",\n                            \"tmp\": \"16\",\n                            \"slp\": \"1027\",\n                            \"hcld\": \"0\",\n                            \"mcld\": \"0\",\n                            \"lcld\": \"-\",\n                            \"apcp\": \"0\",\n                            \"rh\": \"68\",\n                            \"hour\": \"10\"\n                        }\n```\n\u003c/details\u003e\n\nThe included data may vary per forecast model. You can find the keys of variables on the [windguru micro help page](http://micro.windguru.cz/help.php). The only variable all hours have is `hour`.  \nWave models are now included as well. They have different variables.\n\n#### spot\nA string or number. The number windguru uses for a spot.  \nExample: to scrape data for Tarifa, use `43`. You can get this number from the url of the forecast for a spot.\n\n#### model\nA string or number. If provided, wind-scrape will only get the forecastmode for the given spot. Model identifiers can be found [here](http://micro.windguru.cz/help.php).\n\n### custom windguru\n```js\nscrape.customWindguru(coordinates, credentials, model)\n```\n\u003e ⚠️ **Requires a windguru PRO account**\n\nScrapes data for the given coordinates. Optionally get a specific model. Returns a promise which resolves in an object with the following format:\n\u003cdetails\u003e\n \u003csummary\u003eWindguru data format\u003c/summary\u003e\n \n```json\n{\n    \"spot\": {\n        \"coordinates\": {\n            \"lat\": \"36\",\n            \"lng\": \"-5.65\"\n        },\n        \"temperature\": \"25 C\"\n    },\n    \"models\": [\n        {\n            \"name\": \"GFS 27 km\",\n            \"days\": [\n                {\n                    \"date\": \"Tue 4\",\n                    \"hours\": [\n                        {\n                            \"wspd\": \"1\",\n                            \"gust\": \"2\",\n                            \"wdirn\": \"N\",\n                            \"wdeg\": \"352\",\n                            \"tmp\": \"16\",\n                            \"slp\": \"1027\",\n                            \"hcld\": \"0\",\n                            \"mcld\": \"0\",\n                            \"lcld\": \"-\",\n                            \"apcp\": \"0\",\n                            \"rh\": \"68\",\n                            \"hour\": \"10\"\n                        }\n```\n\u003c/details\u003e\n\nThe included data may vary per forecast model. You can find the keys of variables on the [windguru micro help page](http://micro.windguru.cz/help.php). The only variable all hours have is `hour`.  \nWave models are now included as well. They have different variables.\n\n#### coordinates\nObject in the following format:\n```js\n{\n    lat: 36,\n    lon: -5.65\n}\n```\n\n#### credentials\nObject in the following format:\n```js\n{\n    username: 'your windguru username',\n    password: 'your secondary windguru password'\n}\n```\nYou can find/set your secondary windguru password on windguru under settings -\u003e login -\u003e secondary password.\n\n#### model\nA string or number. If provided, wind-scrape will only get the forecastmode for the given spot. Model identifiers can be found [here](http://micro.windguru.cz/help.php).\n\n### Windy\n```js\nscrape.windy(lat, long)\n```\nScrapes data for a custom location. Returns a promise which resolves in an object with the following format:\n\u003cdetails\u003e\n \u003csummary\u003eWindguru data format\u003c/summary\u003e\n \n```json\n{\n    \"name\": \"Windy\",\n    \"models\": [\n        {\n            \"name\": \"ECMWF 9km\",\n            \"days\": [\n                {\n                    \"date\": \"07-04-2019\",\n                    \"hours\": [\n                        {\n                            \"hour\": 9,\n                            \"windspeed\": 20,\n                            \"windgust\": 30,\n                            \"winddirection\": 278\n                        }\n                    ]\n                }\n            ]\n        }\n    ]\n}\n```  \n\u003c/details\u003e\n\n#### lat\nLatitude of a spot\n\n#### long\nLongitude of a spot. Together these make up the coordinates of a spot.\nConsider the following windy url `https://www.windy.com/36.012/-5.611/wind?`. `36.012` would be the latitude, `-5.611` the longitude.\n\n### WindReport\n```js\nscrape.windReport(spotname)\n```\nGets the report data for a windfinder spot report. Returns a promise which resolves in an object with the following format:\n\u003cdetails\u003e\n \u003csummary\u003eWindguru data format\u003c/summary\u003e\n \n```json\n{\n    \"name\": \"Windfinder report\",\n    \"spot\": \"tarifa\",\n    \"report\": [\n        {\n            \"windspeed\": 17,\n            \"windgust\": 25,\n            \"winddirection\": 260,\n            \"time\": \"2019-04-06T15:00:00+02:00\"\n        }\n    ]\n}\n```   \n\u003c/details\u003e\nTime is given in ISO8601 format.\n\n\u003c!-- ## Testing\nTo test newly added features just run one of the following commands. If the test is succesful a file containing the scraped data will be written in the root of the project.  \nThe spot used is *Tarifa*.\n```sh\n# Test all scrape functions  \nnpm test  \n\n# Test the windfinder function\nnpm run test:windfinder  \n\n# Test the windguru function  \nnpm run test:windguru  \n\n# Test the windy function  \nnpm run test:windy  \n\n# Test the windReport function\nnpm run test:windreport\n``` --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeroentvb%2Fwind-scrape","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeroentvb%2Fwind-scrape","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeroentvb%2Fwind-scrape/lists"}