CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Wycinka śmieci

Wycinka śmieci

dział ogólny

Wycinka śmieci

Nowy postprzez nvdante » czwartek, 28 lutego 2013, 10:14

Cześć :-)
Piszę maleńki programik, który po podaniu konkretnego adresu URL pobiera źródło i wyciąga z niego niektóre dane, tj.: linki do podstron.
Problem jednak pojawia się, gdy kod strony nie jest standardowy typu:
Kod: Zaznacz cały
<a href="http://www.domena.pl/strona.html

a jest na przykład:
Kod: Zaznacz cały
<a href="#" onclick="closeMenuAndRedirect(&quot;/category/5810/


Potrzebuję tak zrobić filtrowanie, żeby zawsze otrzymywać idealny link.
Za radą Cyfrowego Barona zastosowałem takie coś:
KOD cpp:     UKRYJ  
if( Value.SubString(1, 10) != "javascript")
        URL->Add( Value.SubString(1, b) );


więc dla powyższego problemu próbowałem takie coś:
KOD cpp:     UKRYJ  
if( Value.SubString(1, 10) != "javascript" || Value.SubString(1, 11) != "<a href=\"#\"")
        URL->Add( Value.SubString(1, b) );


Niestety nic to nie daje.
Ma ktoś jakiś pomysł na w miarę uniwersalne wyciąganie linków?
Dodam, że w przypadku dobrze działającego programu liczę nawet na kilka milionów linków, więc potrzebuję dość mocno dopracować filtry.
Idealny format dla mnie by był ( może być z www, ale nie musi ):
Kod: Zaznacz cały
http://domena.pl/podstrona.rozszerzenie
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows XPFirefox

Re: Wycinka śmieci

Nowy postprzez Mironas » czwartek, 28 lutego 2013, 11:39

Uniwersalnego rozwiązania raczej nie znajdziesz.

Musisz stosować kilka różnych filtrów na różne przypadki. Pomocne metody dostępne dla String/AnsiString oprócz SubString to Pos i Delete.
Zapoznaj się też z funkcją StringReplace.

[EDIT]

Ja bym wycinał teksty w cudzysłowach a potem sprawdzał czy spełniają teoretyczne warunki - brak spacji, przynajmniej jedna kropka itp.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wycinka śmieci

Nowy postprzez nvdante » czwartek, 28 lutego 2013, 11:56

A mógłbyś nakierować mnie czemu powyższe użycie SubString nie działa prawidłowo dla podanego wyjątku?
Według mnie warunek sformułowałem dość dobrze i dlatego nie wiem co jeszcze w nim zmienić.

Część kodu odpowiedzialna za wyciąganie linków zawiera funkcje, o których mówiłeś, jednak nadal nie osiągam tego co potrzeba:
KOD cpp:     UKRYJ  
std::auto_ptr<TStringList> GetAdressURL(AnsiString sAdres)
{
 Screen->Cursor = crHourGlass;
 String Value = ReadFileURL(sAdres);
 Application->ProcessMessages();

std::auto_ptr< TStringList> URL(new TStringList);
 int a = Value.Pos("<a href=\"");

 do
 {
   Value = Value.Delete(1, a + 8);
   int b = Value.Pos("\">") - 1;

      if( Value.SubString(1, 10) != "javascript" || Value.SubString(1, 11) != "<a href=\"#\"")
        URL->Add( Value.SubString(1, b) );

   a = Value.Pos("<a href=\"");
  }while(a > 0);

 Screen->Cursor = crDefault;

 return URL;
}

A o StringRelace już zaczynam czytać :)

Mironas napisał(a):Ja bym wycinał teksty w cudzysłowach a potem sprawdzał czy spełniają teoretyczne warunki - brak spacji, przynajmniej jedna kropka itp.

Nie mogę tego zrobić, bo pomimo że większość linków HTML pisana jest w "" to jednak bez tego również działa prawidłowo i nie każdy musi je stosować. Niezmiennymi fragmentami są na pewno "<a href=" oraz zakończenie linii ">"
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows XPFirefox

Re: Wycinka śmieci

Nowy postprzez Mironas » czwartek, 28 lutego 2013, 12:15

nvdante napisał(a):A mógłbyś nakierować mnie czemu powyższe użycie SubString nie działa prawidłowo dla podanego wyjątku?


Którego wyjątku? Jeśli chodzi Ci o:
Kod: Zaznacz cały
<a href="#" onclick="closeMenuAndRedirect(&quot;/category/5810/

to tutaj w ogóle nie ma linku który można by pozyskać.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wycinka śmieci

Nowy postprzez nvdante » czwartek, 28 lutego 2013, 12:22

Mironas napisał(a):Którego wyjątku? Jeśli chodzi Ci o:
Kod: Zaznacz cały
<a href="#" onclick="closeMenuAndRedirect(&quot;/category/5810/

to tutaj w ogóle nie ma linku który można by pozyskać.


Oczywiście masz rację, z tym, że mój program wyciągnie te dane, ponieważ spełniają warunek:
KOD cpp:     UKRYJ  
int a = Value.Pos("<a href=\"");


Ale już ich nie odrzuci, gdy nie spełniają go w tym miejscu:
KOD cpp:     UKRYJ  
if( Value.SubString(1, 11) != "<a href=\"#\"")


A powinien moim zdaniem, bo 1 != 2.
Problem w tym, że te dane dalej przepisują się do Memo1 i jeżeli tam wpadną to zapisują się do dalszej obróbki z błędami.
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows XPFirefox

Re: Wycinka śmieci

