设为首页 加入收藏

TOP

C++ 实现网络爬虫(一)
2015-07-20 17:50:07 来源: 作者: 【 】 浏览:10
Tags:实现 网络 爬虫
C++实现网络爬虫
复制代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
?
#pragma comment(lib, "ws2_32.lib")
?
using namespace std;
?
void startupWSA()
{
? ? WSADATA wsadata;
? ? WSAStartup( MAKEWORD(2,0), &wsadata);
}
?
inline void cleanupWSA()
{
? ? WSACleanup();
}
?
inline pair binaryString(const string &str, const string &dilme)
{
? ? pair result(str, "");
? ? auto pos = str.find(dilme);
? ? if ( pos != string::npos )
? ? {
? ? ? ? result.first = str.substr(0, pos);
? ? ? ? result.second = str.substr(pos + dilme.size());
? ? }
? ? return result;
}
?
inline string getIpByHostName(const string &hostName)
{
? ? hostent* phost = gethostbyname( hostName.c_str() );
? ? return phost? inet_ntoa(*(in_addr *)phost->h_addr_list[0]): "";
}
?
inline SOCKET connect(const string &hostName)
{
? ? auto ip = getIpByHostName(hostName);
? ? if ( ip.empty() )
? ? ? ? return 0;
? ? auto sock = socket(AF_INET, SOCK_STREAM, 0);
? ? if ( sock == INVALID_SOCKET )
? ? ? ? return 0;
? ? SOCKADDR_IN addr;
? ? addr.sin_family = AF_INET;
? ? addr.sin_port = htons(80);
? ? addr.sin_addr.s_addr = inet_addr(ip.c_str());
? ? if ( connect(sock, (const sockaddr *)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR )
? ? ? ? return 0;
? ? return sock;
}
?
inline bool sendRequest(SOCKET sock, const string &host, const string &get)
{
? ? string http?
? ? ? ? = "GET " + get + " HTTP/1.1\r\n"
? ? ? ? + "HOST: " + host + "\r\n"
? ? ? ? + "Connection: close\r\n\r\n";
? ? return http.size() == send(sock, &http[0], http.size(), 0);
}
?
inline string recvRequest(SOCKET sock)
{
? ? static timeva l wait = {2, 0};
? ? static auto buffer = string(2048 * 100, '\0');
? ? auto len = 0, reclen = 0;
? ? do {
? ? ? ? fd_set fd = {0};
? ? ? ? FD_SET(sock, &fd);
? ? ? ? reclen = 0;
? ? ? ? if ( select(0, &fd, nullptr, nullptr, &wait) > 0 )
? ? ? ? {
? ? ? ? ? ? reclen = recv(sock, &buffer[0] + len, 2048 * 100 - len, 0);
? ? ? ? ? ? if (reclen > 0)
? ? ? ? ? ? ? ? len += reclen;
? ? ? ? }
? ? ? ? FD_ZERO(&fd);
? ? } while (reclen > 0);
?
? ? return len > 11
? ? ? ? ? buffer[9] == '2' && buffer[10] == '0' && buffer[11] == '0'
? ? ? ? ? buffer.substr(0, len)
? ? ? ? : ""
? ? ? ? : "";
}
?
inline void extUrl(const string &buffer, queue &urlQueue)
{
? ? if (buffer.empty())
? ? {
? ? ? ? return ;
? ? }
? ? smatch result;
? ? auto curIter = buffer.begin();
? ? auto endIter = buffer.end();
? ? while ( regex_search(curIter, endIter, result, regex("href=\"(https?:)?//\\S+\"") ) )
? ? {
? ? ? ? urlQueue.push(regex_replace(
? ? ? ? ? ? result[0].str(),?
? ? ? ? ? ? regex("href=\"(https?:)?//(\\S+)\""),
? ? ? ? ? ? "$2") );
? ? ? ? curIter = result[0].second;
? ? }
}
?
void Go(const string &url, int count)
{
? ? queue urls;
? ? urls.push(url);
? ? for (auto i = 0; i != count; ++i)
? ? {
? ? ? ? if ( !urls.empty() )
? ? ? ? {
? ? ? ? ? ? auto &url = urls.front();
? ? ? ? ? ? auto pair = binaryString( url, "/" );
? ? ? ? ? ? auto sock = connect(pair.first);
? ? ? ? ? ? if ( sock && sendRequest(sock, pair.first, "/" + pair.second) )
? ? ? ? ? ? {
? ? ? ? ? ? ? ? auto buffer = move( recvRequest(sock) );
? ? ? ? ? ? ? ? extUrl(buffer, urls);
? ? ? ? ? ? }
       closesocket(sock);
? ? ? ? ? ? cout << url << ": count=> " << urls.size() << ?endl;
? ? ? ? ? ? urls.pop();
?
? ? ? ? }
? ? }
}
?
int main()
{
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 4971 多校10最大权闭合图 下一篇HDU-4973-A simple simulation pr..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C语言中如何将结构体 (2025-12-24 22:20:09)
·纯C语言结构体成员变 (2025-12-24 22:20:06)
·C语言中,指针函数和 (2025-12-24 22:20:03)
·哈希表 - 菜鸟教程 (2025-12-24 20:18:55)
·MySQL存储引擎InnoDB (2025-12-24 20:18:53)