2

我正在抓取一个网页,并在抓取它之后从该网页中提取所有链接,然后我尝试使用下面的代码使用 Apache Tika 和 BoilerPipe 解析所有 url,因此对于某些 url,它解析得很好,但我得到的 XML 很少以下错误。我不确定这个错误是什么意思。我的代码有问题还是 XML 文件有问题?这是 HTML Parser.java 中下面的第 100 行

String parsedText = tika.parseToString(htmlStream, md);

我遇到的错误-

org.apache.tika.exception.TikaException: Invalid XML: Error on line 16: Invalid byte 1 of 1-byte UTF-8 sequence.
        at org.apache.tika.parser.feed.FeedParser.parse(FeedParser.java:75)

        at org.apache.tika.parser.CompositeParser.parse(CompositeParser.java:197)
        at org.apache.tika.parser.CompositeParser.parse(CompositeParser.java:197)
        at org.apache.tika.parser.AutoDetectParser.parse(AutoDetectParser.java:135)
        at org.apache.tika.Tika.parseToString(Tika.java:357)
        at edu.uci.ics.crawler4j.crawler.HTMLParser.parse(HTMLParser.java:101)
        at edu.uci.ics.crawler4j.crawler.WebCrawler.handleHtml(WebCrawler.java:227)
        at edu.uci.ics.crawler4j.crawler.WebCrawler.processPage(WebCrawler.java:299)
        at edu.uci.ics.crawler4j.crawler.WebCrawler.run(WebCrawler.java:118)
        at java.lang.Thread.run(Unknown Source)

HTMLParser.java 代码-

public void parse(String htmlContent, String contextURL) {

    InputStream htmlStream = null;
    text = null;
    title = null;
    metaData = new HashMap<String, String>();

    urls = new HashSet<String>();
    char[] chars = htmlContent.toCharArray();

    bulletParser.setCallback(textExtractor);
    bulletParser.parse(chars);

    try {
        text = articleExtractor.getText(htmlContent);
    } catch (BoilerpipeProcessingException e) {
        e.printStackTrace();
    }

    if (text == null){
        text = textExtractor.text.toString().trim(); 
    }

    title = textExtractor.title.toString().trim();
    try {
        Metadata md = new Metadata();
        htmlStream = new ByteArrayInputStream(htmlContent.getBytes());
        String parsedText = tika.parseToString(htmlStream, md);
        //very unlikely to happen
        if (text == null){
            text = parsedText.trim();
        }
        processMetaData(md);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        IOUtils.closeQuietly(htmlStream);
    }
    bulletParser.setCallback(linkExtractor);
    bulletParser.parse(chars);
    Iterator<String> it = linkExtractor.urls.iterator();

    String baseURL = linkExtractor.base();
    if (baseURL != null) {
        contextURL = baseURL;
    }

    int urlCount = 0;
    while (it.hasNext()) {
        String href = it.next();
        href = href.trim();
        if (href.length() == 0) {
            continue;
        }
        String hrefWithoutProtocol = href.toLowerCase();
        if (href.startsWith("http://")) {
            hrefWithoutProtocol = href.substring(7);
        }
        if (hrefWithoutProtocol.indexOf("javascript:") < 0
                && hrefWithoutProtocol.indexOf("@") < 0) {
            URL url = URLCanonicalizer.getCanonicalURL(href, contextURL);
            if (url != null) {
                urls.add(url.toExternalForm());
                urlCount++;
                if (urlCount > MAX_OUT_LINKS) {
                    break;
                }   
            }               
        }
    }
}
4

2 回答 2

1

尝试改变

htmlStream = new ByteArrayInputStream(htmlContent.getBytes());

String utfHtmlContent = new String(htmlContent.getBytes(),"UTF-8")
htmlStream = new ByteArrayInputStream(utfHtmlContent.getBytes());

这可能是一个 hack,您可能不想将其用作最终解决方案,但如果它在此更改后开始工作,您将知道输入最初不是 UTF-8。

于 2011-11-30T00:42:52.647 回答
1

异常来自 FeedParser 类,它表明您尝试解析的资源是 RSS 或 Atom 提要,而不是 HTML 文档。

根据异常,您似乎正在处理一个格式错误的提要,该提要声明自己为 UTF-8(带<?xml version="1.0" encoding="UTF-8"?>前缀),但随后包含其他一些非 UTF-8 编码的内容。鉴于 XML 的严格解析规则,无法解析此提要,因此您收到的 TikaException 符合预期。

有关该问题的更多详细信息,我建议您将提要验证器指向麻烦的 URL。

于 2011-11-30T08:38:19.260 回答