如何对网页链接是否有效进行判断?

LoveYouSelf 2012-08-14 09:00:35
请提问者看完一下的内容在进行解答,十分感谢。
最近在忙一个针对指定网址的源代码进行源代码抓取的操作,主要遇到两个问题。1、对指定的网页链接如何判断他是否有效,例如一些链接点开时浏览器会提示“404”的错误。
2、将网页的源文件以txt文本文档的形式保存下来,我想文件名使用网页的网址,但是对于网址中许多的“/”如何处理,听一些人说使用转义字符是可以的。但是主要有两个问题:首先就是我手动的给文件重命名貌似使用转义字符或是“/”都不行。再者链接上的“/”这么多,如果使用写成方法将对每一个“/”进行转义的话,我想会很麻烦。不知道有没有其他简便的方法。
求教MFC高手指导。
...全文
972 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
ok1234567 2012-08-25
  • 打赏
  • 举报
回复
由于%为转意符号,所以你必须先将原文中的这个符号处理为一个不冲突的符号,这里用了不可能在URL中出现的'\a',待其它符号替换完成后(串里面可能已经存在很多%了),再转意这个替换符号

用CString的Replace,效率不算高
如果希望高效的操作,应该是指针扫描处理
ok1234567 2012-08-25
  • 打赏
  • 举报
回复
由于%为转意符号,所以你必须先将原文中的这个符号处理为一个不冲突的符号,这里用了不可能在URL中出现的'\a',待其它符号替换完成后(串里面可能已经存在很多%了),再转意这个替换符号

用CString的Replace,效率不算高
如果希望高效的操作,应该是指针扫描处理
LoveYouSelf 2012-08-24
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 的回复:]
引用 19 楼 的回复:
帮你写两个小函数


C/C++ code



CString URL2FileName(LPCSTR pszURL)
{
CString strFileName(pszURL);
strFileName.Replace(_T("%"),_T("\a"));

strFileName.Replace(_T("<"),_T("%0"));
…………
[/Quote]
我懂你的意思了。但是“\a”这个字符是不能出现在文件名中的,应该会替换失败吧!
LoveYouSelf 2012-08-24
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 的回复:]
帮你写两个小函数


C/C++ code



CString URL2FileName(LPCSTR pszURL)
{
CString strFileName(pszURL);
strFileName.Replace(_T("%"),_T("\a"));

strFileName.Replace(_T("<"),_T("%0"));
……
[/Quote]

好了 谢谢! 你这里将“\a” 换成“%” 有什么意思吗? 好像不需要换么
LoveYouSelf 2012-08-24
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 的回复:]
帮你写两个小函数


C/C++ code



CString URL2FileName(LPCSTR pszURL)
{
CString strFileName(pszURL);
strFileName.Replace(_T("%"),_T("\a"));

strFileName.Replace(_T("<"),_T("%0"));
……
[/Quote]

好了 谢谢! 你这里将“\a” 换成“%” 有什么意思吗? 好像不需要换么
ok1234567 2012-08-24
  • 打赏
  • 举报
回复
帮你写两个小函数



CString URL2FileName(LPCSTR pszURL)
{
CString strFileName(pszURL);
strFileName.Replace(_T("%"),_T("\a"));

strFileName.Replace(_T("<"),_T("%0"));
strFileName.Replace(_T(">"),_T("%1"));
strFileName.Replace(_T("?"),_T("%2"));
strFileName.Replace(_T(":"),_T("%3"));
strFileName.Replace(_T("|"),_T("%4"));
strFileName.Replace(_T("*"),_T("%5"));
strFileName.Replace(_T("/"),_T("%6"));
strFileName.Replace(_T("\""),_T("%7"));
strFileName.Replace(_T("\\"),_T("%8"));

strFileName.Replace(_T("\a"),_T("%9"));

return strFileName;
}

CString FileName2URL(LPCSTR pszFileName)
{
CString strURL(pszFileName);

strURL.Replace(_T("%0"),_T("<"));
strURL.Replace(_T("%1"),_T(">"));
strURL.Replace(_T("%2"),_T("?"));
strURL.Replace(_T("%3"),_T(":"));
strURL.Replace(_T("%4"),_T("|"));
strURL.Replace(_T("%5"),_T("*"));
strURL.Replace(_T("%6"),_T("/"));
strURL.Replace(_T("%7"),_T("\""));
strURL.Replace(_T("%8"),_T("\\"));

strURL.Replace(_T("%9"),_T("%"));

return strURL;
}




调用:
URL.Format("%s","http://www.baidu.com/");// 以百度为测试网址。
FileName1.Format("%s%s",URL2FileName(URL),".TXT");//为文件名后面添加TXT。
...
第二个函数将文件名还原为URL

LoveYouSelf 2012-08-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
1、使用"HEAD"方式发送请求,检查URL是否有效
2、“/”是非法的文件命名符号,可以通过转意替换来解决,因为非法的文件名命名符号还不止“/”这一个,比如“?”什么的,那些符号在URL中都是合法的,所以你可能需要制定一个复杂的转意规则,才能部分搞定,对于那些超长的URL,你没有办法这样搞定的:)
[/Quote]
我试了下转义发现不行 下面是我的代码:

