c527380322 发表于 2010-12-8 11:30:44

一个简单的web爬虫,新手 还没完成呢,不过遇到问题卡住了

请教一个问题。我写了个程序下载了一个网页信息,然后我要读取文件得到这个网页信息里面的所有连接,依次从文件读取1024个字节,然后解析,可是怎么判断出结尾处的连续性啊
就是比如前1024个字节
/><label for="parseurloff">禁用 URL 识别</label></p>
<p><input type="checkbox" name="smileyoff" id="smileyoff" value="1"tabindex="1" /><label for="smileyoff">禁用 <a href="faq.php


后1024个字节是
?action=faq&amp;id=5&amp;messageid=32" target="_blank">Smilies</a></label></p>
<p><input type="checkbox" name="bbcodeoff"
他们在文件里面是连续的,现在分开了, 怎么办啊?

就是还有关于解析网页链接有什么好的办法啊。。。
比如把<script>...</script>脚本里面也解析出来

附上程序附件
程序很小刚刚接触,麻烦哪位大佬给解决一下里面正在写的
        //读取href连接
        void Readhref(char* local_file);
就是这个地方

c527380322 发表于 2010-12-8 12:10:44

:L                  :(

featherwit 发表于 2010-12-8 14:50:31

工欲善其事,必先利其器
我想你做的这个东西首先的目的是爬行,而不是解析。
如果自己用的话推荐你用python之类的脚本语言来干这个事情,要容易的多。

实际上由于页面规范等等问题,解析link本身没就是一个比较复杂的事情,所以最好使用现成的html/xml解析库,比如libxml等等。

回到你这个实际问题上来,比如你不需要解析成DOM树这种麻烦的东西,仅仅是要读一个文本中的链接,那么首要的问题是你要有一个能够唯一确定一个link的模式。比如说按你认为的一个link应该是由那些字串组成的?比如你的例子<a href="faq.php?action=faq&amp;id=5&amp;messageid=32" target="_blank">Smilies</a>,那么这里你打算提取的东西应该是<a\bhref="{.*}>.*</a>对吧,这样就算确立一个非常简单的模式。

虽然不推荐一次读1024这种方法,因为一般的html文件放在一个buffer里面没什么问题。按你的一次nbytes这种读法,就要有一个能够拼接字符串的机制,用一个简单的自动机就在好不过了,比如:遇到'<'的时候开始一个tag,遇到'>'的时候结束一个tag,然后是<string></string>的闭合以及嵌套问题 ,再后是解析出标签之后寻找模式的问题。

最后,简单的方法,strstr(stirng)找到开头,在返回的非空字符串指针上strstr(string)找到结尾就可能满足你的要求,当然,适用范围比较窄就是了。

c527380322 发表于 2010-12-8 16:22:48

恩,我试过了,一次读1024,有很大的纰漏,不能很好的匹配链接,而且还不规则
我也想用你说的那个拼接字符串机制,可是涉及的有点复杂,不知道从哪入手,先匹
配哪种状态,看到了一些web蜘蛛的 parse url ,感觉里面的太过复杂,对我来说
优点难度,举个例子,就像下面的函数, 他的参数,我不知道如何去给,
其中这里的参数char* html 就是我们正在处理的代码,可是我不知道从文件中用什么方法传给他指定的代码,是传多长,还是传一行,还是一边传一边处理
/* BetweenTag
* html text -> tag -> maxout out <-
* html: "<p align=center>bye bye</p> ==> "align=center>ciao ciao"
*/

int BetweenTag(char* html, char* tag,char* out,int endwithstarttag,int maxout)
{
char tmptag1, tmptag2;
int iRelPos=0;
char* tmpPacket;
char* startTag;
char* tmpP;

        sprintf(tmptag1,"<%s",tag);
        sprintf(tmptag2,"</%s>",tag);

        tmpPacket = malloc(MAXPACKETSIZE);

        if(tmpPacket==NULL)
                MemoryCorruptedHandler("BetweenTag");

        atoupper(html,tmpPacket,MAXPACKETSIZE-1);

        do
        {
                if((startTag=my_stristr(tmpPacket+iRelPos,_strupr(tmptag1)))<tmpPacket)
                {
                        FREE(tmpPacket);
                        return -1;
                }

                iRelPos=(startTag-tmpPacket)+strlen(tmptag1);

                //loop untile the tag is followed by a char that's not ' ' or '>' or CRLF or a tab
        /*        tmpPacket!=' ' && tmpPacket!='>' && tmpPacket!='\r' && tmpPacket!='\n' && tmpPacket!='\t')
                        return BetweenTag(startTag+strlen(tmptag1)+1, tag, out,endwithstarttag,maxout);
        */
        }while(tmpPacket!=' ' && tmpPacket!='>' && tmpPacket!='\r' && tmpPacket!='\n' && tmpPacket!='\t');

        if(endwithstarttag==1)                                        //Ex. <A href=sample.c>sample code</A>
                tmpP=my_stristr(tmpPacket+iRelPos,_strupr(tmptag2));
        else                                                        //Ex. <IMG src=sample.jpg>
                tmpP=strchr(tmpPacket+iRelPos,'>');

        if(tmpP>tmpPacket+iRelPos && tmpP-(tmpPacket+iRelPos)<=maxout)
        {
                strncpy(out,html+iRelPos,tmpP-(tmpPacket+iRelPos));
                out=0;
       
                FREE(tmpPacket);

        return iRelPos+1;
        }

        out=0;

        FREE(tmpPacket);

return -1;
}

featherwit 发表于 2010-12-8 16:29:33

你的问题是如何把文件内容都读到内存里是吧
这个比较简单,fseek到end得出文件长度,然后new一个长度的buffer读进去就行了。
ps:有很多能解析html的库,可以找找

c527380322 发表于 2010-12-8 16:35:00

也许我应该用你说的这个libxml 来解析,其实解析url的原理我懂的,可是具体问题的时候就发现要处理好真的很难,尤其是像我这种新手,不过感谢featherwit 老大, 能不能教教小弟怎么弄一个简单的拼接字符串的状态机, 能否写一个实例看看,如何可以解决我的问题,最近被爬虫弄的迷糊了,希望不吝教导。

另外附上我刚刚读取网页文本解析链接的新代码:
int parseurl(FILE *fp)
{
        int c, cpos = 0, pos = 0, i, stage, x;
        char a2a;
        char tmpurl;
        memset(a2a, 0, sizeof(a2a));
        memset(tmpurl, 0, sizeof(tmpurl));
        while(!feof(fp))
        {
                c = fread(a2a,1,1024,fp);
                /*printf("%c",c);*/
                cpos++;
                stage = 0;
                x = 0;
                for(i=0;i<(signed)strlen(a2a);i++)
                {
                        switch(stage)
                        {
                        case 0:
                                if(strncmp(a2a+i,"href",4)==0 || strncmp(a2a+i,"HREF",4)==0 )                //href found
                                {
                                        stage=1;
                                        i+=4;
                                }
                                break;
                        case 1:
                                if(a2a=='\"')                                        //start '"' found
                                        stage=2;
                                break;
                        case 2:
                                if(a2a!='\"')                                        //while end '"' is not found
                                {
                                        tmpurl=a2a;
                                        break;
                                }
                                else                                                                //end '"' found
                                {
                                        stage=3;
                                        tmpurl=0;
                                        pos++;
                                        printf("%s\n",tmpurl);
                                        break;
                                }
                        }
                        if(stage==3)                                                        //exits from for{}
                                break;
                }
        }
        printf("%d\n",cpos);
        printf("%d\n",pos);
       
        return cpos;
}

int main()
{

        FILE *fpt1;

        fpt1 = fopen("index.html","r");
        parseurl(fpt1);
        fclose(fpt1);

        system("pause");
        return 0;
}

c527380322 发表于 2010-12-8 16:48:48

OO原来是这么回事噢、、、呵呵。对了我解析出来的有的网页链接是坏链接
你看图片,我是按照这个格式取的,可是有的链接我试过是无用链接。
最好教教我怎么自己弄一个拼接字符串的机制,谢过

c527380322 发表于 2010-12-8 16:57:48

:L遇到问题了,我原文件496KB ,我解析出来的文件存储在新文件里竟然有2022KB。。。
我估计问题出现在循环那里。。。有些不明白

c527380322 发表于 2010-12-8 18:18:21

结贴。
我找了一个html解析库。。。你说的那些 原理都弄明白了。。现在我在看源代码,
慢慢弄懂。。。谢咯。

freeeyes 发表于 2010-12-8 18:34:34

爬虫,我也写过,一般用libcurl,解析么,一般用自己strstr写,比较老土,可以的话,用一个正则表达式去判定一下吧。
页: [1] 2
查看完整版本: 一个简单的web爬虫,新手 还没完成呢,不过遇到问题卡住了