Извлечь все URL-адреса из HTML в C - PullRequest
0 голосов
/ 10 апреля 2020

Как я могу извлечь все URL в HTML, используя C стандартную библиотеку?

Я пытаюсь справиться с этим с помощью sscanf (), но valgrind выдает ошибку (а я даже нет уверен, что после успешной отладки код может удовлетворить мои требования, поэтому, если есть другие способы, сообщите мне). Я сохранил содержимое html в строковом указателе, есть несколько URL (включая абсолютный URL и относительный URL, например http://www.google.com, // www.google.com, /a.html, a. html и т. Д.) В нем. Я хочу извлечь их по одному и сохранить их отдельно в другом строковом указателе.

Я также думаю об использовании strstr (), но тогда я понятия не имею, как получить второй URL.

Мой код (здесь я пропускаю утверждение), используя sscanf:

int
main(int argc, char* argv[]) {
    char *remain_html = (char *)malloc(sizeof(char) * 1001);
    char *url = (char *)malloc(sizeof(char) * 101);

    char *html = "<A HREF=\"http://www.google.com\">navigation</a>"
                 "<a href=\"/a.html\">search</a>";
    printf("html: %s\n\n", html);

    sscanf(html, "<a href=\"%s", remain_html);
    printf("after first href tag: %s\n\n", remain_html);
    sscanf(remain_html, "%s\">", url);
    printf("first web: %s\n\n", url);
    sscanf(remain_html, "<a href=\"%s", remain_html);
    printf("after second href tag: %s\n\n", remain_html);

    free(remain_html);
    free(url);
}

Valgrind дает: Условный переход или перемещение зависит от неинициализированных значений.

Если кто-нибудь может помочь Большое спасибо!

1 Ответ

0 голосов
/ 10 апреля 2020

valgrind предупреждает вас о неинициализированных данных (используемых в тесте), учитывая, что ваша программа делает только sscanf и printf , что означает, что у вас, вероятно, есть проблема с вашим scanf

, если я немного изменю вашу программу для вывода результата sscanf , поэтому покажите много элементов, которые он получит:

int
main(int argc, char* argv[]) {
    char *remain_html = (char *)malloc(sizeof(char) * 1001);
    char *url = (char *)malloc(sizeof(char) * 101);

    char *html = "<A class=\"mw-jump-link\" HREF=\"#mw-head\">Jump to navigation</a>"
                     "<a class=\"mw-jump-link\" href=\"#p-search\">Jump to search</a>";
    printf("html: %s\n\n", html);

    printf("%d\n", sscanf(html, "<a href=\"%s", remain_html));
    printf("after first href tag: %s\n\n", remain_html);
    printf("%d\n", sscanf(remain_html, "%s\">", url));
    printf("first web: %s\n\n", url);
    printf("%d\n", sscanf(remain_html, "<a href=\"%s", remain_html));
    printf("after second href tag: %s\n\n", remain_html);

    free(remain_html);
    free(url);
}

выполнение:

pi@raspberrypi:/tmp $ ./a.out
html: <A class="mw-jump-link" HREF="#mw-head">Jump to navigation</a><a class="mw-jump-link" href="#p-search">Jump to search</a>

0
after first href tag: 

-1
first web: 

-1
after second href tag: 

pi@raspberrypi:/tmp $ 

, поэтому первый scanf ничего не получил (0 элемент), это означает, что он не устанавливает остаются_ html и этот не инициализируется, когда используется следующим sscanf с неопределенным поведением

Из-за формата

"<a href=\"%s"

первого sscanf ожидает строку, начинающуюся с

 <a href="

, но html начинается с

<A class=

, что отличается , поэтому он останавливается на втором символе и не устанавливает остаются_ html


Использовать sscanf не правильно, поиск префикса may be in uppercase for instance using strcasestr, then extract the URL up to the closing "

Example :

#include 
#include 
#include 

/* in case you do not have that function */
char * strcasestr(char * haystack, char *needle)
{
  while (*haystack) {
    char * ha = haystack;
    char * ne = needle;

    while (tolower(*ha) == tolower(*ne)) {
      if (!*++ne)
        return haystack;
      ha += 1;
    }
    haystack += 1;
  }

  return NULL;
}

int main(int argc, char* argv[]) {
  char *html = " navigation"" search"; char * begin = html; символ * конец; printf ("html:% s \ n", html); while ((begin = strcasestr (begin, "
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...