Использование FS для записи новых файлов, если найден определенный URL-адрес, и удаления файла, если он больше не найден - PullRequest
1 голос
/ 06 августа 2020

Я пытаюсь написать скрипт, когда будет найден новый URL, он превратится в ha sh. Убедитесь, что файл уже был записан, он просто игнорирует его, и, если он не известен ранее, его следует добавить.

needle.get(mainUrl, function(err, res) {
  if (err) throw err;

  if (res.statusCode == 200 && !err ) {
    var $ = cheerio.load(res.body)

    var href = $('div div a').each(function(index, element) {
      urlList.push($(element).attr("href"))

      var url =($(element).attr("href"))
      var hash = crypto.createHash('md5').update(url).digest('hex');
                
      fs.writeFile('./directory/otherdirectory' + `${hash}`, url, (err) => {
        if (err) throw err;
        console.log('Hash created: ' + url + ' saved as ' + hash
      });
    }
  )
}
})

Это то, что я делал до сих пор, но это только записывает новые файлы. он не проверяет, были ли уже добавлены файлы, и не удаляет файлы, которые больше не найдены.

Итак, что я пытаюсь сделать:

  1. Я написал сценарий который выбирает веб-сайт для URL-адресов.
  2. Ha sh все URL-адреса.
  3. Заставить FS проверять, был ли файл уже записан, если он просто проигнорировал его.
  4. Если он не известен ранее, добавьте его как новый файл.
  5. Если url больше не обнаруживается при загрузке, удалите его из списка.

1 Ответ

1 голос
/ 06 августа 2020

Я думаю, это может быть проблема X / Y , и поэтому я все еще жду ответа на мой комментарий .

С учетом сказанного, вы можно просто игнорировать существующие файлы, используя fs.existsSync, если это возвращает true, просто пропустите сохранение текущего файла, в противном случае сохраните его. И чтобы удалить файлы, которые больше не доступны, просто получите все файлы в каталоге, используя fs.readdir, и удалите файлы, чьи URL-адреса не указаны в ответе, используя fs.unlink :

needle.get(mainUrl, (err, res) => {
  if (err) throw err;

  if (res.statusCode == 200) {
    let $ = cheerio.load(res.body);

    let hashes = [];                                                      // list of hashes for this website (to be used later to keep only the items that are still available)
    $('div div a').each((index, element) => {
      let url = $(element).attr("href");
      let hash = crypto.createHash('md5').update(url).digest('hex');
      hashes.push(hash);                                                 // store the hash of the current url
      
      if (!fs.existsSync('./directory/otherdirectory/' + hash)) {        // if this file doesn't exist (notice the "not operator !" before fs.existsSync)
        fs.writeFile('./directory/otherdirectory/' + hash, url, err => { // save it
          if (err) throw err;
          console.log('Hash created: ' + url + ' saved as ' + hash);
        });
      }
    });

    fs.readdir('./directory/otherdirectory', (err, files) => {           // get a list of all the files in the directory
      if (err) throw err;
      files.forEach(file => {                                            // and for each file
        if(!hashes.includes(file)) {                                     // if it was not encountered above (meaning that it doesn't exist in the hashes array)
          fs.unlink('./directory/otherdirectory/' + file, err => {       // remove it
            if (err) throw err;
          });
        }
      });
    });
});

Другой подход:

Поскольку вы, кажется, хотите сохранить только URL-адреса, лучший способ - использовать один файл для хранения их все вместо того, чтобы хранить каждый URL-адрес в отдельном файле. Что-то вроде этого более эффективно:

needle.get(mainUrl, (err, res) => {
  if (err) throw err;

  if (res.statusCode == 200) {
    let $ = cheerio.load(res.body);

    let urls = $('div div a')                                           // get the 'a' elements
      .map((index, element) => $(element).attr("href"))                 // map each one into its href attribute
      .get();                                                           // and get them as an array
        
    fs.writeFile('./directory/list-of-urls', urls.join('\n'), err => {  // then save all the urls encountered in the file 'list-of-urls' (each on its own line, hence the join('\n'))
      if (err) throw err;
      console.log('saved all the urls to the file "list-of-urls"');
    });
  }
});

Таким образом старые URL-адреса будут автоматически удаляться, поскольку файл каждый раз перезаписывается, а новые URL-адреса будут добавляться автоматически. Нет необходимости проверять, встречается ли уже URL-адрес или нет, потому что он все равно будет повторно сохранен.

И если вы хотите получить список URL-адресов в другом месте, просто прочитайте файл и разделите его на '\n' вот так:

 fs.readFile('./directory/list-of-urls', 'utf8', (err, data) => {
   if (err) throw err;
   let urls = data.split('\n');
   // use urls here
 });
...