2011-10-26 2 views
4

지금이 문제에 며칠 동안 고생하고 있습니다. 여러 조합을 시도했지만 성공하지 못한 채로 내 눈이 상처를 내고 있습니다. 문제는 인터넷에서 데이터 형식을 가져와 구문 분석 한 다음 사용자에게 보여줄 수있는 앱을 만들고 있다는 것입니다. 나는 이것을하기 위해 여러 가지 방법을 시도해 보았고, JSOUP을 사용하는 것은 특히 파싱과 결과에서 데이터를 가져 오는 데 매우 도움이되었다.GET 요청에 쿠키를 전달할 때의 문제 (POST 후)

그러나 해결할 수없는 한 가지 문제가 있습니다. 정규 HTTPClient와 JSOUP를 시도했지만 필요한 데이터를 성공적으로 가져올 수 없습니다. 다음은 내 코드 (JSOUP 버전)입니다.

public void bht_ht(Context c, int pozivni, int broj) throws IOException { 
    //this is the first connection, to get the cookies (I have tried the version without this method separate, but it's the same 
    Connection.Response resCookie = Jsoup.connect("http://www.bhtelecom.ba/imenik_telefon.html") 
      .method(Method.GET) 
      .execute(); 
    String sessionId = resCookie.cookie("PHPSESSID"); 
    String fetypo = resCookie.cookie("fe_typo_user"); 
    //these two above are the cookies 

    //the POST request, with the data asked 
    Connection.Response res = Jsoup.connect("http://www.bhtelecom.ba/imenik_telefon.html?a=search") 
       .data("di", some_data) 
       .data("br", some_data) 
       .data("btnSearch","Tra%C5%BEi") 
       .cookie("PHPSESSID", sessionId) 
       .cookie("fe_typo_user", fetypo) 
       .method(Method.POST) 
       .execute(); 

    Document dok = res.parse(); 

      //So, here is the GET request for the site which contains the results, and this site is redirected to with HTTP 302 response after the POSt result 
    Document doc = Jsoup.connect("http://www.bhtelecom.ba/index.php?id=3226&") 
      .cookie("PHPSESSID", sessionId) 
      .cookie("fe_typo_user", fetypo) 
      .referrer("http://www.bhtelecom.ba/imenik_telefon.html") 
      .get(); 

    Document doc = res2.parse(); 

    Element elemenat = doc.select("div.boxtexter").get(0); 

    String ime = elemenat.text(); 

} 

따라서 최종 결과는 반환 된 데이터를 포함하는 문자열이됩니다. 그러나 무엇을 시도해도 "빈 페이지"를 얻을 수 있으며 구문 분석 된 텍스트이므로 브라우저에서 요청한 모든 것을 시뮬레이션했습니다. 여기

는 POST이며, 브라우저에 의해 촬영 된 원시 헤더를 GET : (게시물)

> POST /imenik_telefon.html?a=search HTTP/1.1 Host: www.bhtelecom.ba 
> Content-Length: 56 Cache-Control: max-age=0 Origin: 
> http://www.bhtelecom.ba User-Agent: Mozilla/5.0 (Windows NT 6.1; 
> WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 
> Safari/535.1 Content-Type: application/x-www-form-urlencoded Accept: 
> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
> Referer: http://www.bhtelecom.ba/index.php?id=3226& Accept-Encoding: 
> gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: 
> ISO-8859-1,utf-8;q=0.7,*;q=0.3 Cookie: 
> PHPSESSID=opavncj3317uidbt93t9bie980; 
> fe_typo_user=332a76d0b1d4944bdbbcd28d63d62d75; 
> __utma=206281024.1997742542.1319583563.1319583563.1319588786.2; __utmb=206281024.1.10.1319588786; __utmc=206281024; __utmz=206281024.1319583563.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) 
> 
> di=033&br=123456&_uqid=&_cdt=&_hsh=&btnSearch=Tra%C5%BEi 

이 GET, (그 응답), 데이터 I에서

> GET /index.php?id=3226& HTTP/1.1 Host: www.bhtelecom.ba Cache-Control: 
> max-age=0 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) 
> AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1 
> Accept: 
> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
> Referer: http://www.bhtelecom.ba/index.php?id=3226& Accept-Encoding: 
> gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: 
> ISO-8859-1,utf-8;q=0.7,*;q=0.3 Cookie: 
> PHPSESSID=opavncj3317uidbt93t9bie980; 
> __utma=206281024.1997742542.1319583563.1319583563.1319588786.2; __utmb=206281024.1.10.1319588786; __utmc=206281024; __utmz=206281024.1319583563.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); fe_typo_user=07745dd2a36a23c64c2297026061a2c2 

