2012-04-24 10 views
7

Więc buduję aplikację, która wyświetla obraz z witryny, do której się udam, w bardziej przyjaznym dla użytkownika interfejsie. W tej chwili jest z tym wiele problemów, ale największym teraz jest pobieranie obrazów, aby je wyświetlić.Czy jest coś szybszego niż Jsoup do skrobania HTML?

Tak jak teraz, obrazy są wyświetlane w GridView wielkości 12, odzwierciedlając liczbę obrazów na każdej stronie tablicy. Używam Jsoup do zeskanowania strony dla adresów URL obrazków miniaturek wyświetlanych w GridView, a także do uzyskania adresów URL dla obrazów w pełnym rozmiarze wyświetlanych, gdy użytkownik kliknie miniaturę.

Problem polega na tym, że w przypadku Jsoup trwa średnio od 8 do 12 sekund, aby strona HTML została skradziona. Uważam, że jest to niedopuszczalne i zastanawiałem się, czy istnieje jakikolwiek sposób, aby uczynić to szybszym, lub jeśli to będzie nieodłączne wąskie gardło, na które nie mogę nic poradzić.

Oto kod używam aby pobrać stronę do skrobania:

try { 
    Document doc = Jsoup.connect(url).get(); 
    Elements links = doc.select("img[src*=/alt2/]"); 
    for (Element link : links) { 
     thumbURL = link.attr("src"); 
     linkURL = thumbURL.replace("/alt2/", "/").replace("s.jpg", ".jpg"); 
     imgSrc.add(new Pair<String, String>(thumbURL, linkURL)); 
    } 
} 
catch { 
    e.printStackTrace(); 
} 

Odpowiedz

6

użyłem Jsoup za pomocą skrobaczki TLFN i nie miałem żadnych problemów z prędkością. Powinieneś zawęzić wąskie gardło. Zakładam, że twoje skrobanie powoduje problem z prędkością. Spróbuj osobno śledzić swój selektor i ruch w sieci i zobacz, co jest winne. Jeśli Twój selekcjoner jest winien, rozważ znalezienie innego podejścia do sprawdzania i porównywania wyników.

Aby uzyskać szybszy, ogólny pomysł, testowanie zawsze możesz uruchomić Jsoup z normalnego projektu Java i gdy masz wrażenie, że go poprawiłeś, wyrzuć go z powrotem na urządzenie i sprawdź, czy ma podobne ulepszenia wydajności.

EDIT

Nie, że jest to problem, ale należy pamiętać, że za pomocą iteratorów „może” spowodować sporo zbierania śmieci do wyzwolenia. Zazwyczaj nie stanowi to problemu, chociaż jeśli użyjesz ich w wielu miejscach z wieloma powtórzeniami, mogą spowodować, że niektóre urządzenia odniosą zauważalny efekt wydajności.

nie wielki

for (Element link : links) 

lepiej

int i; 
Element tempLink; 
for (i=0;i<links.size();i++) { 
    tempLink = links.get(i); 
} 

EDIT 2

Jeśli adresy URL obrazu są zaczynając/ALT2/może być w stanie wykorzystać^= zamiast * = których może potencjalnie przyspieszyć wyszukiwanie. Dodatkowo, w zależności od ilości HTML, możesz tracić dużo czasu na szukanie w złym miejscu tych obrazów. Sprawdź, czy te obrazy są zapakowane w rozpoznawalny pojemnik, na przykład coś takiego, jak np. <div class="posts">. Jeśli możesz zawęzić ilość HTML do przesiewania, możesz poprawić wydajność.

+0

Dobrze rzeczą jest to, że planowane do get() połączenia, które jest gdzie dostałem 8-12 sekundowe opóźnienie. Ale przyjrzę się selektorowi. – seraphzero

+0

Szybciej można wybrać wszystkie obrazy, a następnie przeglądać je ręcznie, wybierając odpowiednie obrazy. –

+0

