Więc napisałem program do skrobania witryny sieci Web w języku C# przy użyciu pakietu Agility HTML. To było dość proste. Nawet biorąc pod uwagę niespójności w formatowaniu na stronie internetowej, zajęło mi to tylko kilka godzin, aby pracować.Jak zeskrobać stronę internetową za pomocą C?
Teraz muszę ponownie wdrożyć ten program w C, aby można go było uruchomić w środowisku Linux. To poważny koszmar.
Jestem w stanie cofnąć stronę, ale jeśli chodzi o śledzenie jej w celu wyciągnięcia części, które mnie interesują - rysuję dużo pustych miejsc. Początkowo nie byłem nastawiony na próbę wdrożenia rozwiązania podobnego do mojej opcji HTML Agility w języku C#, z wyjątkiem używania Tidy i innej biblioteki XML, aby zachować logikę mniej więcej taką samą.
To nie wyszło tak dobrze. Biblioteka XML, do której mam dostęp, wydaje się nie obsługiwać xpath i nie mogę zainstalować takiej, która działa. Tak więc uciekam się do próby znalezienia sposobu na odczytanie strony za pomocą dopasowywania ciągów znaków w celu znalezienia żądanych danych. Nie mogę oprzeć się wrażeniu, że musi istnieć lepszy sposób na zrobienie tego.
Oto co mam:
#define HTML_PAGE "codes.html"
int extract()
{
FILE *html;
int found = 0;
char buffer[1000];
char searchFor[80], *cp;
html = fopen(HTML_PAGE, "r");
if (html)
{
// this is too error prone, if the buffer cuts off half way through a section of the string we are looking for, it will fail!
while(fgets(buffer, 999, html))
{
trim(buffer);
if (!found)
{
sprintf(searchFor, "<strong>");
cp = (char *)strstr(buffer, searchFor);
if(!cp)continue;
if (strncmp(cp + strlen(searchFor), "CO1", 3) == 0 || strncmp(cp + strlen(searchFor), "CO2", 3) == 0)
{
got_code(cp + strlen(searchFor));
}
}
}
}
fclose(html);
return 0;
}
got_code(html)
char *html;
{
char code[8];
char *endTag;
struct _code_st *currCode;
int i;
endTag = (char *)strstr(html, "</strong>");
if(!endTag)return;
sprintf(code, "%.7s", html);
for(i=0 ; i<Data.Codes ; i++)
if(strcasecmp(Data.Code[i].Code, code)==0)
return;
ADD_TO_LIST(currCode, _code_st, Data.Code, Data.Codes);
currCode->Code = (char *)strdup(code);
printf("Code: %s\n", code);
}
Powyższe nie działać prawidłowo. Otrzymuję wiele kodów, które mnie interesują, ale jak wspomnę powyżej, jeśli bufor odcina się w niewłaściwych miejscach, tęsknię za niektórymi.
Próbowałem po prostu przeczytać cały fragment html, który mnie interesuje, ale nie byłem w stanie wymyślić, jak przejść przez to - nie mogłem uzyskać żadnych wyświetlanych kodów.
Czy ktoś wie, jak rozwiązać ten problem?
EDIT: Myślałem o tym więcej. Czy istnieje sposób, w jaki mogę patrzeć do przodu w pliku i szukać końca każdego "bloku" tekstu, który piszę i ustawić rozmiar bufora przed odczytaniem? Czy potrzebowałbym innego wskaźnika pliku do tego samego pliku? To (miejmy nadzieję) zapobiegnie problemowi odcięcia bufora w niewygodnych miejscach.
Może uruchomić go z Mono? –
C jest świetny, ale nie dla tego rodzaju zadania. Zamiast tego użyj czegoś innego, jak Perl lub Python. Do diabła, nawet PHP by to zrobił. –
Tak, muszę się zgodzić. To po prostu jest niewłaściwe narzędzie do pracy. –