以编程方式阅读网页

时间:2008-12-23 15:01:03

标签: c++ c http

我想用C / C ++编写一个程序,它将动态读取网页并从中提取信息。举个例子想象一下,如果你想写一个应用程序来关注并记录一个ebay拍卖。抓住网页有简单的方法吗?提供此功能的库?是否有一种简单的方法来解析页面以获取特定数据?

7 个答案:

答案 0 :(得分:41)

查看cURL library

 #include <stdio.h>
 #include <curl/curl.h>

 int main(void)
 {
   CURL *curl;
   CURLcode res;

   curl = curl_easy_init();
   if(curl) {
     curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se");
     res = curl_easy_perform(curl);
      /* always cleanup */
    curl_easy_cleanup(curl);
   }
   return 0;
 }

BTW,如果不严格要求C ++。我鼓励你尝试使用C#或Java。它更容易,并且有内置的方式。

答案 1 :(得分:17)

Windows代码:

#include <winsock2.h>
#include <windows.h>
#include <iostream>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main (){
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
        cout << "WSAStartup failed.\n";
        system("pause");
        return 1;
    }
    SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    struct hostent *host;
    host = gethostbyname("www.google.com");
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port=htons(80);
    SockAddr.sin_family=AF_INET;
    SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
    cout << "Connecting...\n";
    if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0){
        cout << "Could not connect";
        system("pause");
        return 1;
    }
    cout << "Connected.\n";
    send(Socket,"GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n", strlen("GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n"),0);
    char buffer[10000];
    int nDataLength;
    while ((nDataLength = recv(Socket,buffer,10000,0)) > 0){        
        int i = 0;
        while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
            cout << buffer[i];
            i += 1;
        }
    }
    closesocket(Socket);
        WSACleanup();
    system("pause");
    return 0;
}

答案 2 :(得分:4)

Windows提供了一个支持HTTP和HTTPS的免费TCP / IP库 - 使用它非常简单。

Ultimate TCP/IP

CUT_HTTPClient http;
http.GET("http://folder/file.htm", "c:/tmp/process_me.htm");    

您还可以GET文件并将它们存储在内存缓冲区中(通过CUT_DataSource派生类)。所有常见的HTTP支持都在那里 - PUT,HEAD等。对代理服务器的支持是轻而易举的,安全套接字也是如此。

答案 3 :(得分:3)

你没有提到任何平台,所以我给你一个Win32的答案。

从互联网下载任何内容的一种简单方法是URLDownloadToFileIBindStatusCallback参数设置为NULL。为了使该函数更有用,需要实现回调接口。

答案 4 :(得分:2)

您可以使用套接字编程来实现,但实现可靠地获取页面所需的协议部分非常棘手。最好使用像neon这样的库。这很可能安装在大多数Linux发行版中。在FreeBSD下使用fetch库。

对于解析数据,因为许多页面不使用有效的XML,所以需要实现启发式算法,而不是真正的基于yacc的解析器。您可以使用正则表达式或状态转换机器来实现这些。正如你要做的那样涉及大量的试错,你最好使用像Perl这样的脚本语言。由于网络延迟较高,您不会发现任何性能差异。

答案 5 :(得分:2)

尝试使用像Qt这样的库,它可以从网络中读取数据并从xml文档中获取数据。 This是如何阅读xml Feed的示例。例如,您可以使用ebay Feed。

答案 6 :(得分:1)

它可以在多平台 QT 库中完成:

QByteArray WebpageDownloader::downloadFromUrl(const std::string& url)
{
    QNetworkAccessManager manager;
    QNetworkReply *response = manager.get(QNetworkRequest(QUrl(url.c_str())));
    QEventLoop event;
    QObject::connect(response, &QNetworkReply::finished, &event, &QEventLoop::quit);
    event.exec();
    return response->readAll();
}

该数据可以是例如保存到文件,或转换为 std::string:

const string webpageText = downloadFromUrl(url).toStdString();

记住需要添加

QT       += network

到QT项目配置编译代码。