【问题标题】:Parse HTML links from a google query从谷歌查询中解析 HTML 链接
【发布时间】:2011-03-28 11:32:59
【问题描述】:

首先修改后的代码抛出javax.swing.text.ChangedCharSetException:

import java.io.*;
import java.net.*;

public class Main
{
    public static void main(String[] args) throws IOException, Exception
    {
        String query = "#pragma";
        Socket s = new Socket("google.com",80);
        PrintStream p = new PrintStream(s.getOutputStream());
        p.print("GET /search?q="+query+" HTTP/1.0\r\n");
        p.print("User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n");
        p.print("Connection: close\r\n\r\n");

        InputStreamReader in = new InputStreamReader(s.getInputStream());
        BufferedReader buffer = new BufferedReader(in);
//        String line;
//
//        while ((line = buffer.readLine()) != null)
//        {  System.out.println(line); }
        HTMLUtils.ParseLinks (buffer);
        in.close();
    }
}


import java.io.BufferedReader;
import java.io.IOException;
//import java.io.FileReader;
import java.io.Reader;
import java.util.List;
import java.util.ArrayList;

import javax.swing.text.html.parser.ParserDelegator;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;
import javax.swing.text.html.HTML.Tag;
import javax.swing.text.html.HTML.Attribute;
import javax.swing.text.MutableAttributeSet;

public class HTMLUtils
{
  private HTMLUtils() {}

  public static List<String> extractLinks(Reader reader) throws IOException
  {
    final ArrayList<String> list = new ArrayList<String>();

    ParserDelegator parserDelegator = new ParserDelegator();
    ParserCallback parserCallback = new ParserCallback()
    {
      public void handleText(final char[] data, final int pos) { }
      public void handleStartTag(Tag tag, MutableAttributeSet attribute, int pos)
      {
        if (tag == Tag.A) {
          String address = (String) attribute.getAttribute(Attribute.HREF);
          list.add(address);
        }
      }
      public void handleEndTag(Tag t, final int pos) {  }
      public void handleSimpleTag(Tag t, MutableAttributeSet a, final int pos) { }
      public void handleComment(final char[] data, final int pos) { }
      public void handleError(final java.lang.String errMsg, final int pos) { }
    };
    parserDelegator.parse(reader, parserCallback, false);
    return list;
  }

  public static void ParseLinks(BufferedReader buffer) throws Exception{
    //FileReader reader = new FileReader("buffer");
    List<String> links = HTMLUtils.extractLinks(buffer);
    for (String link : links) {
      System.out.println(link);
    }
  }
}

请注意,此示例中的用户代理适用于 IE。

现在我有 3 个问题:

  1. 我如何/可以将 HTMLUtils.ParseLinks 方法传递给“原始缓冲区”而不是她期望的 HTML 文件(我可以将缓冲区写入文件,但我想这是不必要的)
  2. 我不知道如何在查询语句中输入引号 (" ") 以获取整个字符串,即:query=" "New York Yankees" "
  3. 从主机获取User-Agent字符串有这么复杂吗??? link text

我不得不说它是我使用的导入类,我真的不明白那里发生了什么。我会尝试了解它何时会起作用 [-8

THNX

【问题讨论】:

    标签: java html


    【解决方案1】:

    阅读http://code.google.com/apis/ajaxsearch/,从 JSON 字符串中获取数据比挖掘大量 HTML 容易得多。有一个用于消化 JSON 的开源 Java 类:http://www.json.org/java/。传输 JSON 也需要更少的带宽!

    【讨论】:

    • 嗨,弗莱德利,我对 JSON 不熟悉一个带有“概念证明”的链接,您建议的内容可能会有所帮助...THNX
    • 它的好处是你不需要知道它是如何工作的。使用适当的调用检索 JSON 字符串后,将其初始化: JSONObject j = new JSONObject(jsonString);然后一切都在 j 下的格式良好的数据结构中,因此您可以进行如下调用: int myInt = j.getInt['someTag']; JSONObject[] myArray = j.getJSONArray['Results'];字符串标题 = myArray.getJSONObject(0).getString['title'];你只需要阅读api上的文档来学习数据结构,那么你实际上需要使用的方法就很少了。
    【解决方案2】:

    如果您想在 Java 中执行此操作,您应该考虑使用 XPath 从响应中提取所有链接。因此,您首先必须convert the response to XML。然后可以apply an XPath查询like

    //a/@href
    

    提取链接的所有href 属性。您可以将查询修改为仅包含来自 Google 结果的链接,而不包含来自广告等的链接。

    Here 是另一个帮助您入门的教程。

    编码愉快。

    顺便说一句:为了避免在创建 HTTP 请求时出错并且(更重要的是)避免不必要的工作,您可以使用像 Apache Commons HTTPClient 这样的库。这会将您的工作减少到:

    HttpClient client = new HttpClient();
    HttpMethod method = new GetMethod("http://www.google.com/search?q=" + query);
    int statusCode = client.executeMethod(method);
    if (statusCode != HttpStatus.SC_OK) {
      System.err.println("Method failed: " + method.getStatusLine());
    }
    String response = new String(method.getResponseBody());
    

    【讨论】:

    • 如果您要解析 HTML 而不是使用轻量级 JSON Web 服务,那么我会推荐 Jsoup 而不是 HttpClient。 HttpClient 很好,但它没有提供任何用于解析 HTML 的内容。你也可以使用 java.net.URLConnection。
    • @BalusC 嘿,这很酷。以前没听说过JSoup。感谢您的提示。
    猜你喜欢
    • 2019-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多