C++ 实现网络爬虫
吐槽
前天心血来潮, 把自己面试经历下了下来.
我觉得自己求职一路来比较心酸, 也付出了比一般人更多的汗水.
本以为写出来, 好歹可以作为一篇励志故事.
得到的评论却是,
语言只是一门工具. ||| 这句话我已经听了4年了!
我以前也是XX, 现在XXX. ||| 直到你膝盖中了一箭?
我也是用c的...只能说,重要的是一种学习的能力,会用即可. ||| 呵呵.
可能能对于你的同学,你是优秀的,但是可能对于你想工作的方向的公司来说,你会的太少,不值得一些公司去培养,所以还是建议你把基础再好好踏实一下更有利。
最后一句话是让我最不爽的.
现在的人啊, 看什么就是什么, 以偏概全,
上的大学不好, 从入大学到大学毕业, 这经过了多少年, 从这多少年前就注定的事能认定这个人现在的水平么?
网投了几百份简历, 没有收到一个面试通知,
直接去公司霸面, 面了2个, 过了2个.
难道这个问题不是出在简历上?
突然就想起了找工作那段时间, 我在某群发了一条挂广告.
立马就有人出来扮演一位阅人无数的高人.
直言说, 你要是很优秀早就有人抢去了, 还是报个培训机构吧.
C++程序员都明白, C++成型慢, 一般公司都不会用新人, 更别说专科毕业的了.
那些习惯了速成的人是不会明白的.
好了, 吐槽完毕. 切换模式.
C++实现网络爬虫
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <queue>
#include <string>
#include <utility>
#include <regex>
#include <fstream>
#include <WinSock2.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
void startupWSA()
{
WSADATA wsadata;
WSAStartup( MAKEWORD(,), &wsadata);
}
inline void cleanupWSA()
{
WSACleanup();
}
inline pair<string, string> binaryString(const string &str, const string &dilme)
{
pair<string, string> result(str, "");
auto pos = str.find(dilme);
if ( pos != string::npos )
{
result.first = str.substr(, pos);
result.second = str.substr(pos + dilme.size());
}
return result;
}
inline string getIpByHostName(const string &hostName)
{
hostent* phost = gethostbyname( hostName.c_str() );
]): "";
}
inline SOCKET connect(const string &hostName)
{
auto ip = getIpByHostName(hostName);
if ( ip.empty() )
;
auto sock = socket(AF_INET, SOCK_STREAM, );
if ( sock == INVALID_SOCKET )
;
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = htons();
addr.sin_addr.s_addr = inet_addr(ip.c_str());
if ( connect(sock, (const sockaddr *)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR )
;
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";
], http.size(), );
}
inline string recvRequest(SOCKET sock)
{
, };
* , '\0');
auto len = , reclen = ;
do {
fd_set fd = {};
FD_SET(sock, &fd);
reclen = ;
, &fd, nullptr, nullptr, &wait) > )
{
reclen = recv(sock, &buffer[] + len, * - len, );
)
len += reclen;
}
FD_ZERO(&fd);
} );
? buffer[] == ] == ] == '
? buffer.substr(, len)
: ""
: "";
}
inline void extUrl(const string &buffer, queue<string> &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[].str(),
regex("href=\"(https?:)?//(\\S+)\""),
"$2") );
curIter = result[].second;
}
}
void Go(const string &url, int count)
{
queue<string> urls;
urls.push(url);
; 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()
{
startupWSA();
Go();
cleanupWSA();
;
}
该爬虫只花了1个小时左右.
其实我想说, 写的很烂, 大伙不要喷.
http协议, socket, 正则表达式咱们就不说了..
说说这个原理,
所有的 URL 全都放在 urls 这个队列中.
首先要 push 一个根 URL.
之后爬虫就行动了.
过程大概是这样:
从urls取出一个URL => 读出URL网页全部内容 => 分析所有URL => 把URL放进 urls => 从 urls 弹出一个 URL.
URL 是 host + get.
因此需要一个 binaryString 把它切开.
效率也不是很快, 1分钟大概4W条URL, 去掉重复至少也有好几千吧.
有一点需要注意.
C++11 的正则表达式真心有点难用~~~
我不知道怎么多次匹配..
只好用一个循环了..
网上搜出来一个答案, 写法有点莫名其妙..
执行结果

C++ 实现网络爬虫的更多相关文章
- Python初学者之网络爬虫(二)
声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途.转载请附上此文章地址 本篇文章Python初学者之网络爬虫的继续,最新代码已提交到https://github.com/octans ...
- 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务
上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...
- 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(3): 抓取amazon.com价格
通过上一篇随笔的处理,我们已经拿到了书的书名和ISBN码.(网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(2): 抓取allitebooks.com书籍信息 ...
- 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(2): 抓取allitebooks.com书籍信息及ISBN码
这一篇首先从allitebooks.com里抓取书籍列表的书籍信息和每本书对应的ISBN码. 一.分析需求和网站结构 allitebooks.com这个网站的结构很简单,分页+书籍列表+书籍详情页. ...
- 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(1): 基础知识Beautiful Soup
开始学习网络数据挖掘方面的知识,首先从Beautiful Soup入手(Beautiful Soup是一个Python库,功能是从HTML和XML中解析数据),打算以三篇博文纪录学习Beautiful ...
- Atitit.数据检索与网络爬虫与数据采集的原理概论
Atitit.数据检索与网络爬虫与数据采集的原理概论 1. 信息检索1 1.1. <信息检索导论>((美)曼宁...)[简介_书评_在线阅读] - dangdang.html1 1.2. ...
- Java 网络爬虫获取页面源代码
原博文:http://www.cnblogs.com/xudong-bupt/archive/2013/03/20/2971893.html 1.网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网 ...
- [Search Engine] 搜索引擎技术之网络爬虫
随着互联网的大力发展,互联网称为信息的主要载体,而如何在互联网中搜集信息是互联网领域面临的一大挑战.网络爬虫技术是什么?其实网络爬虫技术就是指的网络数据的抓取,因为在网络中抓取数据是具有关联性的抓取, ...
- [Python] 网络爬虫和正则表达式学习总结
以前在学校做科研都是直接利用网上共享的一些数据,就像我们经常说的dataset.beachmark等等.但是,对于实际的工业需求来说,爬取网络的数据是必须的并且是首要的.最近在国内一家互联网公司实习, ...
- 【Python网络爬虫一】爬虫原理和URL基本构成
1.爬虫定义 网络爬虫,即Web Spider,是一个很形象的名字.把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛.网络蜘蛛是通过网页的链接地址来寻找网页的.从网站某一个页面(通常 ...
随机推荐
- 如何用正则匹配后缀名不为.jpg, .css, .js, .html, .htm, .png的文件
有网友碰到过这样的问题:如何用正则匹配后缀名不为.jpg, .css, .js, .html, .htm, .png的文件,问题详细内容为: 如何用正则匹配后缀名不为.jpg, .css, .js, ...
- 【HDOJ】2451 Simple Addition Expression
递推,但是要注意细节.题目的意思,就是求s(x) = i+(i+1)+(i+2),i<n.该表达中计算过程中CA恒为0(包括中间值)的情况.根据所求可推得.1-10: 31-100: 3*41- ...
- 【HDOJ】2268 How To Use The Car
数学题.设步行速度a,车速b,距离c.Teddy步行时间为T1,WhereIsHeroFrom步行时间T2,总时间T.若b>a:aT1 + b(T-T1) = c (1)aT2 + b(T-T2 ...
- PHP实现登录,注册,密码修改
注册,登录,修改密码 1.登录 2.忘记密码 3.免费注册 页面布局 <div id="views" class="views"> <div ...
- 【video】m3u8
Safari浏览器识别不了.UC浏览器可以识别. 优酷的Safari浏览器和UC浏览器都可以识别.
- Count Primes ——LeetCode
Description: Count the number of prime numbers less than a non-negative number, n. 题目大意:给一个int,返回小于它 ...
- UVa11248 Frequency Hopping(最大流+最小割)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33206 [思路] 最大流最小割. 可以确定的是如果不可行需要修改的 ...
- 洛谷2583 地铁间谍 (UVa1025A Spy in the Metro)
洛谷2583 地铁间谍(UVa1025A Spy in the Metro) 本题地址:http://www.luogu.org/problem/show?pid=2583 题目描述 特工玛利亚被送到 ...
- MyEclipse里项目部署到tomcat上之后,tomcat webpps文件夹里为什么找不到这个项目
今天在MyEclipse中部署了一个java web项目,然后发现报404错误,跑到tomcat目录下的webapps文件夹里并发现没有这个项目,才发现MyEclipse没有写入webapp ...
- Power Calculus 快速幂计算 (IDA*/打表)
原题:1374 - Power Calculus 题意: 求最少用几次乘法或除法,可以从x得到x^n.(每次只能从已经得到的数字里选择两个进行操作) 举例: x^31可以通过最少6次操作得到(5次乘, ...