{"id":91965,"date":"2026-09-04T20:36:00","date_gmt":"2026-09-04T11:36:00","guid":{"rendered":"http:\/\/kako.com\/blog\/?p=91965"},"modified":"2026-09-04T22:50:36","modified_gmt":"2026-09-04T13:50:36","slug":"web%e6%bc%ab%e7%94%bb%e3%82%a2%e3%83%b3%e3%83%86%e3%83%8a%e3%81%a8%e3%81%84%e3%81%86%e3%82%b5%e3%82%a4%e3%83%88%e3%81%a7%e4%bd%9c%e3%81%a3%e3%81%9f%e8%87%aa%e5%88%86%e3%81%ae%e3%83%aa%e3%82%b9","status":"publish","type":"post","link":"http:\/\/kako.com\/blog\/?p=91965","title":{"rendered":"Web\u6f2b\u753b\u30a2\u30f3\u30c6\u30ca\u3068\u3044\u3046\u30b5\u30a4\u30c8\u3067\u4f5c\u3063\u305f\u81ea\u5206\u306e\u30ea\u30b9\u30c8\u3092\u8aad\u307f\u53d6\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u4f5c\u3063\u3066\u307f\u308b"},"content":{"rendered":"\n<p><a href=\"http:\/\/kako.com\/blog\/?p=91916\">Web\u6f2b\u753b\u30a2\u30f3\u30c6\u30ca\u3068\u3044\u3046\u30b5\u30a4\u30c8\u3067\u4f5c\u3063\u305f\u81ea\u5206\u306e\u30ea\u30b9\u30c8<\/a>\u3092\u8aad\u307f\u53d6\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u4f5c\u3063\u3066\u307f\u308b\u3002<\/p>\n\n\n\n<p>ChatGPT\u306b\u805e\u3044\u3066\u307f\u305f\u3068\u3053\u308d\u3001\u6b21\u306e\u3088\u3046\u306a\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9\u304c\u51fa\u3066\u304d\u305f\u3002<\/p>\n\n\n\n<p>libcurl\u3067\u30ea\u30b9\u30c8\u306eweb\u306e\u30da\u30fc\u30b8\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3001Gumbo\u3068\u3044\u3046\u30e9\u30a4\u30d6\u30e9\u30ea\u3067html\u30d5\u30a1\u30a4\u30eb\u3092parsing\u3057\u3066\u5fc5\u8981\u306a\u3082\u306e\u3092\u629c\u304d\u51fa\u3059\u3068\u3044\u3046\u3082\u306e\u3060\u3002<\/p>\n\n\n\n<!--more-->\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n * webcomics.jp \u306e\u30da\u30fc\u30b8\u304b\u3089\n * \u30bf\u30a4\u30c8\u30eb\u3068\u30ea\u30f3\u30af\u3092\u62bd\u51fa\u3057\u3066 titles.txt \u306b\u4fdd\u5b58\n *\n * \u5fc5\u8981\u30e9\u30a4\u30d6\u30e9\u30ea:\n *   libcurl\n *   gumbo-parser\n *\n * Linux:\n *   gcc main.c -lcurl -lgumbo -o scraper\n *\/\n\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;curl\/curl.h&gt;\n#include &lt;gumbo.h&gt;\n\ntypedef struct {\n    char *memory;\n    size_t size;\n} MemoryBlock;\n\nstatic size_t write_callback(void *contents,\n                             size_t size,\n                             size_t nmemb,\n                             void *userp)\n{\n    size_t realsize = size * nmemb;\n\n    MemoryBlock *mem = (MemoryBlock *)userp;\n\n    char *ptr = realloc(mem-&gt;memory,\n                        mem-&gt;size + realsize + 1);\n\n    if (!ptr)\n        return 0;\n\n    mem-&gt;memory = ptr;\n\n    memcpy(&amp;(mem-&gt;memory&#91;mem-&gt;size]),\n           contents,\n           realsize);\n\n    mem-&gt;size += realsize;\n    mem-&gt;memory&#91;mem-&gt;size] = '\\0';\n\n    return realsize;\n}\n\nstatic const char* get_attribute(\n    GumboElement *element,\n    const char *name)\n{\n    GumboAttribute *attr =\n        gumbo_get_attribute(\n            &amp;element-&gt;attributes,\n            name);\n\n    return attr ? attr-&gt;value : NULL;\n}\n\nstatic void extract_text(\n    GumboNode *node,\n    char *buffer,\n    size_t maxlen)\n{\n    if (node-&gt;type == GUMBO_NODE_TEXT)\n    {\n        strncat(buffer,\n                node-&gt;v.text.text,\n                maxlen - strlen(buffer) - 1);\n    }\n    else if (node-&gt;type == GUMBO_NODE_ELEMENT)\n    {\n        GumboVector *children =\n            &amp;node-&gt;v.element.children;\n\n        for (unsigned int i = 0;\n             i &lt; children-&gt;length;\n             i++)\n        {\n            extract_text(\n                children-&gt;data&#91;i],\n                buffer,\n                maxlen);\n        }\n    }\n}\n\nstatic void search_links(\n    GumboNode *node,\n    FILE *fp)\n{\n    if (node-&gt;type != GUMBO_NODE_ELEMENT)\n        return;\n\n    GumboElement *element =\n        &amp;node-&gt;v.element;\n\n    if (element-&gt;tag == GUMBO_TAG_A)\n    {\n        const char *href =\n            get_attribute(element, &quot;href&quot;);\n\n        if (href)\n        {\n            char title&#91;2048] = {0};\n\n            extract_text(node,\n                         title,\n                         sizeof(title));\n\n            if (strlen(title) &gt; 0)\n            {\n                fprintf(fp,\n                        &quot;%s\\t%s\\n&quot;,\n                        title,\n                        href);\n            }\n        }\n    }\n\n    GumboVector *children =\n        &amp;element-&gt;children;\n\n    for (unsigned int i = 0;\n         i &lt; children-&gt;length;\n         i++)\n    {\n        search_links(children-&gt;data&#91;i],\n                     fp);\n    }\n}\n\nint main(void)\n{\n    const char *url =\n        &quot;https:\/\/webcomics.jp\/list\/dm8hk&quot;;\n\n    CURL *curl;\n    CURLcode res;\n\n    MemoryBlock chunk;\n    chunk.memory = malloc(1);\n    chunk.size = 0;\n\n    curl_global_init(CURL_GLOBAL_DEFAULT);\n\n    curl = curl_easy_init();\n\n    if (!curl)\n    {\n        fprintf(stderr,\n                &quot;curl init failed\\n&quot;);\n        return 1;\n    }\n\n    curl_easy_setopt(curl,\n                     CURLOPT_URL,\n                     url);\n\n    curl_easy_setopt(curl,\n                     CURLOPT_FOLLOWLOCATION,\n                     1L);\n\n    curl_easy_setopt(curl,\n                     CURLOPT_WRITEFUNCTION,\n                     write_callback);\n\n    curl_easy_setopt(curl,\n                     CURLOPT_WRITEDATA,\n                     &amp;chunk);\n\n    curl_easy_setopt(curl,\n                     CURLOPT_USERAGENT,\n                     &quot;Mozilla\/5.0&quot;);\n\n    res = curl_easy_perform(curl);\n\n    if (res != CURLE_OK)\n    {\n        fprintf(stderr,\n                &quot;curl error: %s\\n&quot;,\n                curl_easy_strerror(res));\n\n        curl_easy_cleanup(curl);\n        free(chunk.memory);\n        return 1;\n    }\n\n    FILE *fp = fopen(&quot;titles.txt&quot;, &quot;w&quot;);\n\n    if (!fp)\n    {\n        perror(&quot;fopen&quot;);\n        return 1;\n    }\n\n    GumboOutput *output =\n        gumbo_parse(chunk.memory);\n\n    search_links(output-&gt;root, fp);\n\n    gumbo_destroy_output(\n        &amp;kGumboDefaultOptions,\n        output);\n\n    fclose(fp);\n\n    curl_easy_cleanup(curl);\n    curl_global_cleanup();\n\n    free(chunk.memory);\n\n    printf(&quot;saved to titles.txt\\n&quot;);\n\n    return 0;\n}\n\n<\/pre><\/div>\n\n\n<p>\u3053\u308c\u304f\u3089\u3044\u306a\u3089AI\u306b\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u4f5c\u3063\u3066\u8cb0\u308f\u306a\u304f\u3066\u3082\u3001curl\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u3001\u7d50\u679c\u306e\u30ea\u30b9\u30c8\u306ehtml\u3092\u30d5\u30a1\u30a4\u30eb\u306b\u4fdd\u5b58\u3057\u3066\u3001\u305d\u306ehtml\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u30bf\u30b0\u60c5\u5831\u3092\u624b\u304c\u304b\u308a\u306b\u30c7\u30fc\u30bf\u3092\u629c\u304d\u51fa\u3059\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u81ea\u5206\u3067\u66f8\u3044\u305f\u307b\u3046\u304c\u65e9\u305d\u3046\u3060\u3002<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>html\u30d5\u30a1\u30a4\u30eb\u306f\u3001\u3060\u3044\u305f\u3044\u3053\u3093\u306a\u5f62\u5f0f\u306e\u7e70\u308a\u8fd4\u3057\u306b\u306a\u3063\u3066\u3044\u308b\u3002(<a href=\"https:\/\/webcomics.jp\/list\/dm8hk\">\u30cb\u30b3\u30cb\u30b3\u6f2b\u753b\u306e\u307b\u3046\u306e\u30ea\u30b9\u30c8<\/a>)<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\t&lt;div class=&quot;entry&quot; data-comic-no=&quot;162038&quot;&gt;\n\t\t&lt;div class=&quot;entry-thumb&quot;&gt;\n\t\t\t&lt;a href=&quot;https:\/\/manga.nicovideo.jp\/comic\/66641&quot; target=&quot;_blank&quot;&gt;\n\t\t\t\t&lt;img src=&quot;.\/kako-list-1 - Web\u6f2b\u753b\u30a2\u30f3\u30c6\u30ca_files\/162038.jpg&quot; width=&quot;100&quot; height=&quot;100&quot; loading=&quot;lazy&quot; alt=&quot;\u8fd1\u757f\u5730\u65b9\u306e\u3042\u308b\u5834\u6240\u306b\u3064\u3044\u3066&quot;&gt;\n\t\t\t&lt;\/a&gt;\n\t\t&lt;\/div&gt;\n\n\t\t\t\t\t&lt;div class=&quot;entry-date&quot;&gt;\n\t\t\t\t17\u6642\u9593\u524d\t\t\t&lt;\/div&gt;\n\t\t\n\t\t&lt;div class=&quot;entry-title ellipsis1&quot;&gt;\n\t\t\t&lt;a href=&quot;https:\/\/manga.nicovideo.jp\/comic\/66641&quot; target=&quot;_blank&quot;&gt;\n\t\t\t\t\u8fd1\u757f\u5730\u65b9\u306e\u3042\u308b\u5834\u6240\u306b\u3064\u3044\u3066\t\t\t&lt;\/a&gt;\n\t\t&lt;\/div&gt;\n\n\t\t\n\t\t\t\t\t&lt;div class=&quot;entry-summary ellipsis2&quot;&gt;\n\t\t\t\t\u884c\u65b9\u4e0d\u660e\u306b\u306a\u3063\u305f\u53cb\u4eba\u30fb\u5c0f\u6ca2\u3002\u30aa\u30ab\u30eb\u30c8\u96d1\u8a8c\u306e\u7de8\u96c6\u8005\u3067\u3042\u3063\u305f\u5f7c\u306f\u3001\u5931\u8e2a\u3059\u308b\u524d\u306b\u300c\u25cf\u25cf\u25cf\u25cf\u25cf\u300d\u3068\u3044\u3046\u5730\u57df\u306b\u307e\u3064\u308f\u308b\u602a\u8ac7\u3092\u53d6\u6750\u3057\u3066\u3044\u305f\u3002\u904e\u53bb\u306e\u96d1\u8a8c\u8a18\u4e8b\u304b\u3089\u306e\u5f15\u7528\u3001\u8aad\u8005\u304b\u3089\u306e\u304a\u304b\u3057\u306a\u4f53\u9a13\u8ac7\u3001\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u63b2\u793a\u677f...\t\t\t&lt;\/div&gt;\n\t\t\n\t\t&lt;div class=&quot;entry-site&quot;&gt;\n\t\t\t&lt;a href=&quot;https:\/\/webcomics.jp\/seiga&quot;&gt;\n\t\t\t\t\u30cb\u30b3\u30cb\u30b3\u6f2b\u753b\t\t\t&lt;\/a&gt;\n\t\t&lt;\/div&gt;\n\n\t\t&lt;div class=&quot;entry-footer&quot;&gt;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t&lt;span class=&quot;entry-comment&quot;&gt;\n\t\t\t\t\t\t\t\t\t&lt;span class=&quot;hover-tip&quot;&gt;\n\t\t\t\t\t\t&lt;span class=&quot;hover-tip-popup hover-tip-popup-top-left&quot;&gt;\n\t\t\t\t\t\t\t&lt;span class=&quot;hover-tip-popup-block&quot;&gt;\n\t\t\t\t\t\t\t\t\u30b3\u30e1\u30f3\u30c8\u306f\u307e\u3060\u3042\u308a\u307e\u305b\u3093\n\t\t\t\t\t\t\t&lt;\/span&gt;\n\t\t\t\t\t\t&lt;\/span&gt;\n\t\t\t\t\t\t\u30b3\u30e1\u30f3\u30c8\n\t\t\t\t\t&lt;\/span&gt;\n\t\t\t\t\t\t\t&lt;\/span&gt;\n\t\t\t&lt;span class=&quot;entry-detail&quot;&gt;\n\t\t\t\t&lt;a href=&quot;https:\/\/webcomics.jp\/seiga\/66641&quot;&gt;\u8a73\u7d30\u30fb\u66f4\u65b0\u60c5\u5831&lt;\/a&gt;\n\t\t\t&lt;\/span&gt;\n\t\t&lt;\/div&gt;\n\t&lt;\/div&gt;\n\n<\/pre><\/div>\n\n\n<p>&#8220;entry-thumb&#8221;\u3068\u3044\u3046\u5358\u8a9e\u3092\u63a2\u3057\u3066\u3001\u305d\u306e\u6b21\u306e\u884c\u304b\u3089https\u3067\u59cb\u307e\u308bURL\u6587\u5b57\u5217\u3092\u53d6\u308a\u51fa\u3059\u51e6\u7406\u3092\u66f8\u3051\u3070\u3088\u3044\u3002\u5272\u3068\u7c21\u5358\u305d\u3046\u3060\u3002<\/p>\n\n\n\n<p>\u305d\u3057\u3066\u3001URL\u306e\u672b\u5c3e\u306b&#8221;new&#8221;\u3068\u3044\u3046\u306e\u3092\u4ed8\u3051\u308b\u3068\u6700\u65b0\u8a71\u3078\u306e\u30ea\u30f3\u30af\u306b\u306a\u308b\u3002<br>\u3055\u3089\u306b\u6f2b\u753b\u306e\u30bf\u30a4\u30c8\u30eb\u3068\u3001\u66f4\u65b0\u306e\u6642\u9593\u60c5\u5831\u3082\u53d6\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3002<\/p>\n\n\n\n<p>\u307e\u305a\u306f\u3053\u308c\u3089\u3092\u30d5\u30a1\u30a4\u30eb\u3068\u3057\u3066\u51fa\u529b\u3057\u3001\u305d\u306e\u3042\u3068\u3001\u5b9f\u969b\u306b\u6f2b\u753b\u3092\u95b2\u89a7\u3059\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u306f\u5225\u3067\u66f8\u3044\u3066\u307f\u3088\u3046\u3068\u601d\u3046\u3002<\/p>\n\n\n\n<p>\u305d\u3046\u3084\u3063\u3066\u5206\u89e3\u3057\u3066\u77ed\u3081\u306e\u30bd\u30d5\u30c8\u3092\u4f5c\u3063\u3066\u3044\u3051\u3070\u30011\u3064\u306e\u5927\u304d\u3044\u30bd\u30d5\u30c8\u3068\u3057\u3066\u6f2b\u753b\u66f4\u65b0\u30c1\u30a7\u30c3\u30af\uff06\u95b2\u89a7\u30a2\u30d7\u30ea\u3092\u4f5c\u308b\u3088\u308a\u3082\u7c21\u5358\u306b\u4f5c\u308c\u308b\u3060\u308d\u3046\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Web\u6f2b\u753b\u30a2\u30f3\u30c6\u30ca\u3068\u3044\u3046\u30b5\u30a4\u30c8\u3067\u4f5c\u3063\u305f\u81ea\u5206\u306e\u30ea\u30b9\u30c8\u3092\u8aad\u307f\u53d6\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u4f5c\u3063\u3066\u307f\u308b\u3002 ChatGPT\u306b\u805e\u3044\u3066\u307f\u305f\u3068\u3053\u308d\u3001\u6b21\u306e\u3088\u3046\u306a\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9\u304c\u51fa\u3066\u304d\u305f\u3002 libcurl\u3067\u30ea\u30b9\u30c8\u306eweb\u306e\u30da\u30fc\u30b8\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3001Gumbo [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,14],"tags":[],"_links":{"self":[{"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/91965"}],"collection":[{"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=91965"}],"version-history":[{"count":4,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/91965\/revisions"}],"predecessor-version":[{"id":91970,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/91965\/revisions\/91970"}],"wp:attachment":[{"href":"http:\/\/kako.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=91965"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=91965"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/kako.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=91965"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}