C++获取浏览器浏览历史(兼容谷歌、IE、火狐)

参考网上代码,将获取浏览器浏览历史封装成一个类。

头文件BrowsHistory.h代码如下:

// FileName: BrowsHistory.h
// ------------------------------------------------------------------------------------------------------------------------
// Remarks:
//   BrowsHistory对象应该设置成全局,或者静态;防止还没有获取完网址,对象就析构了;
// ------------------------------------------------------------------------------------------------------------------------

#pragma once
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include "afxwin.h"
struct BrowsData
{
public:
	// 网址
	CString strURL;

	// 对应网址访问次数
	unsigned int nCount;

	// 重载<操作符
	bool operator < (const BrowsData &m)const
	{
		return nCount > m.nCount;
	}
};
class BrowsHistory
{
private:

	// 保存获得的网址和访问次数
	std::vector<BrowsData> m_BrowsHistroy;
private:
	// IE网址过滤,如只取网址com前边的
	void urlFiltrateIE (LPWSTR lpszSourceUrlName);

	// Chrome网址过滤,如只取网址com前边的
	void urlFiltrateChrome (CString strUrlName);
	// Firefox网址过滤,如只去网址com前边的
	void urlFiltrateFirefox (CString strUrlName, int nCount);
	// 查询进程是否已存在, 返回true表示存在;自动结束其进程
	bool IsRunning(CString exe);
	// 编码转换
	void ConvertUtf8ToGBK(CStringA &strUtf8);
	// 获取浏览器历史记录
	void InitHistroy (void);
	// 多线程函数
	static void ThreadPro (LPVOID * ptr);
	// 对获得的网址进行排序
	void Sort (void);
public:
	BrowsHistory();
	~BrowsHistory();
	// 获取网址的进程,是否执行完;执行完时为true;
	bool m_bStatus;
	// 初始化
	void Init (void);
	// 获取浏览器历史记录
	std::vector<BrowsData> GetBrowsHistory(void) const;
};
类实现文件BrowsHistory.cpp

// // FileName: BrowsHistory.cpp
#include "stdafx.h"                    // 如果编译出错请删除此行
#include "BrowseHistory.h"
#include <wininet.h>
#include "Common\\CppSQLite3.h"
#include <shlobj.h> 
#include "Shlwapi.h"
#include "tlhelp32.h"
#include <atlconv.h>

#pragma  comment(lib,"Shlwapi.lib")
#pragma comment(lib,"Common\\sqlite3.lib")

BrowsHistory::BrowsHistory()
{
	m_bStatus = false;
}
BrowsHistory::~BrowsHistory()
{
}
void BrowsHistory::urlFiltrateIE (LPWSTR lpszSourceUrlName)
{
	BrowsData browsDate;
	browsDate.nCount = 0;
	CString strTemp(lpszSourceUrlName);

	std::vector<BrowsData>::iterator iter;
	// 排除非必要的网址
	if (strTemp.Find(_T("@http://")) != -1)
	{
		strTemp.Delete(0, strTemp.Find(_T("@http://"))+8);
		// 排除非必要网址
		if (strTemp.Find(_T(":")) != -1)
		{
			return;
		}
		int nIndex = strTemp.Find(_T("/"));
		if (nIndex != -1)
		{
			for (iter=m_BrowsHistroy.begin(); iter != m_BrowsHistroy.end(); iter++)
			{
				if (iter->strURL == strTemp.Left(nIndex))
				{
					iter->nCount += 1;
					return;
				}
			}
			browsDate.strURL = strTemp.Left(nIndex);
			browsDate.nCount = 1;
			m_BrowsHistroy.push_back(browsDate);
		}
		else
		{
			for (iter=m_BrowsHistroy.begin(); iter != m_BrowsHistroy.end(); iter++)
			{
				if (iter->strURL == strTemp)
				{
					iter->nCount += 1;
					return;
				}
			}
			browsDate.strURL = strTemp;
			browsDate.nCount = 1;
			m_BrowsHistroy.push_back(browsDate);
		}
	}
}
void BrowsHistory::urlFiltrateChrome (CString strUrlName)
{
	// 删除开始的"https://"

	if (strUrlName.Find(_T("https://")) != -1)
	{
		strUrlName.Delete(0, 8);
	}
	else if(strUrlName.Find(_T("http://")) != -1)
	{
		strUrlName.Delete(0, 7);
	}
	int nIndex = strUrlName.Find(_T("/"));
	BrowsData browsDate;
	browsDate.nCount = 0;
	std::vector<BrowsData>::iterator iter;
	if (nIndex != -1)
	{
		for (iter=m_BrowsHistroy.begin(); iter != m_BrowsHistroy.end(); iter++)
		{
			if (iter->strURL == strUrlName.Left(nIndex))
			{
				iter->nCount += 1;
				return;
			}
		}
		browsDate.strURL = strUrlName.Left(nIndex);
		browsDate.nCount = 1;
		m_BrowsHistroy.push_back(browsDate);
	}
	else
	{
		for (iter=m_BrowsHistroy.begin(); iter != m_BrowsHistroy.end(); iter++)
		{
			if (iter->strURL == strUrlName)
			{
				iter->nCount += 1;
				return;
			}
		}
		browsDate.strURL = strUrlName;
		browsDate.nCount = 1;
		m_BrowsHistroy.push_back(browsDate);
	}
}
void BrowsHistory::urlFiltrateFirefox (CString strUrlName, int nCount)
{
	BrowsData browsDate;
	browsDate.nCount = 0;
	int nIndex = strUrlName.Find(_T("/"));
	if (nIndex != -1)
	{
		strUrlName = strUrlName.Left(nIndex);
	}
	std::vector<BrowsData>::iterator iter;
	for (iter=m_BrowsHistroy.begin(); iter != m_BrowsHistroy.end(); iter++)
	{
		if (iter->strURL == strUrlName)
		{
			iter->nCount += nCount;
			return;
		}
	}
	browsDate.strURL = strUrlName;
	browsDate.nCount += nCount;
	m_BrowsHistroy.push_back(browsDate);
}
bool BrowsHistory::IsRunning(CString exe)
{
	PROCESSENTRY32 pe32;
	HANDLE hprocess;
	hprocess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	pe32.dwSize = sizeof(PROCESSENTRY32);
	if(Process32First(hprocess,&pe32))
	{
		do
		{
			HANDLE h_id;
			h_id = OpenProcess(PROCESS_TERMINATE,false,pe32.th32ProcessID);
			CString exefile;
			exefile=pe32.szExeFile;
			exefile.MakeLower();
			exe.MakeLower();
			if(exefile==exe)
			{
				if (TerminateProcess(h_id, 0) !=0)
				{
					return FALSE;
				}
				else
				{
					return TRUE;
				}
			}
		}
		while(Process32Next(hprocess,&pe32));
	}
	return FALSE;
}
void BrowsHistory::ConvertUtf8ToGBK(CStringA &strUtf8)
{
	int len=MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)strUtf8, -1, NULL,0);
	unsigned short * wszGBK = new unsigned short[len+1];
	memset(wszGBK, 0, len * 2 + 2);
	MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)strUtf8, -1,(LPWSTR) wszGBK, len);
	len = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)wszGBK, -1, NULL, 0, NULL, NULL);
	char *szGBK=new char[len + 1];
	memset(szGBK, 0, len + 1);
	WideCharToMultiByte (CP_ACP, 0, (LPWSTR)wszGBK, -1, szGBK, len, NULL,NULL);
	strUtf8 = szGBK;
	delete[] szGBK;
	delete[] wszGBK;
}
void BrowsHistory::Init (void)
{
	// 创建一个线程
	CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadPro, this, 0, NULL);
}
void BrowsHistory::InitHistroy (void)
{
	// 用来支持多次调用
	m_bStatus = false;
	m_BrowsHistroy.clear();
	// 获取IE的历史记录
	HANDLE hCacheEnumHandle = NULL;
	LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = NULL;
	DWORD dwSize = 4096;
	BrowsData browsDate;
	browsDate.nCount = 0;
	lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize];
	lpCacheEntry->dwStructSize = dwSize;
	hCacheEnumHandle = FindFirstUrlCacheEntry(_T("visited:"), lpCacheEntry, &dwSize);
	if(hCacheEnumHandle != NULL)
	{
		urlFiltrateIE(lpCacheEntry->lpszSourceUrlName);
	}
	else
	{
		switch(GetLastError())
		{
		case ERROR_INSUFFICIENT_BUFFER:
			lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize];
			lpCacheEntry->dwStructSize = dwSize;
			hCacheEnumHandle = FindFirstUrlCacheEntry(_T("visited:"), lpCacheEntry, 
				&dwSize);
			if (hCacheEnumHandle != NULL) 
			{
				urlFiltrateIE(lpCacheEntry->lpszSourceUrlName);
				break;        
			}
			else
			{
				// 查找失败
				return; 
			}
		default:
			{
				FindCloseUrlCache(hCacheEnumHandle);
			}
		}
	}
	bool bSign = true;
	do 
	{
		if (FindNextUrlCacheEntry(hCacheEnumHandle, lpCacheEntry, &dwSize))
		{
			urlFiltrateIE(lpCacheEntry->lpszSourceUrlName);
		}
		else
		{
			switch(GetLastError())
			{
			case ERROR_INSUFFICIENT_BUFFER:
				lpCacheEntry = 
					(LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize];
				memset(lpCacheEntry,0,dwSize);
				lpCacheEntry->dwStructSize = dwSize;

				if (FindNextUrlCacheEntry(hCacheEnumHandle, lpCacheEntry, 
					&dwSize)) 
				{
					urlFiltrateIE(lpCacheEntry->lpszSourceUrlName);
					break;
				}
				else
				{
					FindCloseUrlCache(hCacheEnumHandle);
					bSign = false;
					break; 
				}
				break;
			case ERROR_NO_MORE_ITEMS:
				FindCloseUrlCache(hCacheEnumHandle);
				bSign = false;
				break;
			default:
				FindCloseUrlCache(hCacheEnumHandle);
				bSign = false;
				break;
			}
		}
	} while (bSign);
	// 获取谷歌浏览器的历史记录
	char path[MAX_PATH];
	::SHGetSpecialFolderPathA(NULL,path,CSIDL_LOCAL_APPDATA,FALSE);
	strcat_s(path,"\\google\\chrome\\User Data\\default\\History");
	if (PathFileExistsA(path))
	{
		// 谷歌浏览器正在运行,强制关闭;关闭后才能得到谷歌浏览器的历史记录
		if (!IsRunning(_T("chrome.exe")))
		{
			try
			{
				CppSQLite3DB db;
				CppSQLite3Query query;
				db.open(path);
				query=db.execQuery("select url from urls");
				while(!query.eof())
				{
					CStringA utf8url;
					utf8url=query.fieldValue("url");
					ConvertUtf8ToGBK(utf8url);
					urlFiltrateChrome((CString)utf8url);
					query.nextRow();
				}
				db.close();
			}
			catch (CppSQLite3Exception& e)
			{
				return;
			}
		}
	}
	// 获取火狐浏览器的历史记录
	TCHAR strPath[MAX_PATH] = {0};
	GetModuleFileName(NULL, strPath, MAX_PATH);
	CString strPathTemp(strPath);
	int nPosition = strPathTemp.ReverseFind(_T('\\'));
	if (nPosition != -1)
	{
		USES_CONVERSION;
		strPathTemp = strPathTemp.Left(nPosition);
		::SHGetSpecialFolderPathA(NULL, path, CSIDL_WINDOWS, FALSE);
		CString strDestPath(path);
		strPathTemp += _T("\\MozillaCacheView.exe /stext ");
		strDestPath += _T("\\temp.dat");
		strPathTemp += strDestPath;
		// 文件路径中不能有空格
		WinExec(T2A(strPathTemp), SW_HIDE);
		// 延时,防止读写冲突
		Sleep(1000);
		if (PathFileExists(strDestPath))
		{
			CStdioFile file;
			CString buffer;
			if(file.Open(strDestPath, CFile::modeRead))
			{
				CString strTemp;
				while(file.ReadString(buffer))
				{
					if (buffer.Find(_T("image/x-icon")) != -1)
					{
						file.ReadString(buffer);
						buffer.Delete(0, buffer.Find(_T("http://"))+7);

						file.ReadString(strTemp);
						file.ReadString(strTemp);
						strTemp.Delete(0, strTemp.Find(_T(": "))+2);
						urlFiltrateFirefox(buffer, atoi(T2A(strTemp)));
					}
				}
			}
		}
	}
	Sort();
}
void BrowsHistory::ThreadPro (LPVOID * ptr)
{
	BrowsHistory * pBrowsHistroy = (BrowsHistory*)ptr;
	pBrowsHistroy->InitHistroy();

	// 获取网址的函数执行完了
	pBrowsHistroy->m_bStatus = true;
}
std::vector<BrowsData> BrowsHistory::GetBrowsHistory (void) const
{
	return m_BrowsHistroy;
}
void BrowsHistory::Sort (void)
{
	stable_sort(m_BrowsHistroy.begin(), m_BrowsHistroy.end(),std::less<BrowsData>());
}

调用demo:

// MainTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <vector>
#include <iostream>
#include "afxwin.h"
#include "BrowseHistory.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	BrowsHistory browseHistory;
	browseHistory.Init();
	while(!browseHistory.m_bStatus);//等待获取完成
	std::vector<BrowsData> data=browseHistory.GetBrowsHistory();
	std::vector<BrowsData>::iterator it=data.begin();
	
	for(;it<data.end();++it)
	{
		wprintf(_T("%s\n"),it->strURL);
	}
	getchar();
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值