Разбор XHTML результатов от Bing - PullRequest
0 голосов
/ 05 мая 2010

Я пытаюсь проанализировать полученные поисковые запросы от поисковых систем Bing, которые получены в формате xhtml в java. Я использую саксофон XmlReader, чтобы прочитать результаты, но я продолжаю получать ошибки. вот мой код - этот для хадлера читателя:

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


public class XHTMLHandler extends DefaultHandler{
    public XHTMLHandler()
    {
        super();
    }
    public void startDocument ()
    {
        System.out.println("Start document");
    }
    public void endDocument ()
    {
    System.out.println("End document");
    }
    public void startElement (String uri, String name,String qName, Attributes atts)
    {
        if ("".equals (uri))
                System.out.println("Start element: " + qName);
            else
                System.out.println("Start element: {" + uri + "}" + name);
    }

    public void endElement (String uri, String name, String qName)
    {
    if ("".equals (uri))
        System.out.println("End element: " + qName);
    else
        System.out.println("End element:   {" + uri + "}" + name);
    }
    public void startPrefixMapping (String prefix, String uri)
      throws SAXException {
    }
    public void endPrefixMapping (String prefix)
      throws SAXException {
    }



    public void characters (char ch[], int start, int length)
        {
        System.out.print("Characters:    \"");
        for (int i = start; i < start + length; i++) {
            switch (ch[i]) {
            case '\\':
            System.out.print("\\\\");
            break;
            case '"':
            System.out.print("\\\"");
            break;
            case '\n':
            System.out.print("\\n");
            break;
            case '\r':
            System.out.print("\\r");
            break;
            case '\t':
            System.out.print("\\t");
            break;
            default:
            System.out.print(ch[i]);
            break;
            }
        }
        System.out.print("\"\n");
        }

}

и это сама программа:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpRetryException;
import java.net.HttpURLConnection;
import java.net.URL;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;


public class Searching {
    private String m_urlBingSearch  = "http://www.bing.com/search?q=";
    private HttpURLConnection m_httpCon;
    private OutputStreamWriter m_streamWriter;
    //private BufferedReader m_bufferReader;
    private URL m_serverAdress;
    private StringBuilder sb;
    private String m_line;
    private InputSource m_inputSrc;
    public Searching()
    {

        m_httpCon = null;
        m_streamWriter = null;
        //m_bufferReader = null;
        m_serverAdress = null;
        sb = null;
        m_line = new String();
    }
    public void SearchBing(String searchPrms) throws SAXException,IOException 
    {


            //set up connection
            sb = new StringBuilder();
            sb.append(m_urlBingSearch);
            sb.append(searchPrms);
            m_serverAdress = new URL(sb.toString());
            m_httpCon = (HttpURLConnection)m_serverAdress.openConnection();
            m_httpCon.setRequestMethod("GET");
            m_httpCon.setDoOutput(true);
            m_httpCon.setConnectTimeout(10000);
            m_httpCon.connect();
            //m_streamWriter = new OutputStreamWriter(m_httpCon.getOutputStream());
            //m_bufferReader = new BufferedReader(new InputStreamReader(m_httpCon.getInputStream()));
            XMLReader reader = XMLReaderFactory.createXMLReader();
            XHTMLHandler handle = new XHTMLHandler();
            reader.setContentHandler(handle);
            reader.setErrorHandler(handle);
            //reader.startPrefixMapping("html", "http://www.w3.org/1999/xhtml");
            handle.startPrefixMapping("html", "http://www.w3.org/1999/xhtml");
            m_inputSrc = new InputSource(m_httpCon.getInputStream());
            reader.parse(m_inputSrc);
            m_httpCon.disconnect();


    }
    public static void main(String [] args) throws SAXException,IOException
    {
        Searching s = new Searching();
        s.SearchBing("beatles");
    }
}

это мое сообщение об ошибке:

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 503 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at Searching.SearchBing(Searching.java:57)
    at Searching.main(Searching.java:65)

Может кто-нибудь, пожалуйста, помогите? я думаю, что это как-то связано с dtd, но я не знаю, как это исправить

Ответы [ 2 ]

1 голос
/ 05 мая 2010

Сервер вернул код ответа HTTP: 503 для URL: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd

Очевидно, вы пытаетесь проанализировать документ XHTML, используя анализатор извлечения внешних сущностей. Он перетаскивает во внешнее подмножество DTD, чтобы он мог читать любые объявления для специфичных для HTML сущностей, таких как &nbsp; или &eacute;.

В настоящее время вы получаете HTTP 503 от сервера w3.org, на котором размещено это внешнее подмножество DTD, но даже если бы вы этого не делали, было бы крайне невежливо бомбардировать этот сервер запросами DTD каждый раз. ты делаешь царапину (Может быть, они блокируют вас по той же причине?)

Вы можете создать EntityResolver для возврата своей локальной копии DTD или урезанной версии, включающей только определения сущностей. Или вы можете попросить читателя вообще не извлекать DTD, используя setFeature, чтобы отключить эту опцию, если у вас есть реализация XMLReader, которая поддерживает эту функцию. (например, для Xerxes .) Хотя тогда вы можете столкнуться с проблемами, если документ содержит не встроенные ссылки на сущности, такие как &nbsp;.

Кроме того, поскольку это живая веб-страница, которая обслуживается как text/html, и особенно потому, что она исходит от Microsoft, вероятно, весьма оптимистично полагать, что она останется корректной! Соскребание экрана обычно лучше всего выполнять с помощью парсера, который допускает особенности HTML. Но, как говорится в комментариях выше, использование API гораздо лучше, чем скрининг экрана в любом случае.

0 голосов
/ 10 мая 2010

Вы правы, Боб, и я вам очень благодарен. Мое решение: используйте метод Set Feature в парсере URL.

вот мое решение, просто добавьте строки: reader.setFeature ("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); и это все.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...