【问题标题】:How to use HTML Parser to get complete information about all tags in the HTML page如何使用 HTML Parser 获取 HTML 页面中所有标签的完整信息
【发布时间】:2010-02-18 10:32:48
【问题描述】:

我正在使用 HTML Parser 开发应用程序。 下面的代码无法获取页面中的整个标签集。 有一些标签被遗漏了,它们的属性和正文也被遗漏了。 请帮我解释为什么会这样......或者建议我其他方式......

 URL url = new URL("...");
 PrintWriter pw=new PrintWriter(new FileWriter("HTMLElements.txt"));

 URLConnection connection = url.openConnection();
 InputStream is = connection.getInputStream();
 InputStreamReader isr = new InputStreamReader(is);
 BufferedReader br = new BufferedReader(isr);

 HTMLEditorKit htmlKit = new HTMLEditorKit();
 HTMLDocument htmlDoc = (HTMLDocument)htmlKit.createDefaultDocument();
 HTMLEditorKit.Parser parser = new ParserDelegator();
 HTMLEditorKit.ParserCallback callback = htmlDoc.getReader(0);
 parser.parse(br, callback, true);

 ElementIterator iterator = new ElementIterator(htmlDoc);
 Element element;
   while ((element = iterator.next()) != null) 
   {
     AttributeSet attributes = element.getAttributes();
     Enumeration e=attributes.getAttributeNames();

     pw.println("Element Name :"+element.getName());
     while(e.hasMoreElements())
     {
      Object key=e.nextElement();
      Object val=attributes.getAttribute(key);
      int startOffset = element.getStartOffset();
   int endOffset = element.getEndOffset();
   int length = endOffset - startOffset;
   String text=htmlDoc.getText(startOffset, length);

      pw.println("Key :"+key.toString()+" Value :"+val.toString()+"\r\n"+"Text :"+text+"\r\n");

     }
   }

}

【问题讨论】:

  • 问题太模糊了。举一个示例网站(http://google.com 可能?),请详细说明到底缺少什么。
  • 实际上我想提取在线购物网站(如amazon.com)中列出的所有产品的产品名称、价格等信息,我该怎么做???

标签: java screen-scraping


【解决方案1】:

我使用HTML Parser 相当可靠地做到了这一点(前提是 HTML 文档不会改变其结构)。具有稳定 API 的 Web 服务要好得多,但有时我们就是没有。

总体思路:

您首先必须知道您想要的信息在哪些标签(divmetaspan 等)中,并知道识别这些标签的属性。示例:

 <span class="price"> $7.95</span>

如果您正在寻找这个“价格”,那么您对带有class“价格”的span标签感兴趣。

HTML Parser 具有按属性过滤的功能。

filter = new HasAttributeFilter("class", "price");

当您使用过滤器进行解析时,您会得到一个Nodes 列表,您可以对它们执行instanceof 操作以确定它们是否属于您感兴趣的类型,对于span,您会做类似的事情

if (node instanceof Span) // or any other supported element.

查看支持的标签列表here

使用 HTML Parser 获取包含网站描述的元标记的示例:

标签示例:

<meta name="description" content="Amazon.com: frankenstein: Books"/> 

代码:

import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.tags.MetaTag;

public class HTMLParserTest {
    public static void main(String... args) {
        Parser parser = new Parser();
        //<meta name="description" content="Some texte about the site." />
        HasAttributeFilter filter = new HasAttributeFilter("name", "description");
        try {
            parser.setResource("http://www.youtube.com");
            NodeList list = parser.parse(filter);
            Node node = list.elementAt(0);

            if (node instanceof MetaTag) {
                MetaTag meta = (MetaTag) node;
                String description = meta.getAttribute("content");

                System.out.println(description);
                // Prints: "YouTube is a place to discover, watch, upload and share videos."
            }

        } catch (ParserException e) {
            e.printStackTrace();
        }
    }

}

【讨论】:

    【解决方案2】:

    根据 cmets:

    实际上我想提取在线购物网站(如 amazon.com)中列出的所有产品的产品名称、价格等信息,我该怎么做?

    第 1 步: 阅读他们的 robots 文件。它通常位于站点的根目录,例如http://amazon.com/robots.txt。如果您尝试访问的 URL 被 User-Agent* 上的 Disallow 覆盖,则在此处停止。联系他们,向他们详细解释您要做什么,并向他们询问可以为您提供所需信息的方法/替代方案/网络服务。否则,您违反了法律,您可能会被网站和/或您的 ISP 或更糟的情况列入黑名单。如果不是,则继续第 2 步。

    第 2 步: 检查相关站点是否还没有可用的公共 Web 服务,这比解析整个 HTML 页面更容易使用。使用 Web 服务,您将基于一组简单的参数以简洁的格式(JSON 或 XML)准确获取您正在寻找的信息。环顾四周或与他们联系以获取有关任何 Web 服务的详细信息。如果没有办法,请继续执行步骤 3。

    第 3 步:了解 HTML/CSS/JS 的工作原理,了解如何使用 Firebug 等网络开发工具,了解如何解释您通过右键单击看到的 HTML/CSS/JS 源代码 > 查看页面源代码。我敢打赌,该网站使用 JS/Ajax 来加载/填充您想要收集的信息。在这种情况下,您将需要使用能够解析和执行 JS 的 HTML 解析器(您正在使用的那个不这样做)。这不会是一件容易的工作,所以我不会详细解释它,直到完全清楚你想要实现的目标以及是否允许这样做以及是否没有更易于使用的 Web 服务可用。

    【讨论】:

    • 第 1 步:Robots.txt 允许。这不是问题。第 2 步:我尝试使用 AWS,但它没有提供我需要的所有信息的完整列表。但是信息可以在网页上看到。所以我需要实际进入第3步第3步:现在问题是我需要提取产品名称,价格,功能。如果我手动识别这些信息在网页上的存储方式,则可以做到这一点。但是现在我想要一种方法可以自动进行这种模式查找,或者应该能够在没有向程序提供任何模式的情况下提取它。我应该怎么做?谢谢
    【解决方案3】:

    您似乎使用了 Swing HtmlDocument。这可能不是有史以来最聪明的主意。 我相信使用NekoHtml 为例,你会得到更好的结果。

    【讨论】:

      【解决方案4】:

      或者您可以使用的另一个简单库是 jtidy,它可以在解析之前清理您的 html。 希望这会有所帮助。

      http://sourceforge.net/projects/jtidy/

      Ciao!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-01
        • 2021-04-10
        • 1970-01-01
        • 1970-01-01
        • 2011-02-26
        • 2022-11-10
        相关资源
        最近更新 更多