int CheckUrl(CHttpFile &chttpurl);//检查网页链接是否有效。

int _tmain(int argc, _TCHAR* argv[])
{
CString URL,URL1; //URL是表示用于打开的网址 URL1表示用于保存该网址源代码的文件的文件名。
CString strTempData;//网页源文件写入一行数据。
CString FileName,FileName1;//FileName1表示文件名。
HANDLE handle;//创建文件操作所保存的句柄。
CInternetSession session(_T("myagent"));//对指定网址爬取所需声明的对象。

URL.Format("%s","http://www.baidu.com/");// 以百度为测试网址。
URL1.Format("%s","http/:////www.baidu.com//");//测试文件名。

FileName1.Format("%s%s",URL1,".TXT");//为文件名后面添加TXT。

const char * LpFileName = FileName1.GetBuffer(0);//返回指向该文件的指针。

//创建文件操作,以写入的方式
handle = ::CreateFileA(FileName1,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);

if(handle == INVALID_HANDLE_VALUE)
return 0;
else
{
CFile file(handle);

CHttpFile *pF=(CHttpFile *)session.OpenURL(URL);

//测试链接是否有效
int statuesCode = CheckUrl(*pF);

switch(statuesCode)
{
case 1: break;
case 0: return 0;
case 400: return 0;
case 404: return 0;
case 500: return 0;
case 503: return 0;
case 405: return 0;
default: return 0;

}//测试链接是否有效。

DWORD NumberOfBytesWritten;//保存已经写入文件的字节数
while (pF->ReadString(strTempData))
{
file.Write(strTempData,strlen(strTempData)+1);
strTempData = "\r\n" + strTempData;
}

}

if(handle)
{
::CloseHandle(handle);
}

session.Close(); //关闭会话
return 0;
}

int CheckUrl(CHttpFile &chttpurl)
{
DWORD dwStatusCode;
if(chttpurl.QueryInfoStatusCode(dwStatusCode))
{
switch(dwStatusCode)
{
case 200: return 1;
case 400: return 400;
case 404: return 404;
case 405: return 405;
case 500: return 500;
case 503: return 503;
default: return 0;
}
}
else
return 0;
}
zhouzhipen 2012-08-18
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 的回复:]

引用 15 楼 的回复:
有直接的URL编码函数库


能介绍几个包吗?
[/Quote]

WINAPI 中就有现成的,具体叫什么名字忘记了。
LoveYouSelf 2012-08-18
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]
有直接的URL编码函数库
[/Quote]

能介绍几个包吗?
oyljerry 2012-08-18
  • 打赏
  • 举报
