找回密码
 立即注册
查看: 61|回复: 0

c++璇█鐖櫕

[复制链接]

0

主题

0

回帖

20

积分

新手上路

积分
20
发表于 2023-8-26 21:28:27 | 显示全部楼层 |阅读模式
// #include <Windows.h>  

#include <string>  
#include <iostream>  
#include <fstream>  
#include <vector>  
#include "winsock2.h"  
#include <time.h>  
#include <queue>  
#include <hash_set>  

#pragma comment(lib, "ws2_32.lib")   
using namespace std;

#define DEFAULT_PAGE_BUF_SIZE 1048576  

queue<string> hrefUrl;
hash_set<string> visitedUrl;
hash_set<string> visitedImg;
int depth = 0;
int g_ImgCnt = 1;

//瑙f瀽URL锛岃В鏋愬嚭涓绘満鍚嶏紝璧勬簮鍚  
bool ParseURL(const string & url, string & host, string & resource){
        if (strlen(url.c_str()) > 2000) {
                return false;
        }

        const char * pos = strstr(url.c_str(), "http://");

        if (pos == NULL)
                pos = url.c_str();
        else
                pos += strlen("http://");

        if (strstr(pos, "/") == 0)
                return false;
        char pHost[100];
        char pResource[2000];
        sscanf(pos, "%[^/]%s", pHost, pResource);
        host = pHost;
        resource = pResource;
        return true;
}

//浣跨敤Get璇锋眰锛屽緱鍒板搷搴  
bool GetHttpResponse(const string & url, char * &response, int &bytesRead){
        string host, resource;
        if (!ParseURL(url, host, resource)){
                cout << "Can not parse the url" << endl;
                return false;
        }

        //寤虹珛socket  
        struct hostent * hp = gethostbyname(host.c_str());
        if (hp == NULL){
                cout << "Can not find host address" << endl;
                return false;
        }

        SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sock == -1 || sock == -2){
                cout << "Can not create sock." << endl;
                return false;
        }

        //寤虹珛鏈嶅姟鍣ㄥ湴鍧  
        SOCKADDR_IN sa;
        sa.sin_family = AF_INET;
        sa.sin_port = htons(80);
        //char addr[5];  
        //memcpy( addr, hp->h_addr, 4 );  
        //sa.sin_addr.s_addr = inet_addr(hp->h_addr);  
        memcpy(&sa.sin_addr, hp->h_addr, 4);

        //寤虹珛杩炴帴  
        if (0 != connect(sock, (SOCKADDR*)&sa, sizeof(sa))){
                cout << "Can not connect: " << url << endl;
                closesocket(sock);
                return false;
        };

        //鍑嗗鍙戦佹暟鎹  
        string request = "GET " + resource + " HTTP/1.1\r\nHost:" + host + "\r\nConnection:Close\r\n\r\n";

        //鍙戦佹暟鎹  
        if (SOCKET_ERROR == send(sock, request.c_str(), request.size(), 0)){
                cout << "send error" << endl;
                closesocket(sock);
                return false;
        }

        //鎺ユ敹鏁版嵁  
        int m_nContentLength = DEFAULT_PAGE_BUF_SIZE;
        char *pageBuf = (char *)malFQD(m_nContentLength);
        memset(pageBuf, 0, m_nContentLength);

        bytesRead = 0;
        int ret = 1;
        cout << "Read: ";
        while (ret > 0){
                ret = recv(sock, pageBuf + bytesRead, m_nContentLength - bytesRead, 0);

                if (ret > 0)
                {
                        bytesRead += ret;
                }

                if (m_nContentLength - bytesRead<100){
                        cout << "\nRealFQD memorry" << endl;
                        m_nContentLength *= 2;
                        pageBuf = (char*)realFQD(pageBuf, m_nContentLength);       //閲嶆柊鍒嗛厤鍐呭瓨  
                }
                cout << ret << " ";
        }
        cout << endl;

        pageBuf[bytesRead] = '\0';
        response = pageBuf;
        closesocket(sock);
        return true;
        //cout<< response <<endl;  
}

