【问题标题】:C strip html between <...>C 在 <...> 之间剥离 html
【发布时间】:2012-02-25 12:57:12
【问题描述】:

如何使用 C 从 HTML 文档中剥离 HTML 并包含在 HTML 文档中的 <...> 标记之间?我当前的程序使用 curl 获取网页的内容并将其放入文本文件中,然后从文本文件中读取并删除 ,但我不确定如何删除这些标签之间的所有内容。

#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#define WEBPAGE_URL "http://homepages.paradise.net.nz/adrianfu/index.html"
#define DESTINATION_FILE "/home/user/data.txt"

size_t write_data( void *ptr, size_t size, size_t nmeb, void *stream)
{
 return fwrite(ptr,size,nmeb,stream);
}

int main()
{
 int in_tag = 0;
 char * buffer;
 char c;
 long lSize;
 size_t result;

 FILE * file = fopen(DESTINATION_FILE,"w+");
 if (file==NULL) {
    fputs ("File error",stderr); 
    exit (1);
    }

 CURL *handle = curl_easy_init();
 curl_easy_setopt(handle,CURLOPT_URL,WEBPAGE_URL); /*Using the http protocol*/
 curl_easy_setopt(handle,CURLOPT_WRITEFUNCTION, write_data);
 curl_easy_setopt(handle,CURLOPT_WRITEDATA, file);
 curl_easy_perform(handle);
 curl_easy_cleanup(handle);

  int i, nRead, fd;
    int source;
    char buf[1024];


    if((fd = open("data.txt", O_RDONLY)) == -1)
    {
        printf("Cannot open the file");
    }
    else
    {
        nRead = read(fd, buf, 1024);
        printf("Original String ");
        for(i=0; i<nRead; i++)
        {
                printf("%c", buf[i]);
        }

        printf("\nReplaced String ");

        for(i=0; i<nRead; i++)
        {
            if(buf[i]=='<' || buf[i]=='>'){
            buf[i]=' ';

            }
            printf("%c", buf[i]);
        }
    }
    close(source);

 return 0;
 }

【问题讨论】:

  • 你可以做一个最小的状态机。在“”上减少一个计数器。仅当计数器为零时才输出。 (当心栅栏错误!)

标签: c linux curl


【解决方案1】:

只放置删除''标签之间内容的代码(假设您处理正确的html,这意味着您没有一个标签嵌套在另一个标签的声明中,例如&lt;html &lt; body&gt; &gt; )。我只是更改您的一小部分代码。我还将从buf 变量中删除标签,而不是用间隔替换不需要的字符,因为我认为这对您更有用(如果我错了,请纠正我)。

int idx = 0;
int opened = 0; // false
for(i=0; i<nRead; i++)
{
    if(buf[i]=='<') {
        opened = 1; // true
    } else if (buf[i] == '>') {
        opened = 0; // false
    } else if (!opened) {
        buf[idx++] = buf[i];
    }
}
buf[idx] = '\0';
printf("%s\n", buf);

【讨论】:

  • 这正是我想要的,它摆脱了 HTML。然而,它似乎只打印标签之间的第一个文本,例如它只会打印 ... 标签之间的内容。感谢您的帮助。
  • &lt;a title="&lt;bla&gt;" href="https://google.com"&gt;foo&lt;/a&gt; 怎么样?这是有效的 HTML。我认为你需要一个“开放”尖括号的计数器。
  • 标签之间的第一个文本是什么意思:如果多个标签我只打印第一个标签的内容吗?还是我以某种方式截断单个标签的内容?我似乎看不出有什么理由会发生这样的事情。
  • @Gandaro 对我来说这个 html 无效。该字符应使用&amp;lt;&amp;gt; 进行转义。
  • 啊,没关系,我的缓冲区不够大,所以从网页末尾提前剪掉了。
【解决方案2】:

这也将处理脚本和样式标签

int stripHTMLTags(char *sToClean,size_t size)
    {
        int i=0,j=0,k=0;
        int flag = 0; // 0: searching for < or & (& as in &bspn; etc), 1: searching for >, 2: searching for ; after &, 3: searching for </script>,</style>, -->
        char tempbuf[1024*1024] = "";
        char searchbuf[1024] =  "";

        while(i<size)
        {
            if(flag == 0)
            {
                if(sToClean[i] == '<')
                {
                    flag = 1;

                    tempbuf[0] = '\0';
                    k=0; // track for <script>,<style>, <!-- --> etc
                }
                else if(sToClean[i] == '&')
                {
                    flag = 2;
                }
                else
                {
                    sToClean[j] = sToClean[i];
                    j++;
                }
            }
            else if(flag == 1)
            {
                tempbuf[k] = sToClean[i];
                k++;
                tempbuf[k] = '\0';

                //printf("DEBUG: %s\n",tempbuf);

                if((0 == strcmp(tempbuf,"script")))
                {
                    flag = 3;

                    strcpy(searchbuf,"</script>");
                    //printf("DEBUG: Detected %s\n",tempbuf);

                    tempbuf[0] = '\0';
                    k = 0;
                }
                else if((0 == strcmp(tempbuf,"style")))
                {
                    flag = 3;

                    strcpy(searchbuf,"</style>");
                    //printf("DEBUG: Detected %s\n",tempbuf);

                    tempbuf[0] = '\0';
                    k = 0;
                }
                else if((0 == strcmp(tempbuf,"!--")))
                {
                    flag = 3;

                    strcpy(searchbuf,"-->");
                    //printf("DEBUG: Detected %s\n",tempbuf);

                    tempbuf[0] = '\0';
                    k = 0;
                }

                if(sToClean[i] == '>')
                {
                    sToClean[j] = ' ';
                    j++;
                    flag = 0;
                }

            }
            else if(flag == 2)
            {
                if(sToClean[i] == ';')
                {
                    sToClean[j] = ' ';
                    j++;
                    flag = 0;
                }
            }
            else if(flag == 3)
            {
                tempbuf[k] = sToClean[i];
                k++;
                tempbuf[k] = '\0';

                //printf("DEBUG: %s\n",tempbuf);
                //printf("DEBUG: Searching for %s\n",searchbuf);

                if(0 == strcmp(&tempbuf[0] + k - strlen(searchbuf),searchbuf))
                {
                    flag = 0;
                    //printf("DEBUG: Detected END OF %s\n",searchbuf);

                    searchbuf[0] = '\0';
                    tempbuf[0] = '\0';
                    k = 0;
                }
            }

            i++;
        }

        sToClean[j] = '\0';

        return j;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 2012-06-13
    • 2012-08-23
    • 2012-08-08
    • 1970-01-01
    相关资源
    最近更新 更多