본문 바로가기
놀기/기초 공부

libcurl을 사용하여 Web Page 받기

by Hi~ 2023. 2. 13.

https://curl.se/libcurl/

 

libcurl - the multiprotocol file transfer library

libcurl - the multiprotocol file transfer library libcurl is a free and easy-to-use client-side URL transfer library, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP,

curl.se

 

curl은 모든 개발자가 애용하는 프로그램 중의 하나다. 굳이 라이브러리를 호출하지 않고 외부 프로그램으로 실행하는 것만으로도 많은 수고를 덜 수 있는데 간혹 라이브러리 형태로 넣을 필요가 있다. 예를 들어 Web Page를 받을 때 curl 프로그램을 사용하여 Web Page를 임의의 파일로 받아 그 파일을 읽어 사용하면 간단하다. 하여간 라이브러리를 프로그램에 넣어 사용하는 것도 나쁘지 않고 심심해서 한 번 해봤다.

 

라이브러리를 빌드해서 해보는 것도 좋겠지만, 귀찮으니 컴파일된 라이브러리를 사이트에서 받는다.

https://curl.se/windows/

 

curl for Windows

curl 7.87.0 for Windows These are the latest and most up to date official curl binary builds for Microsoft Windows. curl version: 7.87.0 Build: 7.87.0_8 Date: 2022-12-21 Changes: 7.87.0 changelog curl for 64-bit Size: 10.1 MB sha256: bf86f31550151a10e6b759

curl.se

 

그리고 아래와 같이 간단한 코드를 작성한다.

#include <QCoreApplication>
#include <QTimer>
#include <QDebug>

#include <curl/curl.h>

// 데이터 (Web Page HTML source)를 받으면 아래 함수가 호출된다.
// CURLOPT_WRITEDATA에 인자로 넣은 htmlPage 포인터가 stream 변수로 넘어온다.
// stream 변수를 QString *로 타입을 변경하여 여기에 받은 내용을 차곡차곡 저장한다.
// QString *가 아닌 FILE * 라면 받은 내용을 파일에 쓸 수도 있다.
size_t write_html_page(void *ptr, size_t size, size_t count, void *stream)
{
    qDebug() << QString("get data len : [%1]").arg(QString::number(size*count));
    ((QString *) stream)->append(QString((char*) ptr));
    return size*count;
}

QString get_page(QString url)
{
    CURL *curl;
    CURLcode res;

    QString htmlPage;

    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.toLocal8Bit().constData());
        
        // 데이터를 받으면 write_html_page()가 호출
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_html_page);
        
        // write_html_page()가 호출될 때, htmlPage 포인터가 넘어간다. 
        // 따라서, Web Page 내용을 htmlPage 변수에 넣을 수 있고
        // 모든 수행이 끝난 후 해당 변수를 통해 Web Page 내용을 확인할 수 있다.
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&htmlPage);

        res = curl_easy_perform(curl);

        if (CURLE_OK == res) {
            qDebug() << htmlPage;
        }
        else {
            htmlPage = "";
        }

        /* always cleanup */
        curl_easy_cleanup(curl);
    }

    return htmlPage;
}

int run_main(void)
{
    get_page("http://busyman.tistory.com/");
    return 0;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTimer::singleShot(0,[](){
         run_main();
         QCoreApplication::exit(0);
    });

    return a.exec();
}

 

딱히, 별 내용은 없고 아래의 내용이 Web Page를 받기 위한 부분인데...

데이터를 받게 되면 write_html_page()가 호출되고 그때 인자로 넘어가는 것이 htmlPage다. 본 예제에서는 QString에 Web Page 내용을 넣었는데. QString htmlPage 대신 FILE *를 넣으면 받은 결과를 파일로 바로 작성할 수도 있다.

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_html_page);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&htmlPage);

 

https://curl.se/libcurl/c/CURLOPT_WRITEFUNCTION.html

 

CURLOPT_WRITEFUNCTION

CURLOPT_WRITEFUNCTION explained Name CURLOPT_WRITEFUNCTION - callback for writing received data Synopsis #include   size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);   CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WRITEFUNCTI

curl.se

https://curl.se/libcurl/c/CURLOPT_WRITEDATA.html

 

CURLOPT_WRITEDATA

CURLOPT_WRITEDATA explained Name CURLOPT_WRITEDATA - pointer passed to the write callback Synopsis #include   CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WRITEDATA, void *pointer); Description A data pointer to pass to the write callback. If you use t

curl.se

 

libcurl 라이브러리 사용을 위해 아래와 같이 Project 파일에 내용을 추가하고, 예제를 실행하는데 libcurl.dll가 필요하므로 실행 파일 위치에 dll 파일을 복사한다. libcurl.dll은 curl-7.87.0_8-win32-mingw\bin 아래 있다.

QT -= gui

CONFIG += c++17 console
CONFIG -= app_bundle

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        main.cpp

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

# libcurl 추가
INCLUDEPATH += E:/busyman/Lib/curl-7.87.0_8-win32-mingw/include
PATH_CURL_LIB = E:/busyman/Lib/curl-7.87.0_8-win32-mingw/lib
LIBS += $$PATH_CURL_LIB/libcurl.dll.a

 

어째든 실행하면 아래와 같이 결과를 확인할 수 있다.

댓글