2014-08-27 5 views
2

여기 거래가 있습니다. 내 안드로이드 애플 리케이션에서 Jsoup와 함께 몇 가지 웹 근근이 살아가고 있어요. 이제는 잘 작동하지만 너무 느립니다. 내 코드에서 내가 뭘하는지 :Android HTML Jsoup 구문 분석 속도

  1. Jsoup의 POST 방법으로 페이지에 로그인하십시오.
  2. 쿠키를 받으십시오.
  3. 쿠키를 다시 사용하여 6 페이지 (POST 및 GET)를 거쳐 이들을 스크래핑합니다 (주로 테이블과 행이 많습니다. 나는 많이 ... 너무 많은 foreach 루프를 의미합니다).
  4. SQLiteDatabase에 필요한 모든 데이터 쓰기.

이제 문제는 속도가 빨라진다는 것입니다. 내 말은, 로그인 버튼을 누른 후 응용 프로그램의 로그인 화면에서 사용자는 3G에서 최대 10 초, WiFi에서 ~ 8-10 초 (WiFi 속도에 따라 다름)를 기다려야한다는 것입니다. 그리고 그가 데이터 업데이트를 검사 할 때 SQLiteDatabase 테이블 데이터를 비교하는 것과 동일한 알고리즘을 수행합니다.

그래서이 HTML 구문 분석을 수행하여 안드로이드에서 더 빨리 작업 할 수있는 방법이 있습니까? 추신 나는 슬프게 데이타베이스에 접근이 없다.

는 편집 : 당신은 내가 근근이 살아가고있어 내용에 대해 질문 때문에

는, 여기 당신이 로그인하지 않고 액세스 할 수있는 몇 페이지의 한 예입니다 (정말 다른 사람에 비해 큰 테이블 아니다) https://medeine.vgtu.lt/programos/programa.jsp?sid=F&fak=5&prog=87&rus=U&klb=en.

이제, 코드 ... 난 정말 당신에게 전체 코드를 줄 수는 없지만, 여기에 내가 테이블의 각 셀지고있어 방법의 예입니다 : 여기