//鎻愬彇鎵鏈夌殑URL浠ュ強鍥剧墖URL  
void HTMLParse(string & htmlResponse, vector<string> & imgurls, const string & host){
        //鎵炬墍鏈夎繛鎺ワ紝鍔犲叆queue涓  
        const char *p = htmlResponse.c_str();
        char *tag = "href=\"";
        const char *pos = strstr(p, tag);
        ofstream ofile("url.txt", ios::app);
        while (pos){
                pos += strlen(tag);
                const char * nextQ = strstr(pos, "\"");
                if (nextQ){
                        char * url = new char[nextQ - pos + 1];
                        //char url[100]; //鍥哄畾澶у皬鐨勪細鍙戠敓缂撳啿鍖烘孩鍑虹殑鍗遍櫓  
                        sscanf(pos, "%[^\"]", url);
                        string surl = url;  // 杞崲鎴恠tring绫诲瀷锛屽彲浠ヨ嚜鍔ㄩ噴鏀惧唴瀛  
                        if (visitedUrl.find(surl) == visitedUrl.end()){
                                visitedUrl.insert(surl);
                                ofile << surl << endl;
                                hrefUrl.push(surl);
                        }
                        pos = strstr(pos, tag);
                        delete[] url;  // 閲婃斁鎺夌敵璇风殑鍐呭瓨  
                }
        }
        ofile << endl << endl;
        ofile.close();

        tag = "<img ";
        const char* att1 = "src=\"";
        const char* att2 = "lazy-src=\"";
        const char *pos0 = strstr(p, tag);
        while (pos0){
                pos0 += strlen(tag);
                const char* pos2 = strstr(pos0, att2);
                if (!pos2 || pos2 > strstr(pos0, ">")) {
                        pos = strstr(pos0, att1);
                        if (!pos) {
                                pos0 = strstr(att1, tag);
                                continue;
                        }
                        else {
                                pos = pos + strlen(att1);
                        }
                }
                else {
                        pos = pos2 + strlen(att2);
                }

                const char * nextQ = strstr(pos, "\"");
                if (nextQ){
                        char * url = new char[nextQ - pos + 1];
                        sscanf(pos, "%[^\"]", url);
                        cout << url << endl;
                        string imgUrl = url;
                        if (visitedImg.find(imgUrl) == visitedImg.end()){
                                visitedImg.insert(imgUrl);
                                imgurls.push_back(imgUrl);
                        }
                        pos0 = strstr(pos0, tag);
                        delete[] url;
                }
        }
        cout << "end of Parse this html" << endl;
}

//鎶奤RL杞寲涓烘枃浠跺悕  
string ToFileName(const string &url){
        string fileName;
        fileName.resize(url.size());
        int k = 0;
        for (int i = 0; i<(int)url.size(); i++){
                char ch = url;
                if (ch != '\\'&&ch != '/'&&ch != ':'&&ch != '*'&&ch != '?'&&ch != '"'&&ch != '<'&&ch != '>'&&ch != '|')
                        fileName[k++] = ch;
        }
        return fileName.substr(0, k) + ".txt";
}

//涓嬭浇鍥剧墖鍒癷mg鏂囦欢澶  
void DownLoadImg(vector<string> & imgurls, const string &url){

        //鐢熸垚淇濆瓨璇rl涓嬪浘鐗囩殑鏂囦欢澶  
        string foldname = ToFileName(url);
        foldname = "./img/" + foldname;
        if (!CreateDirectory(foldname.c_str(), NULL))
                cout << "Can not create directory:" << foldname << endl;
        char *image;
        int byteRead;
        for (int i = 0; i<imgurls.size(); i++){
                //鍒ゆ柇鏄惁涓哄浘鐗囷紝bmp锛宩gp锛宩peg锛実if   
                string str = imgurls;
                int pos = str.find_last_of(".");
                if (pos == string::npos)
                        continue;
                else{
                        string ext = str.substr(pos + 1, str.size() - pos - 1);
                        if (ext != "bmp"&& ext != "jpg" && ext != "jpeg"&& ext != "gif"&&ext != "png")
                                continue;
                }
                //涓嬭浇鍏朵腑鐨勫唴瀹  
                if (GetHttpResponse(imgurls, image, byteRead)){
                        if (strlen(image) == 0) {
                                continue;
                        }
                        const char *p = image;
                        const char * pos = strstr(p, "\r\n\r\n") + strlen("\r\n\r\n");
                        int index = imgurls.find_last_of("/");
                        if (index != string::npos){
                                string imgname = imgurls.substr(index, imgurls.size());
                                ofstream ofile(foldname + imgname, ios::binary);
                                if (!ofile.is_open())
                                        continue;
                                cout << g_ImgCnt++ << foldname + imgname << endl;
                                ofile.write(pos, byteRead - (pos - p));
                                ofile.close();
                        }
                        free(image);
                }
        }
}



