Oracle 11g R2中如何通过DBMS_OUTPUT从HTML查询结果提取指定值
Oracle 11g R2 提取HTML指定值的实现方案
核心实现逻辑
- 解决原脚本的缓冲区截断问题:原脚本每次按4000字符分段读取响应,目标标题很可能被拆分到两个相邻的读取块中,导致匹配失效,需先把全量HTML响应拼接为CLOB变量存储,再做文本匹配
- 通过Oracle内置正则函数定位目标文本:匹配HTML中
<center>标签包裹的标题内容,自动剥离冗余标签,直接取出目标值 - 编码适配:目标值中的
á是页面本身的编码显示结果,按原编码读取响应即可,无需额外转码
具体代码修改点
- 新增CLOB类型变量存储全量HTML响应内容,避免大页面读取截断
- 替换原循环读取时直接输出分段内容的逻辑,改为逐段拼接全量响应
- 全量内容读取完成后,用正则匹配定位目标文本
- 仅输出匹配到的目标值,不输出其他冗余HTML内容
- 修正原脚本中请求头多带多余空格的语法问题
修改后的完整PL/SQL脚本
declare req utl_http.req; res utl_http.resp; v_url varchar2(4000) := 'http://www.sefaz.ba.gov.br/scripts/cadastro/cadastroBa/result.asp'; v_post_content varchar2(4000) := 'CGC=13504675000110&B1=CNPJ++-%3E&CPF=&IE='; v_full_html clob; -- 存储全量响应内容 v_read_buffer varchar2(32767); v_target_result varchar2(4000); begin -- 初始化POST请求 req := utl_http.begin_request(v_url, 'POST','HTTP/1.1'); utl_http.set_header(req, 'content-type', 'application/x-www-form-urlencoded'); utl_http.set_header(req, 'Content-Length', length(v_post_content)); utl_http.write_text(req, v_post_content); -- 获取响应 res := utl_http.get_response(req); dbms_lob.createtemporary(v_full_html, true); -- 逐段读取并拼接全量HTML begin loop utl_http.read_text(res, v_read_buffer, 32767); dbms_lob.append(v_full_html, v_read_buffer); end loop; exception when utl_http.end_of_body then null; end; utl_http.end_response(res); -- 正则匹配提取目标值:兼容标签间的空格、换行、大小写差异 v_target_result := regexp_substr( v_full_html, '<center>\s*(.*?)\s*</center>', 1, 1, 'inm', -- 匹配模式:i=忽略大小写,n=点号匹配换行,m=多行匹配 1 -- 返回第一个捕获组的文本内容 ); -- 仅输出提取到的目标值 dbms_output.put_line(v_target_result); -- 清理临时CLOB资源 dbms_lob.freetemporary(v_full_html); end;
注意事项
- 11g R2环境下需先为执行脚本的数据库用户授予
UTL_HTTP执行权限、以及外网访问的ACL权限,否则会触发权限报错 - 正则规则适配非规范HTML格式,自动忽略标签间的多余空格、换行,不会匹配到其他无关内容
内容的提问来源于stack exchange,提问作者Mateus Ribeiro
相关产品推荐
相关产品推荐