Uruchamiając więcej testów sprawdzających czas, jestem pewien, że to wywołanie get() trwa cały czas. W przypadku zwykłego projektu Java wywołanie metody get() trwa około 1-2 sekund, a wywołanie funkcji select() trwa około 0,05 sekundy. Uruchamianie tego samego kodu na emulatorze systemu Android, zajmuje wyżej wymienione 8-12 sekund dla get() i około 0,7 sekundy dla select(). – seraphzero

0

można zidentyfikować lepsze materiały, które chcesz dostać, ponieważ jest tylko jeden powód, który może spowolnić wykonywanie kodu

select("img[src*=/alt2/]") 

Czy istnieje jakiś wspólny „klasa” z obrazami, które chcesz dostać ?

+0

Niestety, nie. To tylko źródłowe adresy URL obrazów. – seraphzero

+0

Czy umieścisz html? – ChristopheCVB

+0

Obraz miniaturowy wyglądałby następująco: 'blog, Takahashi Ai,' – seraphzero

2

wpadłem na tym samym numerze:

logcat na moim HTC One S jasno pokazuje, że połączenie-reakcja trwa tylko pierwsze 4 sekundy (3 Połączenia równoległe). Parsowanie trwa prawie 30-40 sekund, co jest ogromnym czas .. zauważyć, że HTC One S ma bardzo szybki DualCore @ 1,4ghz .. Problemem jest wyraźnie nie jest podłączony do emulatora

02-27 14:11:55.278: DEBUG/MyActivity(10735): =c> 
02-27 14:11:55.278: DEBUG/MyActivity(10735): =c> 
02-27 14:11:55.278: DEBUG/MyActivity(10735): =c> 
02-27 14:11:59.002: DEBUG/MyActivity(10735): <r= 
02-27 14:11:59.012: DEBUG/MyActivity(10735): <r= 
02-27 14:11:59.422: DEBUG/MyActivity(10735): <r= 
02-27 14:12:33.949: DEBUG/MyActivity(10735): <d= 
02-27 14:12:37.463: DEBUG/MyActivity(10735): <d= 
02-27 14:12:38.294: DEBUG/MyActivity(10735): <d= 

to jest mój kod:

// Jsoup-Connection 
Connection c = Jsoup.connect(urls[0]); 
// Request timeout in ms 
c.timeout(5000); 
Connection.Response r = c.execute(); 
Log.d("MyActivity","<r= doInBackground ("+urls[0]+")"); 

// Get the actual Document 
Document doc = r.parse(); 
Log.d("MyActivity","<d= doInBackground ("+urls[0]+")"); 

Aktualizacja:

02-27 20:38:25.649: INFO/MyActivity(18253): !=c> 
02-27 20:38:27.511: INFO/MyActivity(18253): !<r= 
02-27 20:38:28.873: INFO/MyActivity(18253): !#d= 

Otrzymałem kilka nowych wyników. Poprzednie wersje były z mojej aplikacji na Androida jako DEBUGGING .. teraz opublikowane wyniki pochodzą z uruchamiania bez trybu debugowania (z IntelliJ IDE) .. jakiekolwiek wyjaśnienie, dlaczego debugowanie sprawia, że ​​Jsoup jest tak powolny?

Po uruchomieniu debuggina na moim komputerze i5-Desktop nie otrzymałem kary za wydajność.

Sprawca dlaczego mój kod jest tak powolny na Androida jest zdecydowanie DEBUG-Mode Tryb .. spowalnia jsoup przez współczynnik 100.

+0

Myślę, że jest to coś związanego z ogromną liczbą połączeń bardzo małych metod. Przypuszczam, że Java VM/debugger ustawił wewnętrzne przechwyty dla każdego wejścia/wyjścia metody lub czegoś podobnego. W każdym razie Jsoup jest niesamowitą i elegancką biblioteką, ale ten problem istnieje tylko w trybie debugowania. Używam Eclipse i odłączam debugger, gdy jestem zmęczony czekaniem. – WindRider