을 (수) 필요가 있지만 매개 변수, 쿠키 또는 내가 시도한 모든 것의 조합으로 POST를 작성하고 이제는 그 데이터를 원한다고 생각할 수는 없습니다.

다음은 JSOUP 파서가없는 코드의 버전입니다.하지만 쿠키를 확인할 때 POST 및 GET과 동일하지만 성공하지는 않지만 작동하도록 설정할 수는 없습니다.

DefaultHttpClient client = new DefaultHttpClient(); 


       String postURL = "http://www.bhtelecom.ba/imenik_telefon.html?a=search"; 
       HttpPost post = new HttpPost(postURL); 
       post.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE); 


       List<NameValuePair> params = new ArrayList<NameValuePair>(); 
       params.add(new BasicNameValuePair("di", "035")); 
       params.add(new BasicNameValuePair("br", "819443")); 
       params.add(new BasicNameValuePair("btnSearch","Tra%C5%BEi")); 
       UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params,HTTP.UTF_8); 
       post.setEntity(ent); 
       HttpResponse responsePOST = client.execute(post); 



       HttpEntity resEntity = responsePOST.getEntity(); 

       if (resEntity != null) {  
        //todo 
        } 
       //checking for cookies, they are OK 
       List<Cookie> cookies = client.getCookieStore().getCookies(); 
       if (cookies.isEmpty()) { 
         Log.d(TAG, "no cookies"); 
       } else { 
        for (int i = 0; i < cookies.size(); i++) { 
          Log.d(TAG, "cookies: " + cookies.get(i).toString()); 
        } 
       } 
       resEntity.consumeContent(); 

       HttpGet get = new HttpGet("http://www.bhtelecom.ba/index.php?id=3226&"); 
       get.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE); 



       HttpResponse responseGET = client.execute(get); 
       HttpEntity entityGET = responseGET.getEntity(); 
       List<Cookie> cookiesGet = client.getCookieStore().getCookies(); 
       if (cookies.isEmpty()) { 
         Log.d(TAG, "no cookies"); 
       } else { 
        for (int i = 0; i < cookiesGet.size(); i++) { 
          Log.d(TAG, "cookies GET: " + cookiesGet.get(i).toString()); 
        } 
       } 

       //a method to check the data, I pass the InputStream to it, and do the operations, I've tried "manually", and passing the InputStream to JSOUP, but without success in either case. 
       samplemethod(entityGET.getContent()); 
       client.getConnectionManager().shutdown(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

그래서, 누군가가 (의 InputStream를) 내 설정에서 오류를 찾거나 나에게 데이터, 그때 입력으로 사용할 수 HTTP 엔터티를 얻을 다음 두 가지 요청을 만들 수있는 방법을 찾을 수 있다면 멋진 JSOUP 파서에게 그것은 놀랄 것입니다. 아니면 페이지가 필요로하는 것에 대해이 모든 것을 얻었고, 다른 매개 변수로 요청을해야 할 필요가 있습니다. Wireshark와 Charles Debugging Proxy를 사용하여 무엇을 만들지 (두 가지를 모두 시도해 보았습니다), 그 세션 ID, fe_typo_user 및 사이트에서 시간을 추적하는 데 사용되는 다른 매개 변수 등을 발견했습니다. 그들도 지나치게 "_ utma" " _utmb"... 등등.

"간단한"POST 전용 메서드를 사용하여 응답하는 데이터가있는 다른 메서드가 있는데 성공적으로 가져 왔지만이 사이트의 특정 문제는 나를 미치게합니다. 귀하의 도움에 미리 감사드립니다.

답변

5

많은 것을 시도하고 들어오고 나가는 패킷을 추적 한 결과 마침내 솔루션을 찾을 수있었습니다.

"버그"또는 HTTPClient의 동작이 문제였습니다. 게시물에 매개 변수를 추가하고 매개 변수가 emty이고 값이 ""있으면 요청과 함께 전송되지 않습니다. 나는 그것을 모르고, 그 매개 변수가 비어 있기 때문에 enything을 변경하지 않을 것이라고 생각했으며, JSOUP를 사용하여 매개 변수를 요청에 전달하지 않았습니다.

params.add(new BasicNameValuePair("_uqid", "")); 
params.add(new BasicNameValuePair("_cdt", "")); 
params.add(new BasicNameValuePair("_hsh", "")); 

그래서는 관심의 장소였다.

이 페이지는 302 응답을 가지고 있으며 JSOUP에는 followRedirects가 기본적으로 "true"로 설정되어 있기 때문에 해당 메소드가 POST이고 "후속 요청"을 GET해야하므로 false로 설정해야했습니다. ,하지만 JSOUP은 여전히 ​​POST라고 가정하고 일을 망칩니다.

그게 전부입니다. 누군가 유용 할 것 같네요.

관련 문제