我想用C / C ++编写一个程序,它将动态读取网页并从中提取信息。举个例子想象一下,如果你想写一个应用程序来关注并记录一个ebay拍卖。抓住网页有简单的方法吗?提供此功能的库?是否有一种简单的方法来解析页面以获取特定数据?
答案 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库 - 使用它非常简单。
CUT_HTTPClient http;
http.GET("http://folder/file.htm", "c:/tmp/process_me.htm");
您还可以GET文件并将它们存储在内存缓冲区中(通过CUT_DataSource
派生类)。所有常见的HTTP支持都在那里 - PUT,HEAD等。对代理服务器的支持是轻而易举的,安全套接字也是如此。
答案 3 :(得分:3)
你没有提到任何平台,所以我给你一个Win32的答案。
从互联网下载任何内容的一种简单方法是URLDownloadToFile
,IBindStatusCallback
参数设置为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项目配置编译代码。