回复
有直接的URL编码函数库
LoveYouSelf 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]
由于你只需要处理10个符号
所以,做一个映射表更好,这10个非法字符(包括%),映射为“%x”两个字符就可以了,可以节约一点长度
[/Quote]
映射表! 高见!!受教了!!
ok1234567 2012-08-16
  • 打赏
  • 举报
回复
由于你只需要处理10个符号
所以,做一个映射表更好,这10个非法字符(包括%),映射为“%x”两个字符就可以了,可以节约一点长度
ok1234567 2012-08-16
  • 打赏
  • 举报
回复
“%”转意是一个标准的算法,按字节对于不安全的字节编码为"%XX","XX"就是该字节值的16进制表示,如上ascii码,也就是ascii码值:)
ok1234567 2012-08-16
  • 打赏
  • 举报
回复
用"%"转意很好,理论上可能增加3倍的长度,非法的文件命名符号一共只有9个,加上转意符号"%",你只需要处理10个符号就可以了
LoveYouSelf 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
引用 5 楼 的回复:

引用 3 楼 的回复:
1、使用"HEAD"方式发送请求,检查URL是否有效
2、“/”是非法的文件命名符号,可以通过转意替换来解决,因为非法的文件名命名符号还不止“/”这一个,比如“?”什么的,那些符号在URL中都是合法的,所以你可能需要制定一个复杂的转意规则,才能部分搞定,对于那些超长的URL,你没有办法这样搞定的:)

是的,纠结的文件命名。

可以……
[/Quote]

%2F 好像不错,感觉很多时候都看到%2f,“%2F”有什么特殊意思吗? 想其他的特殊字符“?” “\”“:” “*” “>” "<" "|"这些字符呢? 有已经存在的替代字符?
Eleven 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 3 楼 的回复:
1、使用"HEAD"方式发送请求,检查URL是否有效
2、“/”是非法的文件命名符号,可以通过转意替换来解决,因为非法的文件名命名符号还不止“/”这一个,比如“?”什么的,那些符号在URL中都是合法的,所以你可能需要制定一个复杂的转意规则,才能部分搞定,对于那些超长的URL,你没有办法这样搞定的:)

是的,纠结的文件命名。
[/Quote]
可以用%2F来替换'/'字符
Eleven 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

引用 4 楼 的回复:
逻辑:通过HTTP建立连接,判断返回值
代码:使用到 ::InternetConnect 即可。

C/C++ code


::InternetOpen //初始化网络句柄
::InternetSetStatusCallback //设置下载状态回调函数
::InternetConnect //建立网络连接
HttpOpenRequest……

……
[/Quote]
可以参考wininet的相关内容
可以用CHttpFile* pFile = (CHttpFile*)CInternetSession::OpenURL(...);
Eleven 2012-08-15
  • 打赏
  • 举报
回复
CHttpFile::QueryInfoStatusCode

Status code
Meaning

200
URL located, transmission follows

400
Unintelligible request

404
Requested URL not found

405
Server does not support requested method

500
Unknown server error

503
Server capacity reached

LoveYouSelf 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
逻辑:通过HTTP建立连接,判断返回值
代码:使用到 ::InternetConnect 即可。

C/C++ code


::InternetOpen //初始化网络句柄
::InternetSetStatusCallback //设置下载状态回调函数
::InternetConnect //建立网络连接
HttpOpenRequest……
[/Quote]
问下关于这块的东西,在哪些书上有介绍啊。我之前也在看MFC的一些书,没看到关于这块的东西。
能不能推荐一些书或者教学视频?
LoveYouSelf 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
1、使用"HEAD"方式发送请求,检查URL是否有效
2、“/”是非法的文件命名符号,可以通过转意替换来解决,因为非法的文件名命名符号还不止“/”这一个,比如“?”什么的,那些符号在URL中都是合法的,所以你可能需要制定一个复杂的转意规则,才能部分搞定,对于那些超长的URL,你没有办法这样搞定的:)
[/Quote]
是的,纠结的文件命名。
加载更多回复(4)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