如何使用HTML解析器获取HTML页面中所有标签的完整信息

5

我正在使用HTML解析器开发一个应用程序。 下面的代码无法获取页面中的所有标签。 有些标签被忽略了,它们的属性和文本内容也被忽略了。 请帮我解释一下为什么会出现这种情况......或者建议其他方法......

 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");

     }
   }

}


2
问题太模糊了。请拿一个示例网站(也许是 http://google.com?)并详细说明缺少什么。 - BalusC
实际上,我想从在线购物网站(如amazon.com)中提取所有产品的信息,例如产品名称、价格等。我该怎么做? - user275965
4个回答

9
我可以用HTML解析器相当可靠地完成这个任务(前提是HTML文档的结构不变)。拥有稳定API的网络服务更好,但有时我们并没有这样的选择。 总体思路: 首先,您需要知道所需信息位于哪些标签(例如divmetaspan等)中,并了解识别这些标签的属性。例如:
 <span class="price"> $7.95</span>

如果你正在寻找这个“价格”,那么你对使用带有class为“price”的标签感兴趣。
HTML解析器具有按属性筛选的功能。
filter = new HasAttributeFilter("class", "price");

当使用过滤器进行解析时,您将获得一个节点(Nodes)列表,您可以对它们执行instanceof操作以确定它们是否为您感兴趣的类型。例如,对于span,您可以执行类似以下操作:
if (node instanceof Span) // or any other supported element.

在此处查看支持的标签列表

使用HTML解析器抓取包含有关网站描述的meta标签示例:

标签示例:

<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();
        }
    }

}

1

根据评论:

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

步骤1:阅读他们的robots文件。它通常位于站点的根目录下,例如http://amazon.com/robots.txt。如果你尝试访问的URL被Disallow覆盖在*User-Agent上,则停止此操作。联系他们,详细解释你要做什么,并要求他们提供可以为你提供所需信息的方式/替代方案/网络服务。否则,你将违反法律,可能会被该网站和/或你的ISP列入黑名单,甚至更糟。如果没有问题,那么继续进行第二步。

步骤2:检查所需网站是否已经有公共 Web 服务可用,这比解析整个 HTML 页面要容易得多。使用 Web 服务,您将根据一组简单的参数以简洁的格式(JSON 或 XML)获得所需的信息。寻找或联系他们以获取有关任何 Web 服务的详细信息。如果没有其他方法,请继续执行第3步。

步骤3:学习 HTML/CSS/JS 的工作原理,学习如何使用像 Firebug 这样的 Web 开发工具,学习如何通过右键单击 > 查看页面源代码 来解释您看到的 HTML/CSS/JS 源代码。我打赌所需的网站使用 JS/Ajax 来加载/填充您想要收集的信息。在这种情况下,您需要使用能够解析和执行 JS 的 HTML 解析器(您正在使用的解析器无法做到这一点)。这不是一项容易的工作,因此在完全清楚您要实现什么、是否允许以及是否有更易于使用的 Web 服务可用之前,我不会详细解释它。


步骤1:Robots.txt允许。这不是问题。步骤2:我尝试使用AWS,但它没有提供我需要的所有信息的全面列表。但是这些信息可以在网页上看到。所以我需要实际执行第3步。步骤3:现在的问题是,我需要提取产品名称、价格和特性。如果我手动识别这些信息在网页上存储的模式,就可以完成这个任务。但现在我想要一种方法,可以自动化这个模式查找或者能够在程序中提取它而无需提供任何模式。我该怎么做呢?谢谢。 - user275965

0

你似乎在使用Swing HtmlDocument。这可能不是最明智的想法。 我相信你使用NekoHtml会有更好的结果。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接