吐槽

前天心血来潮, 把自己面试经历下了下来.

我觉得自己求职一路来比较心酸, 也付出了比一般人更多的汗水.

本以为写出来, 好歹可以作为一篇励志故事.

得到的评论却是,

  语言只是一门工具. ||| 这句话我已经听了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++ 实现网络爬虫的更多相关文章

  1. Python初学者之网络爬虫(二)

    声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途.转载请附上此文章地址 本篇文章Python初学者之网络爬虫的继续,最新代码已提交到https://github.com/octans ...

  2. 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务

      上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...

  3. 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(3): 抓取amazon.com价格

    通过上一篇随笔的处理,我们已经拿到了书的书名和ISBN码.(网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(2): 抓取allitebooks.com书籍信息 ...

  4. 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(2): 抓取allitebooks.com书籍信息及ISBN码

    这一篇首先从allitebooks.com里抓取书籍列表的书籍信息和每本书对应的ISBN码. 一.分析需求和网站结构 allitebooks.com这个网站的结构很简单,分页+书籍列表+书籍详情页. ...

  5. 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(1): 基础知识Beautiful Soup

    开始学习网络数据挖掘方面的知识,首先从Beautiful Soup入手(Beautiful Soup是一个Python库,功能是从HTML和XML中解析数据),打算以三篇博文纪录学习Beautiful ...

  6. Atitit.数据检索与网络爬虫与数据采集的原理概论

    Atitit.数据检索与网络爬虫与数据采集的原理概论 1. 信息检索1 1.1. <信息检索导论>((美)曼宁...)[简介_书评_在线阅读] - dangdang.html1 1.2. ...

  7. Java 网络爬虫获取页面源代码

    原博文:http://www.cnblogs.com/xudong-bupt/archive/2013/03/20/2971893.html 1.网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网 ...

  8. [Search Engine] 搜索引擎技术之网络爬虫

    随着互联网的大力发展,互联网称为信息的主要载体,而如何在互联网中搜集信息是互联网领域面临的一大挑战.网络爬虫技术是什么?其实网络爬虫技术就是指的网络数据的抓取,因为在网络中抓取数据是具有关联性的抓取, ...

  9. [Python] 网络爬虫和正则表达式学习总结

    以前在学校做科研都是直接利用网上共享的一些数据,就像我们经常说的dataset.beachmark等等.但是,对于实际的工业需求来说,爬取网络的数据是必须的并且是首要的.最近在国内一家互联网公司实习, ...

  10. 【Python网络爬虫一】爬虫原理和URL基本构成

    1.爬虫定义 网络爬虫,即Web Spider,是一个很形象的名字.把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛.网络蜘蛛是通过网页的链接地址来寻找网页的.从网站某一个页面(通常 ...

随机推荐

  1. CSS中的高度

    https://developer.mozilla.org/en-US/docs/Web/API/element.clientHeight Element.clientHeight是只读属性,以像素为 ...

  2. 【Linux】鸟哥的Linux私房菜基础学习篇整理(二)

    1. dumpe2fs [-bh] devicename:查询superblock信息.参数:-b:列出保留为坏道的部分:-h:列出superblock的数据,不会列出其他的区段内容. 2. df [ ...

  3. rsync命令来实现将服务器端的文件备份到客户端

    rsync命令来实现将服务器端的文件备份到客户端

  4. ZOJ 3469 Food Delivery

    题目大意: 有n个人,住在一条直线上.第i个人的坐标是Xi,街上有个外卖餐馆的位置是X,现在餐厅工作人员要给街上的每个人送饭,送完之后再回到餐厅,送饭人的速度是V,每个人有个不满意值,当这个人送餐时间 ...

  5. 【转】Android 菜单(OptionMenu)大全 建立你自己的菜单--不错

    原文网址:http://www.cnblogs.com/salam/archive/2011/04/04/2005329.html 菜单是用户界面中最常见的元素之一,使用非常频繁,在Android中, ...

  6. Delphi NativeXml用法攻略

    NativeXml用法攻略 NativeXml可以在官网上下载,下载后将文件夹放在指定地方,打开DELPHI在其环境变量中引用NativeXml路径,然后在程序中引用NativeXml单元,我们就可以 ...

  7. zookeeper集群环境安装配置

    众所周知,Zookeeper有三种不同的运行环境,包括:单机环境.集群环境和集群伪分布式环境 在此介绍的是集群环境的安装配置 一.下载: http://apache.fayea.com/zookeep ...

  8. 浅谈二维RMQ

    针对一些二维区间最值问题,用一维RMQ来解决显然是不够的.所以,要改进算法.鉴于网上没有PASCAL版的RMQ标程与解析,所以小可在这里简单的讲一下. 核心思想和一维的一样,只是在计算区间时略有不同. ...

  9. SRM 506(2-1000pt)

    DIV2 1000pt 题意:一个由n*m的网格组成的棋盘,有四种点,'.'表示空点,'#'表示是墙不能走,'$'表示起点(同样是空点),'1'~'9'表示该点有复活时间为t的怪兽.每次,可以从一个点 ...

  10. 记录下mybatis中#{}和${}传参的区别

    最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下, 比如说用#{},和 ${}传参的区别, 使用#传入参数是,sql语句解析是会加上"&quo ...