Nowy postprzez Mironas » czwartek, 28 lutego 2013, 12:58

nvdante napisał(a):Ale już ich nie odrzuci, gdy nie spełniają go w tym miejscu:
KOD cpp:     UKRYJ  
if( Value.SubString(1, 11) != "<a href=\"#\"")


W warunku masz <a href= a wcześniej wyciąłeś go za pomocą Delete.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wycinka śmieci

Nowy postprzez nvdante » czwartek, 28 lutego 2013, 13:08

Mironas napisał(a):W warunku masz <a href= a wcześniej wyciąłeś go za pomocą Delete.

Faktycznie, moje przeoczenie, ale ten warunek i tak nie działa dobrze, bo np.: dla takiego przykładu także nic nie robi:
To jest w logach:
Kod: Zaznacz cały
https://www.domena.pl

Takie warunek:
KOD cpp:     UKRYJ  
if( Value.SubString(1, 5) != "https")

Jak dla mnie nie powinien w ogóle pokazać https na liście, a jednak.

Jak poprawię warunek dla tego co wcześniej, czyli zapiszę go:
KOD cpp:     UKRYJ  
if( Value.SubString(1, 3) != "\"#\"")

czyli powinien wyciąć "#", a jednak w Memo1 nadal jest...
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows XPFirefox

Re: Wycinka śmieci

Nowy postprzez Mironas » czwartek, 28 lutego 2013, 13:20

Uprośćmy to nieco:
KOD cpp:     UKRYJ  
  String Value = "https://www.domena.pl";
  if( Value.SubString(1, 5) != "https")
    ShowMessage("Dodaj do listy");
 

Ten kod nie wywołuje komunikatu. U Ciebie jest inaczej?
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wycinka śmieci

Nowy postprzez nvdante » czwartek, 28 lutego 2013, 13:28

Mironas napisał(a):Uprośćmy to nieco:
Ten kod nie wywołuje komunikatu. U Ciebie jest inaczej?

Oczywiście komunikatu nie ma, bo żeby wystąpił musiałbyś w kodzie dać '==', a nie '!='. Na pewno to wiesz :)
To rozumiem, ale dlaczego skoro odnajduję na liście wpis 'https' i robię wyjątek "jeżeli nie jest http to zapisz, a jak jest to nie zapisuj" to mimo wszystko nadal zapisuje https?
Chyba wiem o co Ci chodzi, ale jeszcze nie do końca wiem, jak to z listy wywalić, nawet zmieniając warunek.
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows XPFirefox

Re: Wycinka śmieci

Nowy postprzez Mironas » czwartek, 28 lutego 2013, 13:48

Daj konkretny kawałek kodu z wpisanymi na sztywno adresami który daje Ci błędny wynik.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wycinka śmieci

Nowy postprzez nvdante » czwartek, 28 lutego 2013, 14:04

KOD cpp:     UKRYJ  
  String Value = "<a href=\"#\" onclick=\"closeMenuAndRedirect(&quot;/category/5810/";
  int a = Value.Pos("<a href=\""); // Wyszukuję ciąg znaków
  Value = Value.Delete(1, a + 8); // wycinam 8 znaków z początku
  if( Value.SubString(1, 3) == "\"#\"") // sprawdzam czy od 1 do 3 znaku jest zapis "#"
    ShowMessage(Value); // jeżeli tak to wyświetlam ciąg


Tak jest moim zdaniem, a jednak ciąg się nie pojawia. Popełniłem gdzieś bląd?
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows XPFirefox

Re: Wycinka śmieci

Nowy postprzez Mironas » czwartek, 28 lutego 2013, 14:22

Po Delete tekst w Value zaczyna się od jest #" (kratka-cudzysłów) a w warunku sprawdzasz czy zaczyna się od "#" (cudzysłów-kratka-cudzysłów)
Chodzi o ten pierwszy cudzysłów.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wycinka śmieci

Nowy postprzez nvdante » czwartek, 28 lutego 2013, 14:53

Mironas napisał(a):Po Delete tekst w Value zaczyna się od jest #" (kratka-cudzysłów) a w warunku sprawdzasz czy zaczyna się od "#" (cudzysłów-kratka-cudzysłów)
Chodzi o ten pierwszy cudzysłów.

Poprawiłem, i teraz jest tak:
KOD cpp:     UKRYJ  
if( Value.SubString(1, 2) != "#\"")

Mam wrażenie, że faktycznie się udało, ale ilość danych jest dość spora, więc muszę dokładniej to zweryfikować.
Póki co bardzo dziękuje Ci za pomoc :)
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows XPFirefox

Re: Wycinka śmieci

Nowy postprzez Cyfrowy Baron » czwartek, 28 lutego 2013, 15:59

Czy zamierzasz pobierać nie tylko linki zewnętrzne, ale również te wewnętrzne czyli należące do serwisu?

Przykład:

customer/pl/profile -> link wewnętrzny
https://www.komputronik.pl/customer/pl/login -> link zewnętrzny
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Wycinka śmieci

Nowy postprzez nvdante » czwartek, 28 lutego 2013, 16:07

Cyfrowy Baron napisał(a):Czy zamierzasz pobierać nie tylko linki zewnętrzne, ale również te wewnętrzne czyli należące do serwisu?

Przykład:

customer/pl/profile -> link wewnętrzny
https://www.komputronik.pl/customer/pl/login -> link zewnętrzny


Interesują mnie wyłącznie zewnętrzne. Chciałem użyć wewnętrznych, bo myślałem, że tak będzie proście :)
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows XPFirefox

Następna strona

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 46 gości