【问题标题】:Replace all URLs in a HTML替换 HTML 中的所有 URL
【发布时间】:2013-01-03 11:45:45
【问题描述】:

我正在使用crawler4j 抓取一些 HTML 文件,并且我想用自定义链接替换这些页面中的所有链接。目前,我可以使用此代码获取源 HTML 和所有传出链接的列表:

        HtmlParseData htmlParseData = (HtmlParseData) page.getParseData();
        String html = htmlParseData.getHtml();
        List<WebURL> links = htmlParseData.getOutgoingUrls();

然而,一个简单的foreach 循环和搜索和替换不会让我得到我想要的。问题是WebURL.getURL(); 会返回绝对 URL,但有时链接是相对的,有时不是。

我想处理所有链接(图片、URL、JavaScript 文件等)。例如我想用view.php?url=http://www.domain.com/images/img.gif替换images/img.gif

我想到的唯一解决方案是使用有点复杂的Regex,但恐怕我会错过一些罕见的情况。这已经完成了吗?是否有图书馆或一些工具可以实现这一目标?

【问题讨论】:

  • 似乎没有这样的工具或库,但是正则表达式是一个强大的工具,迟早你将不得不学习如何使用它。我建议您立即尝试使用它。您可能还需要为此编写一些单元测试。
  • 你试过我的答案了吗?因为我遇到过像你这样的问题,我使用这个正则表达式
  • @GavinXiong 实际上,我对正则表达式非常熟悉。我已经完成了可以在强大的正则表达式的帮助下修改 c++ 源代码的工具。但是,正如我在下面的评论中提到的那样,可能存在某些情况,例如格式错误的 HTML 会导致问题。
  • @AlirezaNoori 我看不出在 HTML 格式错误的情况下你能做什么......一旦解析器完成了它的工作,那么你所能做的就是处理结果。那么你真的需要修改所有的链接吗?可能有指向 javascript、iframe 源、嵌入式 boject 源等的链接。你在哪里画线?
  • @Lirik 不是全部,大部分链接。例如,我不想替换电子邮件链接等。至于第一部分,我正在寻找解析器,而不是正则表达式。而且因为 crawler4j 已经有了,我可能不得不修改它的代码。但是,如果提供的话,我宁愿使用更好的解决方案。

标签: java html web-crawler crawler4j


【解决方案1】:

我认为您可以为此使用正则表达式:

例如:

  ...
   String regex = "\\/[^.]*\\/[^.]*\\.";
   Pattern pattern =  Pattern.compile(regex);
   Matcher  matcher = pattern.matcher(text);

   while(matcher.find()){
    String imageLink =  matcher.group();
    text = text.replace(imageLink,prefix+imageLink);
   }

【讨论】:

  • 这个正则表达式对于那个用途来说太简单了。它也将替换文本中的 URL。我不想要那个。另外,在我的问题中,我提到我有正则表达式,但我认为应该有某种编译器来实现更好的结果。例如,可能有一些格式错误的 HTML 不会被正则表达式捕获。
  • 这个正则表达式帮助你找到相对的 url。找到相对网址后,您可以将它们转换为您想要的类型。
【解决方案2】:

必须是 Java 解决方案吗? PhantomJs 结合pjscrape 可以站点抓取页面以查找所有网址。

您只需要创建一个配置 javascript 文件。

getlinks.js:

pjs.addSuite({
    url: 'http://stackoverflow.com/questions/14138297/replace-all-urls-in-a-html',
    noConflict: true,
    scraper: function() {
          var links = _pjs.$('a').map(function() {
           // convert relative URLs to absolute
           var link = _pjs.toFullUrl($(this).attr('href'));
           return link;
      });
      return links.toArray();
    }
});
pjs.config({ 
  // options: 'stdout' or 'file' (set in config.outFile)
    log: 'stdout',
    // options: 'json' or 'csv'
    format: 'json',
    // options: 'stdout' or 'file' (set in config.outFile)
    writer: 'stdout',
    scrape_output.json
});

然后运行命令phantomjs pjscrape.js getlinks.js。在本例中,输出存储在一个文件中(也可以记录在控制台中):

这是(部分)输出:

* Suite 0 starting
* Opening http://stackoverflow.com/questions/14138297/replace-all-urls-in-a-html
* Scraping http://stackoverflow.com/questions/14138297/replace-all-urls-in-a-html
* Suite 0 complete
* Writing 145 items
["http://stackoverflow.com/users/login?returnurl=%2fquestions%2f14138297%2freplace-all-urls-in-a-html","http://careers.stackoverflow.com","http://chat.stackoverflow.com","http://meta.stackoverflow.com","http://stackoverflow.com/about","http://stackoverflow.com/faq","http://stackoverflow.com/","http://stackoverflow.com/questions","http://stackoverflow.com/tags","http://stackoverflow.com/users","http://stackoverflow.com/badges","http://stackoverflow.com/unanswered","http://stackoverflow.com/questions/ask", ...
"http://creativecommons.org/licenses/by-sa/3.0/","http://creativecommons.org/licenses/by-sa/3.0/","http://blog.stackoverflow.com/2009/06/attribution-required/"]
* Saved 145 items

【讨论】:

  • 我的代码是用 Java 编写的。如果我找不到其他任何东西,我可以阅读这段代码并将其移植到 Java。但是,如果可能的话,我希望尽可能少做 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-04
  • 1970-01-01
  • 2020-07-24
  • 2013-06-24
  • 1970-01-01
  • 2013-01-12
  • 2020-11-12
相关资源
最近更新 更多