【问题标题】:Is there a way to improved method for separating a substring from search position text via indexOf?有没有办法改进通过 indexOf 将子字符串与搜索位置文本分开的方法?
【发布时间】:2021-08-31 17:26:26
【问题描述】:

我使用的方法我需要把+13-1在搜索文本各部分位置的时候放在计算里面(const Beforeconst After),有没有更靠谱的正确的方法?

  const PositionBefore = TextScript.indexOf(Before)+13;
  const PositionAfter = TextScript.indexOf(After)-1;

我担心由于某种原因搜索文本发生了变化,而我忘记更改计算的数字,这会导致检索到的文本出错。

我返回的文本部分是日期和时间:

2021-08-31 19:12:08
function Clock() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('Clock');
  var url = 'https://int.soccerway.com/';
  
  const contentText = UrlFetchApp.fetch(url).getContentText();
  const $ = Cheerio.load(contentText);
  
  const Before = '"timestamp":"';
  const After = '});\n    block.registerForCallbacks();';
  
  var ElementSelect = $('script:contains(' + Before + ')');
  var TextScript = ElementSelect.html().replace("\n","");
  
  const PositionBefore = TextScript.indexOf(Before)+13;
  const PositionAfter = TextScript.indexOf(After)-1;
  
  sheet.getRange(1, 1).setValue(TextScript.substring(PositionBefore, PositionAfter));
}

var TextScript中收集的示例全文:

  (function() {
    var block = new HomeMatchesBlock('block_home_matches_31', 'block_home_matches', {"block_service_id":"home_index_block_homematches","date":"2021-08-31","display":"all","timestamp":"2021-08-31 19:12:08"});
    block.registerForCallbacks();
    
    $('block_home_matches_31_1_1').observe('click', function() { block.filterContent({"display":"all"}); }.bind(block));
$('block_home_matches_31_1_2').observe('click', function() { block.filterContent({"display":"now_playing"}); }.bind(block));


      block.setAttribute('colspan_left', 2);
  block.setAttribute('colspan_right', 2);



    TimestampFormatter.format('block_home_matches_31');
  })();
  

【问题讨论】:

  • 对于那些投票结束我的问题的人,当我寻求帮助以改进我的代码中的某些内容时,这是什么原因?

标签: javascript google-apps-script cheerio


【解决方案1】:

没有办法消除源内容结构变化的风险。

您可以采取一些措施来尽量减少忘记更改代码的可能性 - 例如,不再需要硬编码 +13-1。但除此之外,您的代码失败可能还有其他原因。

当你的代码确实失败时,让它变得非常明显可能更重要。

考虑以下示例(为简单起见,不使用 Cheerio):

function demoHandler() {
  var url = 'https://int.soccerway.com/';
  const contentText = UrlFetchApp.fetch(url).getContentText();

  var matchedJsonString = contentText.match(/{.*?"timestamp".*?}/)[0];
  if ( matchedJsonString ) {
    try {
      var json = JSON.parse(matchedJsonString);
    } catch(err) {
      console.log( err ); // "SyntaxError..."
    }
    console.log(json.timestamp)
  } else {
    consle.log( 'Something went terribly wrong...' )
  }

}

当您运行上述函数时,它会在控制台打印以下内容:

2021-08-31 23:18:46

它通过假设 "timestamp" 的键值是 JSON 字符串的一部分来做到这一点,以 { 开头并以 } 结尾。

因此,您可以提取此 JSON 字符串并将其转换为 JavaScript 对象,然后直接访问时间戳值,而无需处理子字符串。

如果 JSON 无效,您将收到类似以下的显式错误:

[SyntaxError: Unexpected token c in JSON at position 0]

抓取网页数据几乎总是存在这些类型的风险:如果源结构在没有警告的情况下发生更改,您的代码可能会变得脆弱和容易崩溃。试着让 suc 的变化尽可能引人注目。在您的情况下,将错误写入您的电子表格并使其非常明显(红色、粗体等)。

并充分利用try...catch 语句。见:try...catch

【讨论】:

    猜你喜欢
    • 2018-04-17
    • 2016-08-02
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    • 2014-05-05
    相关资源
    最近更新 更多