前言
Wget.Fit 于2023.10.24停服了,但是把网站的原理以及源码发出来了,我给搬运过来了,有兴趣的可以自己按照教程尝试搭建一个自己的扒站程序。
00x01
wget首先会对输入的url进行解析并提取出其中的协议路径等信息,
通过该信息wget建立与服务器的连接并发送请求
服务器收到请求报文后会返回相应的响应报文。
wget会将其解析并响应,如请求成功,
服务器会将资源返回至wget,wget根据响应信息,将资源递归保存至本地。
00x02
windows版本下的wget调用
@echo off & cd /d %~dp0 mode con cols=100 call :showLogo pause exit :showLogo title Wget downloads tool 2.0-Wget.fit color 80 mode con cols=72 lines=22 if not exist .outlogo ( echo IF9fICAgICAgICAgIF9fICAgICAgICBfICAgICBfX19fX18gXyBfICAgX19fICAgIF9fXyAgCiBcIFwgICAgICAgIC8gLyAgICAgICB8IHwgICB8ICBfX19fKF8pIHwgfF9fIFwgIC8gXyBcIAogIFwgXCAgL1wgIC8gL18gXyAgX19ffCB8XyAgfCB8X18gICBffCB8XyAgICkgfHwgfCB8IHwKICAgXCBcLyAgXC8gLyBfYCB8LyBfIFwgX198IHwgIF9ffCB8IHwgX198IC8gLyB8IHwgfCB8CiAgICBcICAvXCAgLyAoX3wgfCAgX18vIHxfIF98IHwgICAgfCB8IHxfIC8gL18gfCB8X3wgfAogICAgIFwvICBcLyBcX18sIHxcX19ffFxfXyhfKV98ICAgIHxffFxfX3xfX19fKF8pX19fLyAKICAgICAgICAgICAgIF9fLyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIHxfX18vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA==>.logo certutil -decode .logo .outlogo>nul del .logo ) type .outlogo echo. echo The principle of this tool is very simple, is to apply wget with bat echo Official website: www.wget.fit echo===================================================================== set /p a=Url(http/https): color 2f mode con cols=80 lines=25 wget.exe -U‘Mozilla/5.0 -r -p -np -k --no-check-certificate %a% cls title Wget downloads tool 2.0-Wget.fit echo The task is complete. Press Enter to exit echo. &pause >nul
运行如下图
00x02
这是wget.fit网站的文件目录
│ api.php api接口 │ common.php 网站全局文件 │ Config.php 网站核心文件 │ index.php 网站主页 │ ssh.class.php ssh认证文件 │ wget_site.sh wget请求文件 └─work 网站预览目录
从网站主页说起
网站主页仅用于请求api.php
if (isset($_POST['url'])) { $url = $_POST['url']; $email = $_POST['email']; if (get_code($url) != 200) { exit(json_encode(array('code' => '-1', 'msg' => '爬取失败,请检查网址是否正确!'),JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); } $preg = "/^http(s)?:\/\/.+/"; if(!preg_match($preg,$url)){ exit(json_encode(array('code' => '-1', 'msg' => '域名请带上协议头!如( http:// 或 https:// )'),JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); } $file = parse_url($url)['host'].'-'.mt_rand(10000,99999); $ssh = new Components_Ssh($host, $user, $pass, $port, $log); $ssh->cmd("bash /www/wwwroot/wget.fit/wget_site.sh {$url} {$file} >/dev/null && echo \"success\""); if(file_exists('./down/'.$file.'.zip')) { $content='你在Wget.fit提交的扒站请求已结束,下载链接:wget.fit/down/' . $file . '.zip'; $wz=$smtpapi."?adress=".$email."&isHTML=false&title=Wget.fit爬取成功&content=".$content; file_get_contents($wz); exit(json_encode(array('code' => '1', 'msg' => '<center><img src="./assets/simple/img/wget.jpg" width="50%" ></center>', 'down' => 'http://wget.fit/down/' . $file . '.zip', 'yulan' => 'http://wget.fit/work/' . $file . '/' . parse_url($url)['host']),JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); } else { exit(json_encode(array('code' => '-1', 'msg' => '爬取失败!'),JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); } } else { function trans_byte($byte) { $KB = 1024; $MB = 1024 * $KB; $GB = 1024 * $MB; $TB = 1024 * $GB; if ($byte < $KB) { return $byte . "B"; } elseif ($byte < $MB) { return round($byte / $KB, 2) . "KB"; } elseif ($byte < $GB) { return round($byte / $MB, 2) . "MB"; } elseif ($byte < $TB) { return round($byte / $GB, 2) . "GB"; } else { return round($byte / $TB, 2) . "TB"; } } $list = glob('./down/*.zip'); $count = count($list); $page_num = isset($_GET['limit'])?$_GET['limit']:10; $pages = ceil($count / $page_num); $page = isset($_GET['page'])? $_GET['page']:1; $startpos = ($page - 1)*$page_num; $json['code'] = '0'; $json['data'] = $arr; exit(json_encode($json,JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); } function get_code($url){ $ch = curl_init(); $timeout = 3; curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch,CURLOPT_URL,$url); curl_exec($ch); return $httpcode = curl_getinfo($ch,CURLINFO_HTTP_CODE); curl_close($ch); }
下面的代码段包含了两个函数和一些变量:
trans_byte 函数用于将字节数转换为更容易阅读的格式,如KB,MB,GB,TB等。 $list 变量通过 glob 函数获取指定目录下的所有ZIP文件的文件名,并存储在一个数组中。 $count 变量用于存储ZIP文件的数量。 $page_num 从GET请求参数中获取,用于指定每页显示的ZIP文件数量。 $pages 计算总页数,以便进行分页显示。 $page 从GET请求参数中获取,指示当前页数。 $startpos 用于计算分页的起始位置。 get_code 函数用于检查指定URL的HTTP响应代码。它使用CURL来执行HTTP请求,获取响应代码,并返回它。
以下是对这段代码的注释:
if (isset($_POST['url'])) { // 检查是否有POST请求参数 'url' $url = $_POST['url']; $email = $_POST['email']; // 获取POST请求中的URL和电子邮件地址 if (get_code($url) != 200) { // 使用 get_code 函数检查指定URL的HTTP响应代码是否不等于200 exit(json_encode(array('code' => '-1', 'msg' => '爬取失败,请检查网址是否正确!'),JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); // 如果响应代码不等于200,返回一个JSON响应,指示爬取失败 } $preg = "/^http(s)?:\/\/.+/"; if(!preg_match($preg, $url)){ // 使用正则表达式检查URL是否以"http://"或"https://"开头 exit(json_encode(array('code' => '-1', 'msg' => '域名请带上协议头!如( http:// 或 https:// )'),JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); // 如果URL没有协议头,返回一个JSON响应,提醒用户添加协议头 } $file = parse_url($url)['host'].'-'.mt_rand(10000,99999); // 生成一个随机文件名,包括URL的主机名和一个随机数 $ssh = new Components_Ssh($host, $user, $pass, $port, $log); // 创建SSH连接对象 $ssh->cmd("bash /www/wwwroot/wget.fit/wget_site.sh {$url} {$file} >/dev/null && echo \"success\""); // 在服务器上执行bash命令,执行爬取操作 if(file_exists('./down/'.$file.'.zip')) { // 如果爬取成功并且文件存在 $content='你在Wget.fit提交的扒站请求已结束,下载链接:wget.fit/down/' . $file . '.zip'; $wz=$smtpapi."?adress=".$email."&isHTML=false&title=Wget.fit爬取成功&content=".$content; file_get_contents($wz); // 发送包含下载链接的消息到指定的电子邮件地址 exit(json_encode(array('code' => '1', 'msg' => '<center><img src="./assets/simple/img/wget.jpg" width="50%" ></center>', 'down' => 'http://wget.fit/down/' . $file . '.zip', 'yulan' => 'http://wget.fit/work/' . $file . '/' . parse_url($url)['host']),JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); // 返回一个JSON响应,指示爬取成功,并包含相关信息和链接 } else { exit(json_encode(array('code' => '-1', 'msg' => '爬取失败!'),JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); // 如果爬取失败,返回一个JSON响应 } } else { // 如果没有接收到 'url' 参数 function trans_byte($byte) { // 定义一个函数,用于将字节数转换为更易读的格式 $KB = 1024; $MB = 1024 * $KB; $GB = 1024 * $MB; $TB = 1024 * $GB; if ($byte < $KB) { return $byte . "B"; } elseif ($byte < $MB) { return round($byte / $KB, 2) . "KB"; } elseif ($byte < $GB) { return round($byte / $MB, 2) . "MB"; } elseif ($byte < $TB) { return round($byte / $GB, 2) . "GB"; } else { return round($byte / $TB, 2) . "TB"; } } $list = glob('./down/*.zip'); $count = count($list); // 获取指定目录下的ZIP文件列表和文件数量 $page_num = isset($_GET['limit'])?$_GET['limit']:10; // 获取每页显示的ZIP文件数量,如果未指定则默认为10 $pages = ceil($count / $page_num); // 计算总页数 $page = isset($_GET['page'])? $_GET['page']:1; // 获取当前页数,如果未指定则默认为第一页 $startpos = ($page - 1)*$page_num; // 计算分页的起始位置 $json['code'] = '0'; $json['data'] = $arr; // 构建JSON响应 exit(json_encode($json,JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT)); } function get_code($url){ $ch = curl_init(); $timeout = 3; curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch,CURLOPT_URL,$url); curl_exec($ch); return $httpcode = curl_getinfo($ch,CURLINFO_HTTP_CODE); curl_close($ch); }
进入下一个文件:ssh_class.php
这是一个PHP类 Components_Ssh,它用于建立SSH连接和执行远程命令。以下是对这个类的代码注释:
<?php class Components_Ssh { private $host; // SSH服务器主机名 private $user; // SSH登录用户名 private $pass; // SSH登录密码 private $port; // SSH服务器端口 private $conn = false; // SSH连接状态 private $error; // SSH连接错误信息 private $stream; // SSH执行命令的流 private $stream_timeout = 100; // SSH执行命令的超时时间 private $log; // 日志信息 private $lastLog; // 最后一条日志 private $sLog; // 服务器日志记录标志 public function __construct ( $host, $user, $pass, $port, $serverLog ) { // 构造函数,接收SSH连接所需的参数 $this->host = $host; $this->user = $user; $this->pass = $pass; $this->port = $port; $this->sLog = $serverLog; if ( $this->connect ()->authenticate () ) { return true; } } public function isConnected () { // 检查SSH连接状态 return ( boolean ) $this->conn; } public function __get ( $name ) { // 获取类的属性 return $this->$name; } public function connect () { // 建立SSH连接 $this->logAction ( "正在链接 -> {$this->host}" ); if ( $this->conn = ssh2_connect ( $this->host, $this->port ) ) { return $this; } $this->logAction ( "链接失败 -> {$this->host}" ); //exit ( "Unable to connect to {$this->host}" ); } public function authenticate () { // SSH认证 $this->logAction ( "正在认证 -> {$this->host}" ); if ( ssh2_auth_password ( $this->conn, $this->user, $this->pass ) ) { return $this; } $this->logAction ( "认证失败 -> {$this->host} failed" ); //exit ( "Unable to authenticate to {$this->host}" ); } public function cmd ( $cmd, $returnOutput = false ) { // 执行SSH命令 $this->logAction ( "执行命令 -> $cmd" ); $this->stream = ssh2_exec ( $this->conn, $cmd ); if ( FALSE === $this->stream ) { $this->logAction ( "执行失败 -> $cmd" ); //exit ( "Unable to execute command '$cmd'" ); } $this->logAction ( "执行成功 -> $cmd" ); stream_set_blocking ( $this->stream, true ); stream_set_timeout ( $this->stream, $this->stream_timeout ); $this->lastLog = stream_get_contents ( $this->stream ); $this->logAction ( "命令输出 -> [$cmd]:{$this->lastLog}" ); fclose ( $this->stream ); $this->log .= $this->lastLog . "\n"; return ( $returnOutput ) ? $this->lastLog : $this; } public function shellCmd ( $cmds = array () ) { // 在虚拟终端中执行SSH命令 $this->logAction ( "虚拟终端 -> 终端已打开" ); $this->shellStream = ssh2_shell ( $this->conn ); sleep ( 1 ); $out = ''; while ( $line = fgets ( $this->shellStream ) ) { $out .= $line; } $this->logAction ( "虚拟终端 -> [输出]:$out" ); foreach ( $cmds as $cmd ) { $out = ''; $this->logAction ( "执行命令 -> $cmd" ); fwrite ( $this->shellStream, "$cmd" . PHP_EOL ); sleep ( 1 ); while ( $line = fgets ( $this->shellStream ) ) { $out .= $line; sleep ( 1 ); } $this->logAction ( "命令输出 -> [$cmd]:$out" ); } $this->logAction ( "虚拟终端 -> 终端已关闭" ); fclose ( $this->shellStream ); } public function getLastOutput () { // 获取最后一次SSH命令的输出 return $this->lastLog; } public function getOutput () { // 获取所有SSH命令的输出 return $this->log; } public function disconnect () { // 断开SSH连接 $this->logAction ( "正在断开 -> {$this->host}" ); // 如果有断开函数,调用它 if ( function_exists ( 'ssh2_disconnect' ) ) { ssh2_disconnect ( $this->conn ); } else { // 如果没有断开函数,关闭连接并取消变量 @fclose ( $this->conn ); $this->conn = false; } // 总是返回NULL return NULL; } public function logAction ( $message ) { // 记录日志 if ( $this->sLog == 'true' ) { $this->lastLog = $this->log; $this->log = $message; //echo $message .'<br>'; } } }
这个类主要用于SSH连接和执行命令,还有日志记录功能。
wget_site.sh
#!/bin/sh wget -r -p -np -k -P /www/wwwroot/wget.fit/work/$2 $1 cp /www/wwwroot/wget.fit/readme.txt /www/wwwroot/wget.fit/work/$2/readme.txt cd /www/wwwroot/wget.fit/work/$2/ zip -r $2.zip ./ mv $2.zip /www/wwwroot/wget.fit/down rm -rf /www/wwwroot/wget.fit/work/$2
以下是对这段Shell脚本代码的注释:
bash #!/bin/sh # 上一行指定了脚本使用的Shell,这里是Bash。 # 使用wget命令下载指定URL的内容,并进行以下操作: wget -r -p -np -k -P /www/wwwroot/wget.fit/work/$2 $1 # -r: 递归下载整个目录 # -p: 下载所有页面相关资源 # -np: 不遍历父目录 # -k: 将HTML文件中的链接转换为本地链接 # -P /www/wwwroot/wget.fit/work/$2: 指定下载文件的存储路径,$2 是第二个参数,通常是一个文件夹名。 # 复制readme.txt文件到下载目录下 cp /www/wwwroot/wget.fit/readme.txt /www/wwwroot/wget.fit/work/$2/readme.txt # 进入下载目录 cd /www/wwwroot/wget.fit/work/$2/ # 压缩下载的文件和目录为一个ZIP文件 zip -r $2.zip ./ # $2 是第二个参数,通常是一个文件夹名,这将创建一个以文件夹名命名的ZIP文件。 # 移动ZIP文件到下载目录 mv $2.zip /www/wwwroot/wget.fit/down # 删除下载工作目录及其内容 .rm -rf /www/wwwroot/wget.fit/work/$2 用于递归删除目录及其内容。
总结:这个脚本首先使用wget命令下载指定URL的内容到指定目录,然后将readme.txt文件复制到下载目录,接着将下载目录中的内容压缩为ZIP文件,最后将ZIP文件移动到另一个目录,.rm -rf /www/wwwroot/wget.fit/work/$2是故意写错的,为了留下文件预览。
至此一个属于自己的扒站平台搭建成功。
「小礼物走一走?华子可乐来一个!」
还没有人赞赏,支持一下吧
哇~真是太棒了 感谢大佬支持
下载说明:
1.本站资源都是白菜价出售,同样的东西,我们不卖几百,也不卖几十,甚至才卖几块钱,一个永久VIP能下载全站会员专属源码了,所以单独购买也好,会员也好均不提供相关技术服务。
2.如果源码下载地址失效请 提交留言(点击我)进行补发。
3.本站所有资源仅用于学习及研究使用,请必须在24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担。资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您权益请联系本站删除!
4.本站站内提供的所有可下载资源(软件等等)本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发);但本网站不能保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug;同时本站用户必须明白,【晓梦云】对提供下载的软件等不拥有任何权利(本站原创和特约原创作者除外),其版权归该资源的合法拥有者所有。
5.请您认真阅读上述内容,购买即以为着您同意上述内容。
晓梦云资源网 » Wget扒站原理与写一条在线扒站接口源码