//骞垮害閬嶅巻  
void BFS(const string & url){
        char * response;
        int bytes;
        // 鑾峰彇缃戦〉鐨勭浉搴旓紝鏀惧叆response涓  
        if (!GetHttpResponse(url, response, bytes)){
                cout << "The url is wrong! ignore." << endl;
                return;
        }
        string httpResponse = response;
        free(response);
        string filename = ToFileName(url);
        ofstream ofile("./html/" + filename);
        if (ofile.is_open()){
                // 淇濆瓨璇ョ綉椤电殑鏂囨湰鍐呭  
                ofile << httpResponse << endl;
                ofile.close();
        }
        vector<string> imgurls;
        //瑙f瀽璇ョ綉椤电殑鎵鏈夊浘鐗囬摼鎺ワ紝鏀惧叆imgurls閲岄潰  
        HTMLParse(httpResponse, imgurls, url);

        //涓嬭浇鎵鏈夌殑鍥剧墖璧勬簮  
        DownLoadImg(imgurls, url);
}

void main()
{
        //鍒濆鍖杝ocket锛岀敤浜巘cp缃戠粶杩炴帴  
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){
                return;
        }

        // 鍒涘缓鏂囦欢澶癸紝淇濆瓨鍥剧墖鍜岀綉椤垫枃鏈枃浠  
        CreateDirectory("./img", 0);
        CreateDirectory("./html", 0);

        // 閬嶅巻鐨勮捣濮嬪湴鍧  

        string urlStart = "http://weibo.com/p/1005052771037733/album?from=page_100505&mod=TAB#place";
        //string urlStart = "http://hao.360.cn/meinvdaohang.html";   


        // string urlStart = "http://www.wmpic.me/tupian";  
        // string urlStart = "http://item.taobao.com/item.htm?spm=a230r.1.14.19.sBBNbz&id=36366887850&ns=1#detail";

        // 浣跨敤骞垮害閬嶅巻  
        // 鎻愬彇缃戦〉涓殑瓒呴摼鎺ユ斁鍏refUrl涓紝鎻愬彇鍥剧墖閾炬帴锛屼笅杞藉浘鐗囥  
        BFS(urlStart);

        // 璁块棶杩囩殑缃戝潃淇濆瓨璧锋潵  
        visitedUrl.insert(urlStart);

        while (hrefUrl.size() != 0){
                string url = hrefUrl.front();  // 浠庨槦鍒楃殑鏈寮濮嬪彇鍑轰竴涓綉鍧  
                cout << url << endl;
                BFS(url);                   // 閬嶅巻鎻愬彇鍑烘潵鐨勯偅涓綉椤碉紝鎵惧畠閲岄潰鐨勮秴閾炬帴缃戦〉鏀惧叆hrefUrl锛屼笅杞藉畠閲岄潰鐨勬枃鏈紝鍥剧墖  
                hrefUrl.pop();                 // 閬嶅巻瀹屼箣鍚庯紝鍒犻櫎杩欎釜缃戝潃  
        }
        
        WSACleanup();
        return;
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|翻墙党

GMT+8, 2026-10-2 17:34 , Processed in 0.075439 second(s), 30 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表