解析谷歌查询中的HTML链接

时间:2010-08-11 15:56:58

标签: java html

首先修改了引发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
  4. 我必须说它是我使用的导入类,我真的不明白它们在那里发生了什么。我会试着了解它何时起作用[-8

    日Thnx

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

//a/@href

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

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

快乐的编码。

BTW :为了避免在创建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());