标签:style blog http color os io strong 文件
操作系统:windowAll
编程工具:visual studio 2013
编程语言:VC++
最近博文更新的较频繁,为了防止账号异常引起csdn博文丢失,所以花了点时间做了个小工具来导出博文,用做备份。本文将从源码分析整个实现过程。先看个截图:
bool CBlogExportDlg::GetUrlStr(CString strUrl, CString& UrlData)
{
CInternetSession session;
CHttpFile *file = NULL;
try{
file = (CHttpFile*)session.OpenURL(strUrl);
}
catch (CInternetException *m_pException){
file = NULL;
m_pException->m_dwError;
m_pException->Delete();
session.Close();
ShowMes("网络连接错误...");
return false;
}
if (!file){
ShowMes(strUrl + "获取失败...");
return false;
}
CString sRecived;
while (file->ReadString(sRecived) != NULL) {
UrlData += sRecived + "\n";
}
session.Close();
file->Close();
delete file;
file = NULL;
return true;
}
int CBlogExportDlg::ConvUtf8ToAnsi(CString& strSource, CString& strChAnsi)
{
if (strSource.GetLength() <= 0)
return 0;
CString strWChUnicode;
strSource.TrimLeft();
strSource.TrimRight();
strChAnsi.Empty();
int iLenByWChNeed = MultiByteToWideChar(CP_UTF8, 0,
strSource.GetBuffer(0),
strSource.GetLength(), //MultiByteToWideChar
NULL, 0);
int iLenByWchDone = MultiByteToWideChar(CP_UTF8, 0,
strSource.GetBuffer(0),
strSource.GetLength(),
(LPWSTR)strWChUnicode.GetBuffer(iLenByWChNeed * 2),
iLenByWChNeed); //MultiByteToWideChar
strWChUnicode.ReleaseBuffer(iLenByWchDone * 2);
int iLenByChNeed = WideCharToMultiByte(CP_ACP, 0,
(LPCWSTR)strWChUnicode.GetBuffer(0),
iLenByWchDone,
NULL, 0,
NULL, NULL);
int iLenByChDone = WideCharToMultiByte(CP_ACP, 0,
(LPCWSTR)strWChUnicode.GetBuffer(0),
iLenByWchDone,
strChAnsi.GetBuffer(iLenByChNeed),
iLenByChNeed,
NULL, NULL);
strChAnsi.ReleaseBuffer(iLenByChDone);
if (iLenByWChNeed != iLenByWchDone || iLenByChNeed != iLenByChDone)
return 1;
return 0;
}
void CBlogExportDlg::ShowMes(CString mes)
{
CTime time;
time = CTime::GetCurrentTime();//Get the current time
CString Times = _T("[") + time.Format("%H:%M:%S") + "]";//Conversion time format
int len = MesEdit.GetWindowTextLength();
MesEdit.SetSel(len, len);
MesEdit.ReplaceSel(Times + mes + _T("\r\n"));
}
void CBlogExportDlg::OnBnClickedButtonOk()
{
GetDlgItemText(IDC_EDIT_ADDRESS, blogAdr);
ShowBlogAdr();
//blogAdr = ("http://blog.csdn.net/yxstars/");
int pos = blogAdr.Find("http://blog.csdn.net/");
if (pos == -1){
ShowMes("csdn blog地址不对...");
}
blogAdrs = blogAdr;
CString urlData;
if (!GetUrlStr(blogAdr, urlData)){
return;
}
CFile fs;
if (!fs.Open(strDirPath + "temp", CFile::modeCreate | CFile::modeWrite)){
return;
}
fs.Write(urlData, urlData.GetLength());
fs.Close();
CString ansiUrlData;
ConvUtf8ToAnsi(urlData, ansiUrlData);
GetBlogInfo(ansiUrlData);
}
<!--显示分页 --> <div id="papelist" class="pagelist"> <span> 113条数据 共6页</span><strong>1</strong> <a href="/yxstars/article/list/2">2</a> <a href="/yxstars/article/list/3">3</a> <a href="/yxstars/article/list/4">4</a> <a href="/yxstars/article/list/5">5</a> <a href="/yxstars/article/list/6">...</a> <a href="/yxstars/article/list/2">下一页</a> <a href="/yxstars/article/list/6">尾页</a> </div>
从上面的代码中可以获取信息如下:
<span> 113条数据 共6页</span>, 共有113篇博文,共有6页。
<a href="/yxstars/article/list/3">,页面链接地址为/yxstars/article/list/
+ 要显示的页数。
C++代码实现如下:
void CBlogExportDlg::GetBlogInfo(CString& urlData)
{
int pos = urlData.Find("<div id=\"papelist\" class=\"pagelist\">");
if (pos == -1){
ShowMes("获取列表数目失败...");
return;
}
urlData = urlData.Mid(pos + 44);
pos = urlData.Find("条数据");
if (pos == -1){
ShowMes("获取列表条数失败...");
return;
}
CString blogListNum = urlData.Left(pos);
pos = urlData.Find("条数据 共");
int poss = urlData.Find("页</span>");
if ((poss == -1) || (pos == -1)){
ShowMes("获取列表页数失败...");
return;
}
CString listPage = urlData.Mid(pos + 10, poss - pos - 10);
blogListPage = StrToInt(listPage);
ShowMes("博文" + blogListNum + "篇");
}
void CBlogExportDlg::OnBnClickedButtonList()
{
clearMes();
CString urlData, ansiUrlData, listPage;
//http://blog.csdn.net/yxstars/article/list/1
FileListMap.clear();
listNum = 1;
for (int i = 1; i < blogListPage + 1; i++){
urlData.Empty();
ansiUrlData.Empty();
listPage.Format("%d", i);
blogAdr = blogAdrs + "/article/list/" + listPage;
ShowBlogAdr();
if (!GetUrlStr(blogAdr, urlData)){
return;
}
ConvUtf8ToAnsi(urlData, ansiUrlData);
GetFileList(ansiUrlData);
}
}
<h1>
<span class="link_title"><a href="/yxstars/article/details/38469431">
<font color="red">[置顶]</font>
金融系列12《双币电子现金方案》
</a></span>
</h1>
<span class="link_title">后面就是博文链接地址。
</a>前面的就是博文标题。
如果有置顶操作,会多出这部分<font color="red">[置顶]</font>
C++获取源码实现如下:
void CBlogExportDlg::GetFileList(CString& urlData)
{
CString strListNum;
int posF = urlData.Find("<span class=\"link_title\">");
while (posF != -1){
urlData = urlData.Mid(posF + 34);
int posE = urlData.Find("\"");
if (posE == -1){
ShowMes("获取列表失败...");
return;
}
CString href = urlData.Left(posE);
posF = urlData.Find("</a>");
if (posF == -1){
ShowMes("获取列表失败...");
return;
}
CString title = urlData.Mid(posE+2, posF-posE-2);
posF = title.ReverseFind('>');
if (posF != -1){
title = title.Mid(posF + 1);
}
title.Trim("\n").Trim();
href = "http://blog.csdn.net" + href;
FileListMap[title] = href;
strListNum.Format("%03d", listNum++);
strListNum = (strListNum + ":" + title + " ").Left(45);
ShowMes(strListNum + href);
posF = urlData.Find("<span class=\"link_title\">");
}
}
void CBlogExportDlg::OnBnClickedButtonExport()
{
clearMes();
unsigned tid;
unsigned long thd = _beginthreadex(NULL, 0, CBlogExportDlg::WriteCycle, this, 0, &tid);
if (thd != NULL)
{
CloseHandle((HANDLE)thd);
}
}
unsigned __stdcall CBlogExportDlg::WriteCycle(void* p)
{
CBlogExportDlg* dlg = (CBlogExportDlg*)p;
CString blogFolderPath = dlg->strDirPath + "Blog\\";
if (!PathIsDirectory(blogFolderPath))
{
if (!CreateDirectory(blogFolderPath, NULL))
{
dlg->ShowMes(blogFolderPath + "创建失败...");
return 1;
}
}
dlg->stopRun = false;
CString urlData, strList;
int iList = 1;
CFile cf;
std::map<CString, CString>::iterator iter;
for (iter = dlg->FileListMap.begin(); iter != dlg->FileListMap.end(); iter++){
//dlg->blogAdr = iter->second;
//dlg->ShowBlogAdr();
urlData.Empty();
if (!dlg->GetUrlStr(iter->second, urlData)){
return 1;
}
strList.Format("%3d", iList++);
dlg->ShowMes("正在导出第" + strList + "篇博文:" + iter->first);
CString blogPath(iter->first);
blogPath.Replace('\\', '_');
blogPath.Replace('/', '_');
blogPath = blogFolderPath + blogPath + ".html";
if (!cf.Open(blogPath, CFile::modeCreate | CFile::modeWrite)){
dlg->ShowMes("创建文件失败" + blogPath);
return 2;
}
cf.Write(urlData, urlData.GetLength());
cf.Close();
if (dlg->stopRun){
return 1;
}
}
return 0;
}
void CBlogExportDlg::OnBnClickedButtonRead()
{
clearMes();
unsigned tid;
unsigned long thd = _beginthreadex(NULL, 0, CBlogExportDlg::ReadCycle, this, 0, &tid);
if (thd != NULL)
{
CloseHandle((HANDLE)thd);
}
}
unsigned __stdcall CBlogExportDlg::ReadCycle(void* p)
{
CBlogExportDlg* dlg = (CBlogExportDlg*)p;
dlg->stopRun = false;
std::map<CString, CString>::iterator iter;
for (iter = dlg->FileListMap.begin(); iter != dlg->FileListMap.end(); iter++){
dlg->blogAdr = iter->second;
dlg->ShowBlogAdr();
dlg->ShowMes("正在遍历博文:" + iter->first);
Sleep(3000);
if (dlg->stopRun){
return 1;
}
}
return 0;
}CSDN免积分下载地址:http://download.csdn.net/detail/yxstars/7786309
文/闫鑫原创
CSDN博客导出(C++实现),布布扣,bubuko.com
标签:style blog http color os io strong 文件
原文地址:http://blog.csdn.net/yxstars/article/details/38686487