首页 > 解决方案 > Cheerio 在脚本标签中查找文本

问题描述

我想在脚本标签中提取 js 脚本。

这是脚本标签:

<script>
  $(document).ready(function(){

    $("#div1").click(function(){
      $("#divcontent").load("ajax.content.php?p=0&cat=1");
    });

    $("#div2").click(function(){
      $("#divcontent").load("ajax.content.php?p=1&cat=1");
    });

  });
</script>

我有一个像这样的 id 数组['div1', 'div2'],我需要在其中提取 url 链接:所以如果我调用一个函数:

getUrlOf('div1');

它会回来ajax.content.php?p=0&cat=1

标签: javascriptnode.jscheerio

解决方案


使用 Cheerio,很容易获取script 标签的文本:

const cheerio = require('cheerio');
const $ = cheerio.load("the HTML the webpage you are scraping");

// If there's only one <script>
console.log($('script').text());

// If there's multiple scripts
$('script').each((idx, elem) => console.log(elem.text()));

从这里开始,您实际上只是在问“我如何解析一个通用的 javascript 块并提取链接列表”。我同意上面评论中的帕特里克,你可能不应该。你能制作一个正则表达式,让你找到脚本中的每个链接并推断出它链接到的页面吗?是的。但很有可能,如果此页面发生任何变化,您的脚本将立即中断 - 页面的作者可能会切换到内联<a>标签、重构代码、使用实时事件等。

请注意,依赖此脚本标记的确切内容会使您的应用程序非常脆弱——甚至比通常的页面抓取更脆弱。

编辑:当然,这是一个松散但有效的正则表达式的例子:

let html = "incoming html";
let regex = /\$\("(#.+?)"\)\.click(?:.|\n)+?\.load\("(.+?)"/;
let match;

while (match = regex.exec(html)) {
    console.log(match[1] + ': ' + match[2]);
}

如果您是正则表达式的新手:此表达式包含两个捕获组,在括号中(第一个是 div id,第二个是链接文本),以及中间的一个非捕获组,它的存在只是为了确保正则表达式将通过换行符继续。我说它是“松散的”,因为它正在寻找的匹配看起来像这样:

  • $(" ***").click ***ignored chars***.load(" ***"

因此,根据 javascript 的数量和相似程度,您可能需要收紧它以避免误报。


推荐阅读