ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

利用纯真IP库建立MySQL IP数据库:TaoToken统一Key通道下的查询接口搭建

利用纯真IP库建立MySQL IP数据库:TaoToken统一Key通道下的查询接口搭建 1. 纯真IP库导入MySQL到底难在哪从qqwry.dat到可查询ip数据库的完整链路做后台系统、风控日志、访问统计的时候经常需要把一个IP翻译成哪个省哪个市哪个运营商。纯真IP库qqwry.dat是国内用得比较久的一份离线数据体积小、查询快、不依赖外部接口很适合自建一个MySQL版的IP归属地数据库。但真正动手的人会发现坑不在下载而在解析和导入这两步qqwry.dat是二进制格式不能直接拿文本编辑器打开解析出来的记录有几十万条一次性生成SQL文件动辄五六十兆phpMyAdmin默认2M上限直接卡死再加上编码问题导入完发现地区名全是乱码。这篇就按能跟做的标准把整条链路走一遍先把qqwry.dat解析成结构化文本再建MySQL表然后分批生成SQL并导入最后写一个PHP查询接口。查询接口这一层我会用TaoToken的统一Key通道来补一个IP归属地模型解读的能力——比如把归属地结果丢给模型做风险描述或者让模型帮你把一批IP归类。TaoToken官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API入口是 https://taotoken.net/api 一个Key就能调多种模型省得为每个模型单独配一套鉴权。适合谁看会一点PHP和MySQL、想自己搭IP库的开发者被php.ini上传限制卡过的人以及想把IP查询和模型能力串起来做小工具的人。下面每一步都给命令和配置你照着改路径就能跑。2. 前置准备qqwry.dat解析工具与TaoToken统一Key通道配置先说数据来源。纯真IP库的官方发布渠道会定期更新qqwry.dat下载后是一个二进制文件通常二十多兆。你不能直接cat它需要用解析脚本按固定偏移量读取。网上有不少现成的PHP或Python解析类核心逻辑是文件头记录第一条和最后一条索引的偏移然后按起始IP、结束IP、记录偏移三段式读取索引区再跳到记录区取地区字符串。我这里给一个精简的PHP解析思路重点是把它输出成起始IP||结束IP||地区||详细地址这种用||分隔的文本方便后面转SQL。为什么用||因为地区名里可能带空格用空格分隔会切错字段。解析脚本跑完会生成一个几十兆的txt这一步别急着导入先确认编码。Windows下生成的文本默认可能是GBK导入MySQL前建议统一转成UTF-8否则查询出来是乱码。可以用iconv -f GBK -t UTF-8 ip.txt ip_utf8.txt或者在PHP里用mb_convert_encoding。然后是TaoToken这一侧。它的定位是统一Key通道你注册后拿到一个API Key就能通过同一个Base URL调用不同模型不用为每个厂商单独申请。对咱们这个场景来说用途是给IP查询接口加一层模型解读——比如查询到某个IP属于某地某运营商可以让模型生成一句风险提示或者批量把IP按地区归类。配置上你只需要三样东西Base URL填https://taotoken.net/apiKey填你控制台生成的密钥Model ID按你需要的模型填。控制台在 https://taotoken.net/console Key管理在 https://taotoken.net/api-keys 文档在 https://taotoken.net/doc 。如果你后面要做长期编码或Agent类任务可以看Coding Plan https://taotoken.net/coding-plan 。注意TaoToken是模型调用通道不替代你的MySQL和PHP环境。IP库解析、建表、导入这些还是在你自己的服务器上完成TaoToken只负责查询结果之后的模型调用这一段。3. 可复制配置建表SQL、dat解析脚本与php.ini参数调整这一节是核心给全可复制的片段。先建库建表。表结构沿用经典的ipstart/ipend整数区间方案查询时把用户IP转成整数用BETWEEN或 AND 定位。引擎用MyISAM还是InnoDB都行MyISAM在这个只读场景下查询略快但InnoDB更稳我建议InnoDB。CREATE DATABASE IF NOT EXISTS ip_data DEFAULT CHARACTER SET utf8mb4; USE ip_data; CREATE TABLE ip_data ( ipstart INT UNSIGNED NOT NULL, ipend INT UNSIGNED NOT NULL, region VARCHAR(50) NOT NULL, address VARCHAR(100) NOT NULL, PRIMARY KEY (ipstart, ipend), KEY idx_ipend (ipend) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;注意原方案里region和address长度偏小实际数据里详细地址可能超过100字符建议address给到VARCHAR(150)。主键用(ipstart, ipend)联合主键查询走ipstart ? AND ipend ?能命中索引。接着是php.ini。导入大文件时phpMyAdmin受三个参数限制memory_limit、upload_max_filesize、post_max_size。默认upload_max_filesize2M所以你生成50M的SQL根本传不上去。改法memory_limit 256M upload_max_filesize 128M post_max_size 128M max_execution_time 600改完重启PHP服务。但即便改了phpMyAdmin导入几十兆还是容易超时所以更稳的做法是分批生成SQL每批控制在2M左右或者直接用命令行source导入。下面是解析脚本把qqwry.dat转成||分隔的文本。这里给的是读取已解析文本再转SQL的思路dat二进制解析部分用现成类库即可?php // ip_to_sql.php // 输入ip_utf8.txt每行格式 起始IP||结束IP||地区||详细地址 // 输出ip_1.sql, ip_2.sql ... 每个约2M function ip2long_safe($ip) { $long ip2long($ip); return $long false ? 0 : sprintf(%u, $long); } $lines file(ip_utf8.txt, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $i 1; $len 0; $fp fopen(ip_{$i}.sql, w); fwrite($fp, USE ip_data;\n); foreach ($lines as $line) { $parts explode(||, $line); if (count($parts) 4) continue; $start ip2long_safe(trim($parts[0])); $end ip2long_safe(trim($parts[1])); $region addslashes(trim($parts[2])); $address addslashes(trim($parts[3])); $sql INSERT INTO ip_data (ipstart, ipend, region, address) VALUES . ({$start}, {$end}, {$region}, {$address});\n; fwrite($fp, $sql); $len strlen($sql); if ($len 2097152) { fclose($fp); $i; $len 0; $fp fopen(ip_{$i}.sql, w); fwrite($fp, USE ip_data;\n); } } fclose($fp); echo 生成完成共 {$i} 个文件\n;跑完你会得到一批ip_N.sql。导入有两种方式。图形界面就在phpMyAdmin里逐个导入命令行更快mysql -u root -p ip_data ip_1.sql mysql -u root -p ip_data ip_2.sql # ... 依次导入或者进MySQL后一次性sourceUSE ip_data; SOURCE /path/to/ip_all.sql;四十多万条数据命令行导入通常几分钟到十几分钟取决于磁盘。导入完用SELECT COUNT(*) FROM ip_data;确认条数。TaoToken的配置片段如果你用PHP调用可以放一个config.php?php return [ base_url https://taotoken.net/api, api_key getenv(TAOTOKEN_API_KEY), model your-model-id, ];Key不要硬编码进代码用环境变量或配置文件并加权限控制。Key在 https://taotoken.net/api-keys 生成。4. 验证请求PHP查询接口 curl实测IP归属地返回结果表建好、数据导入后写查询接口。核心是把用户IP转成整数然后查区间?php // ip_query.php header(Content-Type: application/json; charsetutf-8); function ip2long_safe($ip) { $long ip2long($ip); return $long false ? 0 : sprintf(%u, $long); } $ip $_GET[ip] ?? ; if (!filter_var($ip, FILTER_VALIDATE_IP)) { echo json_encode([code 400, msg IP格式不正确]); exit; } $pdo new PDO(mysql:host127.0.0.1;dbnameip_data;charsetutf8mb4, root, yourpass); $pdo-setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $longIp ip2long_safe($ip); $stmt $pdo-prepare( SELECT region, address FROM ip_data WHERE ipstart :ip AND ipend :ip LIMIT 1 ); $stmt-execute([:ip $longIp]); $row $stmt-fetch(PDO::FETCH_ASSOC); if (!$row) { echo json_encode([code 404, msg 未找到归属地, ip $ip]); exit; } echo json_encode([ code 0, ip $ip, region $row[region], address $row[address], ], JSON_UNESCAPED_UNICODE);启动PHP内置服务器测试php -S 0.0.0.0:8080然后curl验证curl http://127.0.0.1:8080/ip_query.php?ip114.114.114.114正常返回类似{code:0,ip:114.114.114.114,region:江苏省南京市,address:电信}如果查不到先确认ipstart/ipend是不是无符号整数。ip2long在32位系统上会返回负数所以脚本里用了sprintf(%u, ...)转无符号。另外确认导入的数据没有因为编码问题变成乱码SELECT region FROM ip_data LIMIT 5;看一眼。接下来接TaoToken做模型解读。比如查询到归属地后把结果拼成prompt发给模型让它生成一句风险描述?php // ip_ai.php $config require config.php; $ip $_GET[ip] ?? ; $region $_GET[region] ?? ; $address $_GET[address] ?? ; $payload [ model $config[model], messages [ [role system, content 你是一个网络安全助手用一句话描述该IP的归属风险。], [role user, content IP: {$ip}归属地: {$region} {$address}], ], ]; $ch curl_init($config[base_url] . /v1/chat/completions); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER true, CURLOPT_POST true, CURLOPT_HTTPHEADER [ Content-Type: application/json, Authorization: Bearer . $config[api_key], ], CURLOPT_POSTFIELDS json_encode($payload), ]); $resp curl_exec($ch); curl_close($ch); echo $resp;curl验证模型调用curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d {model:your-model-id,messages:[{role:user,content:IP 114.114.114.114 归属江苏南京电信一句话风险描述}]}返回里能看到choices[0].message.content就是模型输出。到这一步IP查询模型解读的链路就通了。想直接在网页里试模型效果可以用模型对话入口 https://taotoken.net/model-chat 。5. 常见报错排查401、local proxy failed、reading choices与OAuth问题这一节按真实报错来对。第一个高频是401 Unauthorized。原因通常是Key没带、带错、或者带了多余空格。检查Authorization: Bearer xxx这一行Bearer后面一个空格再跟Key。如果你把Key写在config.php里确认没有把换行符带进去。另外Key可能被禁用或额度用尽去 https://taotoken.net/api-keys 看一眼状态。第二个是local proxy failed或连接超时。这类报错一般出在网络层你的服务器出网被限制、DNS解析不到、或者本地配了不该配的转发。先curl -v https://taotoken.net/api看握手是否成功。如果是内网机器确认出口策略允许访问。注意不要在任何环节引入不合规的网络工具正常的企业出网配置即可。第三个是reading choices相关报错比如cannot read property choices of undefined。这通常说明返回体不是预期的JSON可能是鉴权失败返回了错误对象或者模型ID写错导致返回了错误结构。打印原始返回var_dump($resp)看error字段。常见的是Model ID拼错或者请求体里messages格式不对。第四个是OAuth类问题。如果你用的是某些需要OAuth授权的客户端比如Claude Code这类报错可能提示token过期或授权失败。这类场景建议直接用API Key方式Base URL填https://taotoken.net/apiKey填控制台生成的密钥Model ID填对应模型。Claude Code接入可以参考文档 https://taotoken.net/doc Claude Code专用说明在 https://taotoken.net/claude-code 。还有一个容易忽略的MySQL导入时ERROR 1153 (08S01): Got a packet bigger than max_allowed_packet bytes。这是MySQL服务端的包大小限制不是php.ini。改my.cnf里的max_allowed_packet64M重启MySQL。或者继续用2M分批导入最稳。排查顺序建议先确认MySQL里数据条数对不对再确认PHP查询接口单独能返回最后才接TaoToken。分层排查比一上来就怀疑模型通道高效得多。6. 把IP查询接进你的系统TaoToken API Key与接入文档入口整条链路跑通后你可以把它封装成一个内部服务定时更新qqwry.dat、重新解析导入、对外暴露/ip_query接口。查询结果可以缓存到Redis减少MySQL压力。模型解读那层按需调用不必每次查询都走模型可以只对高风险IP或批量任务触发。TaoToken这边日常调用用API Key就够了入口在 https://taotoken.net/api-keys 。接入细节、参数说明、错误码都在文档里 https://taotoken.net/doc 。如果你要把它接进编码工具或Agent流程Coding Plan更适合长期高频场景 https://taotoken.net/coding-plan 。想先直观感受模型输出用模型对话页面试几句 https://taotoken.net/model-chat 。控制台统一管理Key和用量 https://taotoken.net/console 。最后给个实用建议qqwry.dat更新频率不固定建议写个定时任务每月检查一次新版本解析导入前先备份旧表用RENAME TABLE做原子切换避免查询接口在导入期间读到半截数据。导入时如果数据量大关掉autocommit、批量INSERT速度会明显快于逐条提交。这些细节踩过一次就记住了。
返回列表