ウェブでのラッピング
55308 ワード
私がstrapiコミュニティに伝えようとしている1つのメッセージがあるならば、それはstrapiでどんなタイプのアプリケーションも作成することが可能であるということです.それがAであるかどうかsimple blog , エーshowcase site , エーcorporate site , 安e-commerce site , ある方法では、モバイルアプリケーションなどで使用できるAPI.
その強力なカスタマイズのために、あなたはstrapiで望むものは何でも作成できます.今日、このチュートリアルでは、Webサイトをscrapeに使用するアプリケーションを作成するためにご案内いたします.私は、過去の情報を収集するためにいくつかのウェブサイトを削って構成されたフリーランスの使命のために過去にstrapiを使用している.
strapiは非常に便利だったので、私はアーキテクチャを構築するためにスクレーパーだけで数回のクリックで管理することができます.しかし、次の手順は、strapiでスクラップアプリを作成する最良の方法ではないかもしれません.公式ガイドラインはありません、それはあなたのニーズとあなたの想像力に依存します.
このチュートリアルでは、我々はjamstack.org サイトとより正確にsite generators section . このサイトはstrapiやその他のようなヘッドレスのCMSSをリストしますが、サイトジェネレータやフレームワークなどのようなフレームワークを示しますNext.js , Gatsby or Jekyll .
我々は単に、cronを介して、収集するアプリを作成するつもりですsite generators 毎日、それらをstrapiアプリに挿入します.
これを行うにはPuppeteer ブラウザを制御して必要な情報を抽出するCheerio .
さあ、始めましょう!
次のコマンドを使用して、strapiアプリケーションを作成します. フォームを提出して管理者を作成します.
スクレーパーと呼ばれる最初のコレクション型を作成します
コンテンツタイプビルダー>+新しいコレクションタイプを作成します.
今すぐあなたの側のnavのスクレーパーをクリックして、スクレーパを見ることができる必要があります:
新しいスクレーパーを追加
このビューはよく組織されていません. ビューの構成をクリックし、次の組織を再生します プレスセーブ スクレーパーコレクションの種類を作成することにより、直接管理者のスクレーパーの動作を管理することができます.できます.
別のコレクション型を作成します
パーフェクト!すべては管理者のコンテンツに関して準備ができているようです!
さあ、スクレーパーを作りましょう.
スクレーパーをクリックしてください
次のスクレーパーを作成します
ここにあります.
最初にすることは、あなたのアプリケーションをスラグでスクラップを得ることができることです.
次のコードを追加します
のみ更新
すごい!今、あなたは関連スラグを使用してスクレーパーを取得することができます.
さあ、スクレーパーを作りましょう. クリエイトア クリエイトア クリエイトア このファイルには、Jamstackのサイトジェネレータをscrapeするロジックが含まれます.org. これはcronによって呼び出されますが、開発中は
最後に、我々はそこからそれを削除し、毎分私たちのcronファイルでそれを呼び出します.スクリプトは、これを実行する時間かどうかのために定義されるスクレーパーの周波数のおかげではないかどうかをチェックします.
次のコードを追加します
アップデート
これで、ブートストラップファイルを保存した後、あなたの端末にスクレーパー(JSON)を見ることができます.
すごい!今スクラップする時間です!
まず最初に、我々はスクリプトの役に立つ機能を含んでいるファイルを作成するつもりです.
クリエイトア
最初の関数は
次のコマンドを実行して、次のパッケージを追加します.
次のコードを追加します
この関数は、スクレーパーを実行する時間かどうかチェックします.あなたのスクレーパー、パッケージに設定する周波数に応じて
重要:あなたのスクレーパーの周波数を変更する場合は、削除する必要があります
次の関数は、スクリプトの実行中に再び取得しないように、すでにデータベースに挿入されたすべてのサイトジェネレータを取得します.
以下の関数を追加します
次の関数は単にレポートとエラーログの現在の日付を取得します
以下の関数を追加します
最後の関数は最後の実行のレポートを準備します.
以下の関数を追加します
ああ!あなた
あなたにPetpeteerとチェリオを加えてください
アップデート
はい、あなたはそれがさらに行くことはありませんので、あなたのスクレーパーを有効にしなかった.したがって、継続するためには、このコードをコメントする必要があります.なぜなら、scrape関数のコードを待機する必要がないかどうかをコード化できますからです).
次のコードの一部をコメントします
あなたのファイルを保存することができます今、それは罰金する必要があります!
パーフェクト!今すぐデータをこするに飛び込む!
アップデート
この変更について説明します.
まず最初に、まだ作成していないファイルから関数をインポートしていることがわかります.
それから、我々は
クリエイトア
ご存知のように、我々はこれで最後にスクレーパーを更新している
それを加えましょう
もう一度、あなたのファイルを保存することによって、このメッセージを持つべきです.
まず第一にすべてを設定する必要があります
アップデート
アップデート
あなたの更新を更新することによってcronを使用する可能性をアクティブにします
あなたのファイルを保存! 今、何が起こるかは、次の分では、スクレイパーが記入されます
だから次の分後
さて、私はそれがこの迅速かつ簡単なチュートリアルのためだと思う!
では、周波数を普通の何かに戻しましょう.
私はあなたがそれを楽しんでほしい!
あなたが学習を維持したい場合はAcademy ストーカーの専門家になるか、単に我々の閲覧blog あなたが好きなすべての科目を明らかにする.
その強力なカスタマイズのために、あなたはstrapiで望むものは何でも作成できます.今日、このチュートリアルでは、Webサイトをscrapeに使用するアプリケーションを作成するためにご案内いたします.私は、過去の情報を収集するためにいくつかのウェブサイトを削って構成されたフリーランスの使命のために過去にstrapiを使用している.
strapiは非常に便利だったので、私はアーキテクチャを構築するためにスクレーパーだけで数回のクリックで管理することができます.しかし、次の手順は、strapiでスクラップアプリを作成する最良の方法ではないかもしれません.公式ガイドラインはありません、それはあなたのニーズとあなたの想像力に依存します.
このチュートリアルでは、我々はjamstack.org サイトとより正確にsite generators section . このサイトはstrapiやその他のようなヘッドレスのCMSSをリストしますが、サイトジェネレータやフレームワークなどのようなフレームワークを示しますNext.js , Gatsby or Jekyll .
我々は単に、cronを介して、収集するアプリを作成するつもりですsite generators 毎日、それらをstrapiアプリに挿入します.
これを行うにはPuppeteer ブラウザを制御して必要な情報を抽出するCheerio .
さあ、始めましょう!
StrAPIアプリケーションの作成
npx create-strapi-app jamstack-scraper --quickstart
このアプリケーションはSQLiteデータベースがあります.自由に取り除く--quickstart
オプションは、お気に入りのデータベースを選択します.スクレーパーと呼ばれる最初のコレクション型を作成します
コンテンツタイプビルダー>+新しいコレクションタイプを作成します.
このビューはよく組織されていません.
1. Enable/Disable it
2. Update the frequency
3. See the errors of the last execution
4. Get a report of the last execution
5. See all the data scraped for this scraper with a relation
パーフェクト!すべては管理者のコンテンツに関して準備ができているようです!
さあ、スクレーパーを作りましょう.
スクレーパーの作成
ここにあります.
1. The name of the scraper.
2. The slug which is generated thanks to the name.
3. We disable it for now.
4. The frequency here is expressed using cron schedule expressions. `* * * * *` here means every minute. Since after testing we want to launch the scraper every day at, let's say, 3pm, it would be something like this: `0 15 * * *`
5. The `next_execution_at` will contains a string of the timestamp of the next execution. This way the scraper will respect the frequency. You will have more details after ;)
コードに飛び込みましょう!最初にすることは、あなたのアプリケーションをスラグでスクラップを得ることができることです.
次のコードを追加します
./api/scraper/controllers/scraper.js
ファイルconst { sanitizeEntity } = require('strapi-utils');
module.exports = {
/**
* Retrieve a record.
*
* @return {Object}
*/
async findOne(ctx) {
const { slug } = ctx.params;
const entity = await strapi.services.scraper.findOne({ slug });
return sanitizeEntity(entity, { model: strapi.models.scraper });
},
};
のみ更新
findOne
あなたのルート./api/scraper/config/routes.json
次のコードをファイルします{
"routes": [
...
{
"method": "GET",
"path": "/scrapers/:slug",
"handler": "scraper.findOne",
"config": {
"policies": []
}
},
...
]
}
さあ、スクレーパーを作りましょう.
./scripts
あなたのStrapiプロジェクトのルートのフォルダ../scripts/scrapers
この以前に作成したフォルダ内のフォルダ../scripts/starters/jamstack.js
空のファイル../config/functions/bootstrap.js
サーバが再起動する度に実行されるファイル.このようにして、ファイルを保存するたびにスクリプトを試してみることができます.最後に、我々はそこからそれを削除し、毎分私たちのcronファイルでそれを呼び出します.スクリプトは、これを実行する時間かどうかのために定義されるスクレーパーの周波数のおかげではないかどうかをチェックします.
次のコードを追加します
./scripts/starters/jamstack.js
ファイルconst main = async () => {
// Fetch the correct scraper thanks to the slug
const slug = "jamstack-org"
const scraper = await strapi.query('scraper').findOne({
slug: slug
});
console.log(scraper);
// If the scraper doesn't exists, is disabled or doesn't have a frequency then we do nothing
if (scraper == null || !scraper.enabled || !scraper.frequency)
return
}
exports.main = main;
アップデート
./config/functions/bootstrap.js
以下のファイルを指定します.'use strict';
/**
* An asynchronous bootstrap function that runs before
* your application gets started.
*
* This gives you an opportunity to set up your data model,
* run jobs, or perform some special logic.
*
* See more details here: https://strapi.io/documentation/developer-docs/latest/concepts/configurations.html#bootstrap
*/
const jamstack = require('../../scripts/scrapers/jamstack.js')
module.exports = () => {
jamstack.main()
};
すごい!今スクラップする時間です!
まず最初に、我々はスクリプトの役に立つ機能を含んでいるファイルを作成するつもりです.
クリエイトア
./scripts/scrapers/utils/utils.js
以下を含むファイル'use strict'
cron-parser
Adminで設定した頻度に応じてスクリプトを実行できるかどうかをチェックするパッケージ.また、私たちはchalk
色でメッセージを表示するパッケージ.次のコマンドを実行して、次のパッケージを追加します.
yarn add cron-parser chalk
次のコードを追加します
./scripts/scrapers/utils/utils.js
ファイル.'use strict'
const parser = require('cron-parser');
const scraperCanRun = async (scraper) => {
const frequency = parser.parseExpression(scraper.frequency);
const current_date = parseInt((new Date().getTime() / 1000));
let next_execution_at = ""
if (scraper.next_execution_at){
next_execution_at = scraper.next_execution_at
}
else {
next_execution_at = (frequency.next().getTime() / 1000);
await strapi.query('scraper').update({
id: scraper.id
}, {
next_execution_at: next_execution_at
});
}
if (next_execution_at <= current_date){
await strapi.query('scraper').update({
id: scraper.id
}, {
next_execution_at: (frequency.next().getTime() / 1000)
});
return true
}
return false
}
module.exports = { scraperCanRun }
cron-parser
それを解析して、これがあなたのスクレイパーを実行する適切な時間であるかどうか確かめてくださいnext_execution_at
フィールド.重要:あなたのスクレーパーの周波数を変更する場合は、削除する必要があります
next_execution_at
値.それはあなたの新しい周波数に応じてリセットされます.次の関数は、スクリプトの実行中に再び取得しないように、すでにデータベースに挿入されたすべてのサイトジェネレータを取得します.
以下の関数を追加します
./scripts/scrapers/utils/utils.js
ファイル.'use strict'
...
const getAllSG = async (scraper) => {
const existingSG = await strapi.query('site-generator').find({
_limit: 1000,
scraper: scraper.id
}, ["name"]);
const allSG = existingSG.map(x => x.name);
console.log(`Site generators in database: \t${chalk.blue(allSG.length)}`);
return allSG;
}
module.exports = { getAllSG, scraperCanRun }
以下の関数を追加します
./scripts/scrapers/utils/utils.js
ファイル.'use strict'
...
const getDate = async () => {
const today = new Date();
const date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
const time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
return date+' '+time;
}
module.exports = { getDate, getAllSG, scraperCanRun }
以下の関数を追加します
./scripts/scrapers/utils/utils.js
ファイル.'use strict'
...
const getReport = async (newSG) => {
return { newSG: newSG, date: await getDate()}
}
module.exports = { getReport, getDate, getAllSG, scraperCanRun }
./scripts/scrapers/utils/utils.js
次のようになります.```bash
'use strict'
const parser = require('cron-parser');
const chalk = require('chalk');
const scraperCanRun = async (scraper) => {
const frequency = parser.parseExpression(scraper.frequency);
const current_date = parseInt((new Date().getTime() / 1000));
let next_execution_at = ""
if (scraper.next_execution_at){
next_execution_at = scraper.next_execution_at
}
else {
next_execution_at = (frequency.next().getTime() / 1000);
await strapi.query('scraper').update({
id: scraper.id
}, {
next_execution_at: next_execution_at
});
}
if (next_execution_at <= current_date){
await strapi.query('scraper').update({
id: scraper.id
}, {
next_execution_at: (frequency.next().getTime() / 1000)
});
return true
}
return false
}
const getAllSG = async (scraper) => {
const existingSG = await strapi.query('site-generator').find({
scraper: scraper.id
}, ["name"]);
const allSG = existingSG.map(x => x.name);
console.log(`Site generators in database: \t${chalk.blue(allSG.length)}`);
return allSG
}
const getDate = async () => {
const today = new Date();
const date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
const time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
return date+' '+time;
}
const getReport = async (newSG) => {
return { newSG: newSG, date: await getDate()}
}
module.exports = { getReport, getDate, getAllSG, scraperCanRun }
```
更新しましょう./scripts/scrapers/jamstack.js
今少しファイルを.でも、まずピペットを加えましょう.)人形師とチェリオを加えること
あなたにPetpeteerとチェリオを加えてください
package.json
以下のコマンドを実行します.yarn add puppeteer cheerio
./scripts/scrapers/jamstack.js
以下のファイルを指定します.'use strict'
const chalk = require('chalk');
const puppeteer = require('puppeteer');
const {
getReport,
getDate,
getAllSG,
scraperCanRun
} = require('./utils/utils.js')
let report = {}
let errors = []
let newSG = 0
const scrape = async () => {
console.log("Scrape function");
}
const main = async () => {
// Fetch the correct scraper thanks to the slug
const slug = "jamstack-org"
const scraper = await strapi.query('scraper').findOne({
slug: slug
});
// If the scraper doesn't exists, is disabled or doesn't have a frequency then we do nothing
if (scraper == null || !scraper.enabled || !scraper.frequency){
console.log(`${chalk.red("Exit")}: (Your scraper may does not exist, is not activated or does not have a frequency field filled in)`);
return
}
const canRun = await scraperCanRun(scraper);
if (canRun && scraper.enabled){
const allSG = await getAllSG(scraper)
await scrape(allSG, scraper)
report = await getReport(newSG);
}
}
exports.main = main;
今すぐあなたのファイルを保存!次のメッセージがあります.はい、あなたはそれがさらに行くことはありませんので、あなたのスクレーパーを有効にしなかった.したがって、継続するためには、このコードをコメントする必要があります.なぜなら、scrape関数のコードを待機する必要がないかどうかをコード化できますからです).
次のコードの一部をコメントします
'use strict'
const chalk = require('chalk');
const puppeteer = require('puppeteer');
const {
getReport,
getDate,
getAllSG,
scraperCanRun
} = require('./utils/utils.js')
let report = {}
let errors = []
let newSG = 0
const scrape = async () => {
console.log("Scrape function");
}
const main = async () => {
// Fetch the correct scraper thanks to the slug
const slug = "jamstack-org"
const scraper = await strapi.query('scraper').findOne({
slug: slug
});
// If the scraper doesn't exists, is disabled or doesn't have a frequency then we do nothing
// if (scraper == null || !scraper.enabled || !scraper.frequency){
// console.log(`${chalk.red("Exit")}: (Your scraper may does not exist, is not activated or does not have a frequency field filled in)`);
// return
// }
// const canRun = await scraperCanRun(scraper);
// if (canRun && scraper.enabled){
const allSG = await getAllSG(scraper)
await scrape(allSG, scraper)
// }
}
exports.main = main;
パーフェクト!今すぐデータをこするに飛び込む!
データの削り
アップデート
./scripts/scrapers/jamstack.js
以下のファイルを指定します.'use strict'
const chalk = require('chalk');
const cheerio = require('cheerio');
const puppeteer = require('puppeteer');
const {
getReport,
getDate,
getAllSG,
scraperCanRun
} = require('./utils/utils.js')
const {
createSiteGenerators,
updateScraper
} = require('./utils/query.js')
let report = {}
let errors = []
let newSG = 0
const scrape = async (allSG, scraper) => {
const url = "https://jamstack.org/generators/"
const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
const page = await browser.newPage();
try {
await page.goto(url)
} catch (e) {
console.log(`${chalk.red("Error")}: (${url})`);
errors.push({
context: "Page navigation",
url: url,
date: await getDate()
})
return
}
const expression = "//div[@class='generator-card flex flex-col h-full']"
const elements = await page.$x(expression);
await page.waitForXPath(expression, { timeout: 3000 })
const promise = new Promise((resolve, reject) => {
elements.forEach(async (element) => {
let card = await page.evaluate(el => el.innerHTML, element);
let $ = cheerio.load(card)
const name = $('.text-xl').text().trim() || null;
// Skip this iteration if the sg is already in db
if (allSG.includes(name))
return;
const stars = $('span:contains("stars")').parent().text().replace("stars", "").trim() || null;
const forks = $('span:contains("forks")').parent().text().replace("forks", "").trim() || null;
const issues = $('span:contains("issues")').parent().text().replace("issues", "").trim() || null;
const description = $('.text-sm.mb-4').text().trim() || null;
const language = $('dt:contains("Language:")').next().text().trim() || null;
const template = $('dt:contains("Templates:")').next().text().trim() || null;
const license = $('dt:contains("License:")').next().text().trim() || null;
const deployLink = $('a:contains("Deploy")').attr('href') || null;
await createSiteGenerators(
name,
stars,
forks,
issues,
description,
language,
template,
license,
deployLink,
scraper
)
newSG += 1;
});
});
promise.then(async () => {
await page.close()
await browser.close();
});
}
const main = async () => {
// Fetch the correct scraper thanks to the slug
const slug = "jamstack-org"
const scraper = await strapi.query('scraper').findOne({
slug: slug
});
// If the scraper doesn't exists, is disabled or doesn't have a frequency then we do nothing
// if (scraper == null || !scraper.enabled || !scraper.frequency){
// console.log(`${chalk.red("Exit")}: (Your scraper may does not exist, is not activated or does not have a frequency field filled in)`);
// return
// }
// const canRun = await scraperCanRun(scraper);
// if (canRun && scraper.enabled){
const allSG = await getAllSG(scraper)
await scrape(allSG, scraper)
report = await getReport(newSG);
// }
}
exports.main = main;
まず最初に、まだ作成していないファイルから関数をインポートしていることがわかります.
./scripts/scrapers/utils/query.js
. これらの2つの関数は、私たちのデータベースにサイトジェネレータを作成し、スクレーパ(エラーとレポート)を更新できます.このファイルは心配しないで作成します.それから、我々は
scrape
関数は、単に我々が使用したいデータをこすってpuppeteer
and cheerio
そして、以前に説明した関数を使って、このデータをデータベースに挿入します.クリエイトア
./scripts/scrapers/utils/query.js
以下を含むファイル'use strict'
const chalk = require('chalk');
const createSiteGenerators = async (name, stars, forks, issues, description, language, template, license, deployLink, scraper) => {
try {
const entry = await strapi.query('site-generator').create({
name: name,
stars: stars,
forks: forks,
issues: issues,
description: description,
language: language,
templates: template,
license: license,
deploy_to_netlify_link: deployLink,
scraper: scraper.id
})
} catch (e) {
console.log(e);
}
}
const updateScraper = async (scraper, report, errors) => {
await strapi.query('scraper').update({
id: scraper.id
}, {
report: report,
error: errors,
});
console.log(`Job done for: ${chalk.green(scraper.name)}`);
}
module.exports = {
createSiteGenerators,
updateScraper,
}
updateScraper
関数.それから、それが有効になっているならば、我々は我々のスクレーパーが実行されるか、頻度に応じてならないコードをコメントしないでしょう.それを加えましょう
./scripts/scrapers/jamstack.js
ファイル'use strict'
const chalk = require('chalk');
const cheerio = require('cheerio');
const puppeteer = require('puppeteer');
const {
getReport,
getDate,
getAllSG,
scraperCanRun
} = require('./utils/utils.js')
const {
createSiteGenerators,
updateScraper
} = require('./utils/query.js')
let report = {}
let errors = []
let newSG = 0
const scrape = async (allSG, scraper) => {
const url = "https://jamstack.org/generators/"
const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
const page = await browser.newPage();
try {
await page.goto(url)
} catch (e) {
console.log(`${chalk.red("Error")}: (${url})`);
errors.push({
context: "Page navigation",
url: url,
date: await getDate()
})
return
}
const expression = "//div[@class='generator-card flex flex-col h-full']"
const elements = await page.$x(expression);
await page.waitForXPath(expression, { timeout: 3000 })
const promise = new Promise((resolve, reject) => {
elements.forEach(async (element) => {
let card = await page.evaluate(el => el.innerHTML, element);
let $ = cheerio.load(card)
const name = $('.text-xl').text().trim() || null;
// Skip this iteration if the sg is already in db
if (allSG.includes(name))
return;
const stars = $('span:contains("stars")').parent().text().replace("stars", "").trim() || null;
const forks = $('span:contains("forks")').parent().text().replace("forks", "").trim() || null;
const issues = $('span:contains("issues")').parent().text().replace("issues", "").trim() || null;
const description = $('.text-sm.mb-4').text().trim() || null;
const language = $('dt:contains("Language:")').next().text().trim() || null;
const template = $('dt:contains("Templates:")').next().text().trim() || null;
const license = $('dt:contains("License:")').next().text().trim() || null;
const deployLink = $('a:contains("Deploy")').attr('href') || null;
await createSiteGenerators(
name,
stars,
forks,
issues,
description,
language,
template,
license,
deployLink,
scraper
)
newSG += 1;
});
});
promise.then(async () => {
await page.close()
await browser.close();
});
}
const main = async () => {
// Fetch the correct scraper thanks to the slug
const slug = "jamstack-org"
const scraper = await strapi.query('scraper').findOne({
slug: slug
});
// If the scraper doesn't exists, is disabled or doesn't have a frequency then we do nothing
if (scraper == null || !scraper.enabled || !scraper.frequency){
console.log(`${chalk.red("Exit")}: (Your scraper may does not exist, is not activated or does not have a frequency field filled in)`);
return
}
const canRun = await scraperCanRun(scraper);
if (canRun && scraper.enabled){
const allSG = await getAllSG(scraper)
await scrape(allSG, scraper)
report = await getReport(newSG);
await updateScraper(scraper, report, errors)
}
}
exports.main = main;
```bash
Exit: (Your scraper may not exist, is not activated, or does not have a frequency field filled in)
```
frequency
に設定し、next_execution_at
フィールド.このチュートリアルでは、1分の周波数をすばやく結果を見るために設定します.次に、単に有効にする必要があります.アップデート
./config/functions/bootstrap.js
デフォルト値:'use strict'
/**
* An asynchronous bootstrap function that runs before
* your application gets started.
*
* This gives you an opportunity to set up your data model,
* run jobs, or perform some special logic.
*
* See more details here: https://strapi.io/documentation/developer-docs/latest/concepts/configurations.html#bootstrap
*/
module.exports = () => {};
./config/functions/cron.js
次のコードを使用します.'use strict';
/**
* Cron config that gives you an opportunity
* to run scheduled jobs.
*
* The cron format consists of:
* [SECOND (optional)] [MINUTE] [HOUR] [DAY OF MONTH] [MONTH OF YEAR] [DAY OF WEEK]
*
* See more details here: https://strapi.io/documentation/developer-docs/latest/concepts/configurations.html#cron-tasks
*/
const jamstack = require('../../scripts/scrapers/jamstack.js')
module.exports = {
'* * * * *': () => {
jamstack.main()
}
};
./config/server.js
以下のファイルを指定します.module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
admin: {
auth: {
secret: env('ADMIN_JWT_SECRET', 'ea8735ca1e3318a64b96e79cd093cd2c'),
},
},
cron: {
enabled: true,
}
});
next_execution_at
あなたの周波数に応じて対応する1つの値は、ここで、次の分後.だから次の分後
next_execution_at
Timestampは実際のものと比較されます、そして、もちろん、あなたのスクレーパーが実行されるように、劣るか等しいでしょう.新しいnext_execution_at
これに応じてタイムスタンプが次の分に設定されますfrequency
.さて、私はそれがこの迅速かつ簡単なチュートリアルのためだと思う!
結論
私はあなたがそれを楽しんでほしい!
あなたが学習を維持したい場合はAcademy ストーカーの専門家になるか、単に我々の閲覧blog あなたが好きなすべての科目を明らかにする.
Reference
この問題について(ウェブでのラッピング), 我々は、より多くの情報をここで見つけました https://dev.to/strapijs/web-scraping-with-strapi-31khテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol