Технически Университет Варна
Катедра „Компютърни науки и технологии”
Курсова работа
Извличане на информация в Интернет
Изготвил: Проверил:/............................/
Теодора Цветкова гл.ас.д-р инж. В.Алексиева
СИТ, 1-ти курс, 2А-група
Фак.№ 61262153
Задача:
Да се създаде програмна система на С++, която да реализира опростенa
система за търсене в web със следната функционалност:
a. Получава съдържанието на уеб -страницата в изходен вид от уеб
сървър.
b. Извлича текстовото съдържание (мета-данни: заглавие, ключови
думи, описание; съдържание на html -документа: игнорирайки текста в
таговете за изображения) в балансирано дърво.
c. Извлича от страницата всички линкове към други страници (.htm или
.html) и създава списък с линковете.
d. Обхожда този списък, обработвайки аналогично всяка една от
страниците, като дълбочината на вложеност да не бъде повече от 10.
e. Извежда в подходящ графичен вид граф на връзките между
страниците.
f. Генерира резултат от търсене по въведена от потребителя определена
дума – извежда линковете на страниците, в които е открита (по реда на
откриване, без рейтинг).
Теория:
Web Crawler е система за изтегляне на web страници в големи обеми и има
разнообразно приложение. На първо място тези сиеми се яв яват базовия
компонент на web търсещите машини – основното средство за търсена на
информация в Интернет. Другоприложение е web архивирането, при което
големи множества от web страници периодично се събират и архивират за
бъдещо използване. На трето място е web data mining, където web
страниците се анализират за получаване на статистически характеристики.
Изтеглянето на web страниците се извършва на базата на техните
идентификатори – Uniform Resource Locator (URL).
Използвани функции:
string downloadHTTP(Url url) – създава се сокет и се свързва към хоста. Съдържанието
на страницата се извлича в стринг;
void makeTheTree() – построява се дърво на думите;
void extractLinks(string webSiteContent, vector<string> &hrefs) - извличат се
линковете от страницата, в зададения вектор &hrefs;
void removeDuplicates(vector<string>& vec) – проверка и изтриване на повторения, в
посочения вектор;
void parseTheLinks(Url& website,vector<string>& vec1, vector<string>&
vec2,vector<Url>& urls) – отделят се компонентите на всеки линк и той се описва в url
структура, ако има линкова за последващо търсене те се отделят;
void crawling(Url& website, vector<string>& hrefs, vector<Url>&
allTheInformation,string& httpContent,fstream& fp) – извежда списък на откритите
линкове;
void searchString(vector<Url>& allTheInformation) – функция за търсене на дума в
парснатите документи;
void goDeep(int& deepness,Url& website,vector<string>& a,vector<string>&
b,vector<string>& allTheHrefs,vector<Url>& allTheInformation) – обхождат се всички
страници и се записват;
Source.cpp:
#include <fstream>
#include <locale>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
#include <windows.h>
#include "BinaryTree.h"
#include <regex>
#include <vector>
#include <cstdlib>
using namespace std;
const char SYMBOLS[] = { ' ', '\n', '.', ';', '-', '=', '(', ')', '{', '}', '[',
']', '<', '>', ',' };
const int sizeBuff = 70000;
struct Url
{
string host;
string path;
string content;
bool visited;
};
bool path_less (const Url &l, const Url &r){ return l.path<r.path; } //сръвнава
URL за сортиране по път, за void sort
bool path_equal (const Url &l, const Url &r){ return l.path==r.path; }
//сръвнава URL за сортиране по път, за void removeDuplicates
string downloadHTTP(Url url){
WSADATA wsaData;
// Initialize Winsock
int nResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (nResult != 0 || (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2))
{
cout << "Error wsa startup" << endl;
return NULL;
}
SOCKET nSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
int *p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if ((setsockopt(nSocket, SOL_SOCKET, SO_REUSEADDR, (char*)p_int,
sizeof(int)) == -1)
|| (setsockopt(nSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int,
sizeof(int)) == -1))
{
printf("ERROR setsockopt");
free(p_int);
return NULL;
}
HOSTENT* pHost = gethostbyname(url.host.c_str());
// check if we connected to the HOST
if (pHost == NULL)
{
int dwError = WSAGetLastError();
if (dwError != 0)
{
if (dwError == WSAHOST_NOT_FOUND)
{
printf("Host not found\n");
return false;
}
else if (dwError == WSANO_DATA)
{
printf("No data record found\n");
return false;
}
else
{
printf("Function failed with error: %ld\n",
dwError);
return false;
}
}
}
SOCKADDR_IN oSockAddrIn;
oSockAddrIn.sin_port = htons(80);
oSockAddrIn.sin_family = AF_INET;
oSockAddrIn.sin_addr.s_addr = *((unsigned long*)pHost->h_addr);
if (connect(nSocket, (SOCKADDR*)(&oSockAddrIn), sizeof(oSockAddrIn)) !=
0)
{
cout << "Error connect" << endl;
return NULL;
}
char Request[100] = "";
strcat_s(Request, "GET ");
if (url.path[0] != '/')
strcat_s(Request, "/");
strcat_s(Request, url.path.c_str());
strcat_s(Request, " HTTP/1.1\r\nHost: ");
strcat_s(Request, url.host.c_str());
strcat_s(Request, "\r\n\r\n");
send(nSocket, Request, strlen(Request) + 1, 0);
int temporareReadBytes = 0;
int totalSize = 0;
char pBuffer[sizeBuff];
string fullDownload;
while ( (temporareReadBytes = recv(nSocket, pBuffer, sizeBuff - 1, 0)) >
0 )
{
pBuffer[temporareReadBytes] = '\0';
fullDownload += pBuffer;
if (temporareReadBytes < sizeBuff) break;
}
char * pageContent = new char[fullDownload.length() + 1];
strcpy_s(pageContent, fullDownload.length() + 1, fullDownload.c_str());
return pageContent;
}//създаваме сокет и се опитваме да се свържем с хоста. След като сме се
свързали извличаме съдържанието на страницата в ст ринг.
bool hasSymbol(char value){
bool result = false;
for (int i = 0; i<sizeof(SYMBOLS); i++){
if (value == SYMBOLS[i]){
result = true;
break;
}
}
return result;
} //проверка за char
void makeTheTree(){
tree *root = NULL;
char ch = ' ';
string buff = "";
string searchWord;
fstream fp("theFullString.txt");
if (fp.is_open() == false){
cout << "Error opening the file.";
}
while (fp.get(ch)){
if (!hasSymbol(ch)){
if (ch >= 65 && ch <= 90){
ch = ch + 'a' - 'A';
}
buff += tolower(ch);
}
else {
if (buff.length() > 0){
struct tree *sValue = search(buff, root);
if (sValue == NULL){
addTreeElement(buff, root);
}
else{
sValue->count++;
}
buff.clear();
}
}
}
fp.close();
}
void extractLinks(string webSiteContent, vector<string> &hrefs){
int len = webSiteContent.length()-6;
int hrefCounter = 0;
char c;
string href[100];
for(unsigned int i = 0; i < webSiteContent.length()-10; i++){
c = webSiteContent[i];
if(c == 'h' || c=='H'){
c = webSiteContent[i+1];
if(c == 'r' || c=='R'){
c = webSiteContent[i+2];
if(c == 'e' || c=='E'){
c = webSiteContent[i+3];
if(c == 'f' || c=='F'){
c = webSiteContent[i+4];
if(c == '=' ){
c =
webSiteContent[i+5];
if(c == '\"'){
i+=6;
c = webSiteContent[i];
string temp = "";
do{
c = webSiteContent[i];
temp+= c;
i++;
}while(webSiteContent[i]!='\"');
if(temp.substr((temp.length()-5),5) == ".html"
|| temp.substr((temp.length()-4),4) == ".htm")
{hrefs.push_back(temp);}
temp = "";
hrefCounter ++ ;
//проверявабуква по буква, търси "href", ако
намер извлича линка във вектор, само тези с разширение .htm или .html
}}}}}}
}
}
void removeDuplicates(vector<string>& vec){
sort(vec.begin(), vec.end());
vec.erase(unique(vec.begin(), vec.end()), vec.end());
//изтрива повтарящите се стрингове от вектора със линкове
}
Url makeUrl(string& host, string& path, string& content, bool visited){
Url make;
make.host = host;
make.path = path;
make.content = content;
make.visited = 1;
return make;
//записва структура
}
void parseTheLinks(Url& website,vector<string>& vec1, vector<string>&
vec2,vector<Url>& urls){
//взима линковете от вектора(.htm и .html)
for(unsigned int i = 0; i<vec1.size(); i++){
if(vec1[i].substr(0,5) == "http:") {
Url webb;
vec1[i] = vec1[i].substr(7);
size_t slashPos = vec1[i].find("/");
webb.host = vec1[i].substr(0,slashPos);
webb.path = vec1[i].substr(slashPos+1);
webb.content = downloadHTTP(webb);
webb.visited = 1;
extractLinks(webb.content,vec2);
urls.push_back(makeUrl(webb.host, webb.path,
webb.content, webb.visited));
}//раделя линковете на части (host, path)
//eкстрактва линковете от новополучения вебсайт и ги слага
в др.вектор
//прави структура Url и я пушва във вектор от структури
else {
Url webb;
webb.host = website.host;
webb.path = vec1[i];
webb.content = downloadHTTP(webb);
webb.visited = 1;
extractLinks(webb.content,vec2);
urls.push_back(makeUrl(webb.host, webb.path,
webb.content, webb.visited));
}
}
}
void crawling(Url& website, vector<string>& hrefs, vector<Url>&
allTheInformation,string& httpContent,fstream& fp){
cout<<"\n ***** Link's list: *****"<<endl;
for(unsigned int x=0; x<hrefs.size();x++){
if(allTheInformation[x].visited == TRUE){
if(hrefs[x].substr(0,5) == "http:") {
hrefs[x] = hrefs[x].substr(7);
size_t slashPos = hrefs[x].find("/");
website.host = hrefs[x].substr(0,slashPos);
website.path = hrefs[x].substr(slashPos);
website.content =
allTheInformation[x].content;
}
else {
website.host = "crawlertest.cs.tu-varna.bg";
website.path = "/"+hrefs[x];
}
cout<<"\n";
cout<<x+1<<". "<<website.host<<"
"<<website.path<<endl;
httpContent = downloadHTTP(website);
fp<<httpContent+"\n\n";
}}//сваля съдържанието на всички линкове и ги извежда на
екрана
}
void searchString(vector<Url>& allTheInformation){
string sw;
char choice, ch;
cout<<"\n\nDo you want to search word? [y/n]"<<endl;
cin>>choice;
while(choice == 'y' || choice == 'Y'){
cout<<"\nEnter word to search: ";
cin>>sw;
for(unsigned int i = 0; i<allTheInformation.size();i++){
for(int j=0;j<allTheInformation[i].content.length();j++){
ch = tolower(allTheInformation[i].content[j]);
allTheInformation[i].content[j] = ch;
j++;
}//преобразува в малки букви
if(allTheInformation[i].content.find(sw) != string::npos){
cout<<"\nThe word "<<sw<<" was found at:
"<<allTheInformation[i].host<<"/"<<allTheInformation[i].path;
}
}
cout<<"\nDo you want to search another word? [y/ n]"<<endl;
cin>>choice;
}
//търси думата навсякъде
}
void goDeep(int& deepness,Url& website,vector<string>& a,vector<string>&
b,vector<string>& allTheHrefs,vector<Url>& allTheInformation){
deepness=2;
for(int j=0;j<deepness;j++){
parseTheLinks(website,a,b,allTheInformation);
removeDuplicates(b);
allTheHrefs.insert(allTheHrefs.end(),b.begin(),b.end());
a.clear();
a.insert(a.end(),b.begin(),b.end());
b.clear();
}
}
int main(){
struct Url website;
website.host = "crawlertest.cs.tu-varna.bg";
fstream fp("theFullString.txt", ios::out, ios::trunc);
vector<string> a;
vector<string> b;
vector<string> allTheHrefs;
vector<Url> allTheInformation;
int howDeep = 0;
cout<<"\n ***** Please wait *****"<<endl;
string httpContent = downloadHTTP(website);
//записва съдържанието на website в httpContent
extractLinks(httpContent,a); // прехвърля намерените линкове във вектор a
goDeep(howDeep,website,a,b,allTheHrefs,allTheInformation); //обхожда
линковете свалени в a, сваленотоот тях поставя в b,
//сваленото от b слага в allTheHrefs, прехвърля всичко във
allTheInformation
removeDuplicates(allTheHrefs);//премахва повторенията във вектора
sort(allTheInformation.begin(),allTheInformation.end(),p
0 коментара
За да коментирате, трябва да сте влезли в профила си.
Влезте