C++ 以编程方式读取网页

C++ 以编程方式读取网页,c++,c,http,C++,C,Http,我想用C/C++编写一个程序,动态读取网页并从中提取信息。例如,想象一下,如果您想编写一个应用程序来跟踪并记录ebay拍卖。有没有一种简单的方法可以抓取网页?提供此功能的库?是否有一种简单的方法来解析页面以获取特定数据?请查看: #包括 #包括 内部主(空) { 卷曲*卷曲; 卷曲编码; curl=curl_easy_init(); if(curl){ curl_easy_setopt(curl,CURLOPT_URL,“curl.haxx.se”); res=旋度(curl)\u容易执行(cu

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

请查看:

#包括
#包括
内部主(空)
{
卷曲*卷曲;
卷曲编码;
curl=curl_easy_init();
if(curl){
curl_easy_setopt(curl,CURLOPT_URL,“curl.haxx.se”);
res=旋度(curl)\u容易执行(curl);
/*总是清理*/
旋度\轻松\清洁(旋度);
}
返回0;
}

BTW,如果不严格要求C++。我鼓励您尝试C#或Java。这要容易得多,而且有一种内置的方式。

您可以通过套接字编程来实现,但要实现可靠获取页面所需的协议部分却很棘手。最好使用图书馆,比如。这可能安装在大多数Linux发行版中。在FreeBSD下使用fetch库


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

尝试使用库,如Qt,它可以跨网络读取数据,并从xml文档中获取数据。是一个如何读取xml提要的示例。例如,您可以使用易趣订阅源。

有一个免费的TCP/IP库,可用于支持HTTP和HTTPS的Windows—使用它非常简单


您还可以获取文件并将其存储在内存缓冲区中(通过
CUT\u DataSource
派生类)。所有常见的HTTP支持都在那里—PUT、HEAD等。对代理服务器的支持和对安全套接字的支持都是轻而易举的事。

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

从Internet下载任何内容的一种简单方法是
URLDownloadToFile
,其中
IBindStatusCallback
参数设置为
NULL
。为了使函数更有用,需要实现回调接口。

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;
}
#包括
#包括
#包括
#pragma注释(lib,“ws2_32.lib”)
使用名称空间std;
int main(){
WSADATA WSADATA;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0){
cout h_addr);

cout可以在多平台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项目配置来编译代码。

在C/C++中非常困难。即使在广泛支持正则表达式、XML解析、HTTP方法等(如Java)的语言中,这也够烦人的了至于易趣网,它有一个API,你应该使用。1的卷曲-我在C++的一个应用程序中使用了卷曲,它很好用,甚至可以使用代理和所有其他可能遇到的障碍。如果卷曲为空,最好返回一个错误(在上面的例子中)检查CURLPP -C++包装器,用于Curl LanguryBUBUBER,以建议C或java。Python更容易,特别是如果你安装了漂亮的ToIP包来帮助解析。为什么这个+1会被选择为答案?实际文档在哪里?代码做什么?明目张胆的复制和粘贴。虽然它们不是有效的XML,但是很多L。语言库中有HTML解析器,可以使用DOM接口解析HTML文档(但正如m3rLinEz的回答中所提到的,我的大部分经验都是关于curl的。有什么比较吗?在发布多个问题的复制粘贴样板/逐字回答时要小心,这些问题往往被标记为“垃圾邮件”由社区提供。如果您这样做,则通常意味着问题是重复的,因此将其标记为:此代码有严重缺陷:1)如果页面超过10000字节,且没有不可打印字符,则会读取超过缓冲区结尾和seg错误。2)如果网页中有制表符(或其他不可打印的字符),此代码将向前跳至10000字节。3)新代码不应使用
gethostbyname()
。它应使用
getaddrinfo()
,并支持IPv4和IPv6。内部while循环可替换为
printf('%s',ndalength,buffer);
更简单、更快、更安全。
const string webpageText = downloadFromUrl(url).toStdString();
QT       += network