document = Jsoup.connect(getContext().getString(R.string.url)) 
        .cookie("JSESSIONID", cookie) 
        .get(); 

      Element table = document.select("table.duomenys").first(); 
      if (table != null) { 
       databaseHandler.openDatabase(); 
       databaseHandler.getDatabase().beginTransaction(); 
       try { 
        for (Element row : table.select("tr.n, tr.l") { 
         Elements columns = row.select("td"); 
         addItem(columns, DatabaseHandler.getTableName()); 
        } 
        databaseHandler.getDatabase().setTransactionSuccessful(); 
       } finally { 
        databaseHandler.getDatabase().endTransaction(); 
       } 
       databaseHandler.closeDatabase(); 
      } 

을 그리고는 addItem를 (이다) 메소드 예 :

private void addItem(Elements columns, String tableName) { 
    databaseHandler.addItem(new Item(
      columns.get(0).text(), 
      columns.get(1).text(), 
      columns.get(3).text(), 
      columns.get(4).text() 
    ), tableName); 
} 

그리고 이것은 단지 한 페이지에 불과합니다. 그들 중 6 명이 있고 그들 중 몇몇은 훨씬 더 큽니다. 물론 이것은 AsyncTaskLoader의 loadInBackground() 메소드 내에서 수행됩니다.

편집 2 :

Connection.Response response = Jsoup.connect("https://medeine.vgtu.lt/studentams/submit.jsp") 
       .data("studKnNr", id, "asmKodas", password) 
       .timeout(3000) 
       .method(Connection.Method.POST) 
       .execute(); 

     String cookie = response.cookie("JSESSIONID"); 

     Document document = Jsoup.connect(modules_url) 
       .cookie(cookie_id, cookie) 
       .get(); 

나는 그것에 대해 생각하면 ... 그렇지 구문 분석이 로그인하고 6 페이지를 통해 리디렉션 그 경우 나는 아무것도 할 수 느리지 만 일 수 있었다 ? 이제 Connection.Response에서 .execute()를 통해 서버에 POST를 보내고 쿠키를받는 데 ~ 2.5 초가 걸린 것으로 나타났습니다.

+0

는'SQLiteDatabase'에 필요한 모든 데이터를 쓰기'나는 database'에 대한 액세스 권한이없는 사용자의 HTTP 요청이 동시에 할 수있는 방법에 선정 된 대답 ???? – greenapps

+1

다운로드 한 데이터를 내 자신의 SQLiteDatabase에 쓰려고합니다. 액세스 권한이 없다는 것은 해당 웹 사이트의 데이터베이스에 액세스 할 수 없다는 것을 의미하므로 웹 사이트를 긁어 야합니다. 매우 명확하기 때문에 대학 정보 시스템 웹 사이트를 고치고 있으며 아직 데이터베이스에 대한 액세스 권한이 없습니다. – env

+0

코드가 느린 경우 여기에 코드를 게시하고 인터넷에 한 페이지를 두어 로그인 할 필요가 없도록 몇 가지 테스트를 수행 할 수 있습니다. – greenapps

답변

5

질문이 모호하고 코드를 제공하지 않았기 때문에 구문 분석하려는 일부 DOM 샘플이 아니기 때문에 일반적인 대답을 제공 할 것입니다.

  • jsoup 쿼리를 최적화하십시오. 많은 데이터 (큰 DOM)가 있기 때문에 최대한 효율적으로 구문 분석하려면 을 시도하십시오.
  • 루프를 최소화하십시오. 데이터 처리 중 불필요한 루프를 수행하지 않으시겠습니까? ?
  • 큰 덩어리의 문자열을 연결 한 다음 String 대신 StringBuilder을 사용해보십시오.
  • 여러 스레드를 사용해보십시오.

업데이트

당신은, 서버의 응답을 수신 메시지의 본문을 조작 한 다음 구문 분석 시간을 최소화 할 수 있도록 Jsoup의 구문 분석을 사용할 수 있습니다

.

try { 
    Connection.Response response = Jsoup.connect("ENTER_URL") 
            .userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0") 
            .referrer("http://www.google.com") 
            .method(Method.GET) //or Method.POST 
            .execute(); 

    String body = response.body(); 

    String table = body; //Manipulate the string, remove all the data you don't want. 

    Document doc = Jsoup.parse(table); 

    System.out.println(doc); 

} catch(Exception e) { 
    e.printStackTrace(); 
} 

업데이트 2

Connection.Response line takes 2.6 seconds이 도움이 될 수 없습니다. 요청을 처리 할 때까지 지연되는 서버이기 때문에이 서버를 사용해야합니다. 결국 쿠키를 한 번만 사용한 다음 다시 사용합니다.

그러나이 부분은 getting the page이지만 일부는 최적화 할 수 있습니다. 게시 한 코드를 사용하면 여전히 http 요청을 다시 작성하는 오버 헤드가 발생하지만 (피할 수는 없으며 쿠키와 함께 서버가 지연됩니다), 대신에 필요한 부분 만 구문 분석합니다. 전체 응답. 이것은 당신에게 약간의 개선을 줄 것이다. 그러나 나는 그것이 많이 될 것이라고 생각하지 않는다. 그럴 가치가없는 것일 수도 있습니다. 그러나 당신은이 부분 만 변경하려고 할 수 있습니다.

Document document = Jsoup.connect(modules_url) 
       .cookie(cookie_id, cookie) 
       .get(); 

실제로 속도가 필요한 경우 병행 성 (여러 스레드)을 사용해야합니다.

  1. 가 (처음에 한 번만) 쿠키를 검색 부모 스레드에서이 같은 뭔가 진짜 차이를 만들 것입니다.
  2. 모든 페이지에 대해 새 스레드를 만들고 쿠키와 URL을 인수로 사용합니다.
  3. 모든 스레드는 할당 된 페이지를 구문 분석합니다.
  4. 모든 데이터는 상위 스레드에서 수집됩니다.

Check this 당신이

+0

DOM 구문 분석의 효율성을 위해 : 테이블 만 구문 분석 할 수있는 방법이 있습니까? Jsoup.connect(). get()은 전체 HTML 페이지를 파싱하고 그냥 긁기 시작하기 때문입니다. 테이블 만 있으면 돼. – env

+0

내 업데이트 확인 – alkis

+0

그래, 로그인 할 때 즉시 다른 페이지로 리디렉션해야하며 GET 메서드를 보내고 있습니다. 어쨌든 .get()이 사용됩니다. 로그인 코드 EDIT 2를 확인하십시오. 그리고이 .body() 코드는 필자의 경우 로그인하지 않은 페이지에서만 작동 할 것이라고 생각한다. – env