This commit is contained in:
Default
2025-04-15 16:33:25 +08:00
parent ccdae1e854
commit 5893a41166
23 changed files with 1686 additions and 1080 deletions

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74;
use app\task\crawler\zw74\page\Site;
use app\task\crawler\zw\Scheduler as ZwScheduler;
/**
* @mixin think\Model
*/
class Scheduler extends ZwScheduler
{
/**
* Undocumented function
*
* @return void
*/
public function init()
{
$this->intSlice = 8;
}
/**
* Undocumented function
*
* @return Site
*/
public function getSite()
{
if ($this->Site == NULL) {
$this->Site = new Site;
}
return $this->Site;
}
}

View File

@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74\page;
use app\task\crawler\zw\page\ChapterPage as ZwChapterPage;
class ChapterPage extends ZwChapterPage {}

View File

@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74\page;
use app\model\NovelModel;
use app\task\crawler\zw\page\LatestListPage as ZwLatestListPage;
class LatestListPage extends ZwLatestListPage {}

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74\page;
use app\task\crawler\zw\page\NovelPage as ZwNovelPage;
class NovelPage extends ZwNovelPage
{
/**
* 分析关联数据
*
* @return void
*/
public function getReletedNovel()
{
if (empty($this->arrRelatedNovel) || empty($this->arrForgeNovel)) {
$this->getQueryList()->find('.first_txt')->eq(0)->find("a")->map(function ($A) {
$strName = $A->text();
$strUri = $A->attr('href');
if (is_numeric(strpos($strUri, 'http'))) {
return;
}
$strPattern = '#^/\d+/(\d+)/$#';
if (is_numeric(strpos($strUri, 'info'))) {
$intNForgeId = (int)supperExtractFilename($strUri);
$this->arrForgeNovel[] = [
"n_forge_id" => $intNForgeId,
"n_forge_title" => $strName,
];
} elseif (preg_match($strPattern, $strUri, $arrMatches)) {
$intNSourceId = (int)$arrMatches[1];
$arrNovelInfo = $this->findOrCreateNovel($intNSourceId, $strName);
$this->arrRelatedNovel[] = [
"n_id" => $arrNovelInfo["n_id"],
"n_source_id" => $arrNovelInfo["n_source_id"],
"og_novel_book_name" => $arrNovelInfo["og_novel_book_name"],
];
}
});
}
}
}

View File

@@ -0,0 +1,152 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74\page;
use app\task\crawler\zw\page\Site as ZwSite;
use GuzzleHttp\Client;
/**
* @mixin think\Model
*/
class Site extends ZwSite
{
/**
* Undocumented variable
*
* @var string
*/
protected $strDomain = 'https://www.74zw.cc';
/**
* Undocumented variable
*
* @var string
*/
protected $strSiteCode = 'zw';
/**
* Undocumented function
*/
public function initClient()
{
$arrConfig = [
'http_version' => '1.1', // 强制用 HTTP/1.1,已有,保持
'base_uri' => $this->strDomain, // 基础域名,已有,保持
'http_errors' => false, // 不抛 HTTP 错误,已有,保持
'timeout' => 60, // 从 160 秒改为 60 秒
'connect_timeout' => 10, // 从 30 秒改为 10 秒
'curl' => [
CURLOPT_TCP_KEEPALIVE => 1, // 启用 TCP Keep-Alive已有保持
CURLOPT_TCP_KEEPIDLE => 120, // Keep-Alive 空闲时间
CURLOPT_TCP_KEEPINTVL => 60, // Keep-Alive 探测间隔
// CURLOPT_SSL_VERIFYPEER => true, // 验证 SSL已有保持
],
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0',
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language' => 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Referer' => $this->strDomain,
'Connection' => 'keep-alive',
'sec-ch-ua' => '"Microsoft Edge";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
'sec-ch-ua-mobile' => '?0',
'sec-ch-ua-platform' => '"Windows"',
'sec-fetch-dest' => 'document',
'sec-fetch-mode' => 'navigate',
'sec-fetch-site' => 'same-origin',
'sec-fetch-user' => '?1',
'upgrade-insecure-requests' => '1',
],
'pool_size' => 10,
'verify' => false,
];
$arrProxy = config('proxy');
if ($arrProxy['proxy_status']) {
$strCode = $arrProxy['proxy_code'];
$strProxyHost = $arrProxy['proxy_host'];
$strKey = $arrProxy['proxy_key'];
$strSecret = $arrProxy['proxy_secret'];
switch ($strCode) {
case 'XIONGMAO':
$intTime = time();
$strTxt = "orderno=" . $strKey . ",secret=" . $strSecret . ",timestamp=" . $intTime;
$strSign = strtoupper(md5($strTxt));
$strAuth = 'sign=' . $strSign . '&orderno=' . $strKey . '&timestamp=' . $intTime;
$arrConfig['proxy'] = $strProxyHost;
$arrConfig['headers']['Proxy-Authorization'] = $strAuth;
break;
case 'KUAI':
$arrConfig['proxy'] = $strProxyHost;
$arrConfig['curl'][CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
$arrConfig['curl'][CURLOPT_PROXYUSERPWD] = "$strKey:$strSecret";
break;
}
}
$this->Client = new Client($arrConfig);
}
/**
* Undocumented function
*
* @param int $intNSourceId
* @param int $intPage
* @return string
*/
public function getNovelPageUri($intNSourceId, $intPage): string
{
$intUriFirst = intdiv($intNSourceId, 1000);
$strUri = '';
if ($intPage == 0) {
$strUri = sprintf('/%s/%s/', $intUriFirst, $intNSourceId);
} else {
$strUri = sprintf('/book/%s/list%s.html', $intNSourceId, $intPage);
}
return $strUri;
}
/**
* Undocumented function
*
* @param object $Site
* @param string $strUri
* @return NovelPage
*/
public function getNovelPage($Site, $strUri)
{
return new NovelPage($Site, $strUri);
}
/**
* Undocumented function
*
* @param object $Site
* @param string $strUri
* @return ChapterPage
*/
public function getChapterPage($Site, $strUri)
{
return new ChapterPage($Site, $strUri);
}
/**
* Undocumented function
*
* @param object $Site
* @param string $strUri
* @return LatestListPage
*/
public function getLatestListPage($Site, $strUri)
{
return new LatestListPage($Site, $strUri);
}
}