如何修改C语言Lexbor代码获取完整带值td标签并存入缓冲区
基于Lexbor库的HTML目标td元素完整内容抓取方案
实现原理
Lexbor库自带DOM元素序列化接口,不需要手动拼接标签结构,可直接将定位到的td元素(含开标签、内部文本、闭合标签)完整输出到内存缓冲区,性能损耗极低,符合保留Lexbor依赖保障抓取效率的要求。
完整代码示例
#include <stdio.h> #include <string.h> #include <lexbor/html/html.h> #include <lexbor/dom/dom.h> int main(int argc, const char *argv[]) { // 待解析的HTML示例内容,可替换为实际抓取的HTML内容 const lxb_char_t html[] = "<table><tr><th id=\"choose-this-header\">数值</th><td header=\"choose-this-header\">0.7</td></tr></table>"; // 1. 初始化HTML解析器 lxb_html_document_t *document = lxb_html_document_create(); lxb_status_t status = lxb_html_document_parse(document, html, sizeof(html) - 1); if (status != LXB_STATUS_OK) { printf("HTML解析失败\n"); return EXIT_FAILURE; } // 2. 遍历DOM查找所有header属性为choose-this-header的td元素 lxb_dom_collection_t *collection = lxb_dom_collection_make(&document->dom_document, 16); if (collection == NULL) { printf("集合创建失败\n"); lxb_html_document_destroy(document); return EXIT_FAILURE; } // 获取所有td元素 status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document), collection, (const lxb_char_t *)"td", 2); if (status != LXB_STATUS_OK) { printf("获取td元素失败\n"); lxb_dom_collection_destroy(collection, true); lxb_html_document_destroy(document); return EXIT_FAILURE; } for (size_t i = 0; i < lxb_dom_collection_length(collection); i++) { lxb_dom_element_t *td_elem = lxb_dom_collection_element(collection, i); // 校验header属性值 const lxb_char_t *header_val = lxb_dom_element_get_attribute(td_elem, (const lxb_char_t *)"header", 6, NULL); if (header_val != NULL && strcmp((const char *)header_val, "choose-this-header") == 0) { // 3. 序列化完整td元素到缓冲区 lxb_char_t *serialized_buf; size_t buf_len; serialized_buf = lxb_html_serialize_str(lxb_dom_interface_node(td_elem), &buf_len); if (serialized_buf == NULL) { printf("td序列化失败\n"); continue; } // serialized_buf即为完整的td标签内容,可复制到自定义缓冲区做后续处理 printf("完整td内容:%.*s\n", (int)buf_len, serialized_buf); // 可选方案:不需要完整标签的话可直接提取内部文本,省略序列化步骤性能更高 lxb_dom_node_t *text_node = lxb_dom_node_first_child(lxb_dom_interface_node(td_elem)); if (text_node != NULL && text_node->type == LXB_DOM_NODE_TYPE_TEXT) { printf("td内文本值:%s\n", lxb_dom_node_text_content(text_node, NULL)); } // 释放序列化生成的缓冲区 lexbor_free(serialized_buf); } } // 释放全局资源 lxb_dom_collection_destroy(collection, true); lxb_html_document_destroy(document); return EXIT_SUCCESS; }
编译运行说明
- 前置依赖安装:
sudo apt install liblexbor-dev - 编译指令:
gcc step_one.c -llexbor -o step_one - 运行指令:
./step_one
注意事项
- 序列化接口返回的缓冲区需要手动调用
lexbor_free释放,避免内存泄漏 - 若是仅需要td内部的文本值,直接提取子文本节点即可,不需要走序列化流程,抓取效率更高
内容的提问来源于stack exchange,提问作者p.luck
相关产品推荐
相关产品推荐

