Wget扒站原理与写一条在线扒站接口源码

前言

Wget.Fit 于2023.10.24停服了,但是把网站的原理以及源码发出来了,我给搬运过来了,有兴趣的可以自己按照教程尝试搭建一个自己的扒站程序。

00x01

wget首先会对输入的url进行解析并提取出其中的协议路径等信息,
通过该信息wget建立与服务器的连接并发送请求
服务器收到请求报文后会返回相应的响应报文。
wget会将其解析并响应,如请求成功,
服务器会将资源返回至wget,wget根据响应信息,将资源递归保存至本地。
00x02
windows版本下的wget调用

Wget扒站原理与写一条在线扒站接口源码,653e449490567.png,扒站,源码,Wget,第1张

@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

运行如下图

Wget扒站原理与写一条在线扒站接口源码,653e449874c13.png,扒站,源码,Wget,第2张

00x02

Wget扒站原理与写一条在线扒站接口源码,653e449870776.png,扒站,源码,Wget,第3张

这是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扒站原理与写一条在线扒站接口源码

发表评论

您需要后才能发表评论

晓梦云资源站、分享更多优质有趣的源码!

特权介绍 留言处理