Compare commits

...

5 Commits

Author SHA1 Message Date
www
b764e7555d fix(seo): normalize GPT sitemap push URLs 2026-05-09 11:10:00 +08:00
Your Name
04242363a8 debug 2026-04-23 18:12:23 +08:00
Your Name
c1ac050c6a debug 2026-04-22 13:39:28 +08:00
Your Name
b943ea2ab7 debug 2026-04-21 01:02:21 +08:00
root
e568577ce0 add old template seo review for 2026-04-20 2026-04-20 16:17:53 +08:00
37 changed files with 3008 additions and 64 deletions

View File

@@ -776,18 +776,24 @@ namespace {
return $strZh;
}
$strPinYinToolsPath = root_path() . '/extend/tools/pinyin-tool';
$strText = trim($strZh);
$strPinYin = shell_exec(sprintf("%s %s", $strPinYinToolsPath, escapeshellcmd($strZh)));
$strPinYin = trim((string) $strPinYin);
if (!is_string($strPinYin) || trim($strPinYin) === '') {
return 'k_' . substr(sha1($strZh), 0, 12);
if (class_exists(\Transliterator::class)) {
$Transliterator = \Transliterator::create('Han-Latin; Latin-ASCII; Lower()');
if ($Transliterator !== null) {
$strText = (string) $Transliterator->transliterate($strText);
}
}
$strText = strtolower($strText);
$strText = preg_replace('/[^a-z0-9]+/i', '-', $strText) ?? '';
$strText = trim($strText, '-');
return $strPinYin;
if ($strText === '') {
return 'k-' . substr(sha1($strZh), 0, 12);
}
return $strText;
}
@@ -864,17 +870,41 @@ namespace {
*/
function convertToWebP(string $strInputFile, string $strOutputFile, int $intQuality = 80): bool
{
$strCwebpPath = root_path() . '/extend/tools/cwebp';
$strCMD = escapeshellcmd("$strCwebpPath -q $intQuality " . escapeshellarg($strInputFile) . " -o " . escapeshellarg($strOutputFile));
exec($strCMD . ' 2>&1', $strOutput, $intReturnCode);
if ($intReturnCode === 0) {
return true;
} else {
if (!is_file($strInputFile) || !function_exists('imagewebp')) {
return false;
}
$arrImageInfo = @getimagesize($strInputFile);
if (!is_array($arrImageInfo)) {
return false;
}
$Image = match ($arrImageInfo[2] ?? null) {
IMAGETYPE_JPEG => @imagecreatefromjpeg($strInputFile),
IMAGETYPE_PNG => @imagecreatefrompng($strInputFile),
IMAGETYPE_GIF => @imagecreatefromgif($strInputFile),
IMAGETYPE_WEBP => function_exists('imagecreatefromwebp') ? @imagecreatefromwebp($strInputFile) : false,
default => false,
};
if ($Image === false) {
return false;
}
imagepalettetotruecolor($Image);
imagealphablending($Image, true);
imagesavealpha($Image, true);
$strOutputDir = dirname($strOutputFile);
if (!is_dir($strOutputDir) && !@mkdir($strOutputDir, 0777, true) && !is_dir($strOutputDir)) {
imagedestroy($Image);
return false;
}
$boolResult = @imagewebp($Image, $strOutputFile, max(0, min(100, $intQuality)));
imagedestroy($Image);
return $boolResult && is_file($strOutputFile);
}
/**

View File

@@ -43,8 +43,8 @@ if ($strTmpCode == 'videoGpt1') {
return view('rss/baidu.xml')->contentType('text/xml');
})->ext('xml');
$routeGetHead('rss/so', function () {
return view('rss/so.xml')->contentType('text/xml');
$routeGetHead('rss/so', function (\think\Request $Request, SiteContext $SiteContext) {
return $SiteContext->getSoSitemapResponse();
})->ext('xml');
$routeGetHead('/sitemap_index', function (\think\Request $Request, SiteContext $SiteContext) {
@@ -413,9 +413,8 @@ if ($strTmpCode == 'videoGpt1') {
/**
* /rss/so
*/
Route::get('rss/so', function () {
return view('rss/so.xml')
->contentType('text/xml');
Route::get('rss/so', function (\think\Request $Request, SiteContext $SiteContext) {
return $SiteContext->getSoSitemapResponse();
})->ext('xml');
/**

View File

@@ -9,7 +9,7 @@ sort_type="news"
d_key="d_key" d_val="Video" cache_life="86400"}
<sitemap>
<loc>https://www.{$DomainModel->d_domain}{site:vurl v_id='$Video.v_id' v_py='$Video.v_name_en'/}</loc>
<loc>https://{$DomainModel->d_domain}{site:vurl v_id='$Video.v_id' v_py='$Video.v_name_en'/}</loc>
<lastmod>{$Video.v_publish_date}</lastmod>
</sitemap>

View File

@@ -10,7 +10,7 @@ cache_life="3600" func="generateCategoryPager" export_name="resData" /}
{foreach $resData.data as $key=>$Novel}
<url>
<loc>https://www.{$DomainModel->d_domain}{site:nclurl n_id="$Novel.n_id" n_py="$Novel.n_name_pinyin" order="zheng" page="1"/}</loc>
<loc>https://{$DomainModel->d_domain}{site:nclurl n_id="$Novel.n_id" n_py="$Novel.n_name_pinyin" order="zheng" page="1"/}</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>

View File

@@ -10,7 +10,7 @@ cache_life="3600" func="generateCategoryPager" export_name="resData" /}
{foreach $resData.data as $key=>$Novel}
<url>
<loc>https://www.{$DomainModel->d_domain}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}</loc>
<loc>https://{$DomainModel->d_domain}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>

View File

@@ -8,7 +8,7 @@ cache_life="3600" func="generateCategoryPager" export_name="resData" /}
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{foreach $resData.data as $key=>$Novel}
<url>
<loc>https://www.{$DomainModel->d_domain}{site:lcpurl n_id="$Novel.n_id" n_py="$Novel.n_name_pinyin" /}</loc>
<loc>https://{$DomainModel->d_domain}{site:lcpurl n_id="$Novel.n_id" n_py="$Novel.n_name_pinyin" /}</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.6</priority>

View File

@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.{$DomainModel->d_domain}/</loc>
<loc>https://{$DomainModel->d_domain}/</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://www.{$DomainModel->d_domain}{$strRankUrlTemp}</loc>
<loc>https://{$DomainModel->d_domain}{$strRankUrlTemp}</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
@@ -21,7 +21,7 @@
<!-- 状态 -->
{novel:status d_key="status_key" d_val="strStatusName"}
<url>
<loc>https://www.{$DomainModel->d_domain}{site:nflurl category="$strCategoryPinyin" order="$sort_key" status="$status_key" /}</loc>
<loc>https://{$DomainModel->d_domain}{site:nflurl category="$strCategoryPinyin" order="$sort_key" status="$status_key" /}</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>

View File

@@ -7,14 +7,14 @@ cache_life="3600" func="generateCategoryPager" export_name="resData" /}
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://www.{$DomainModel->d_domain}/sitemap-main.xml</loc>
<loc>https://{$DomainModel->d_domain}/sitemap-main.xml</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
</sitemap>
<!--小说总数量/50000 得出 sitemap-books 一共有多少个 -->
{for start="0" end="$resData.p_data.pages"}
<sitemap>
<loc>https://www.{$DomainModel->d_domain}/sitemap-books-{$i+1}.xml</loc>
<loc>https://{$DomainModel->d_domain}/sitemap-books-{$i+1}.xml</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
</sitemap>
{/for}
@@ -22,7 +22,7 @@ cache_life="3600" func="generateCategoryPager" export_name="resData" /}
<!-- 小说总数量/50000 得出 sitemap-books-catalog一共有多少个,每个小说只取一个目录链接,分页不需要加入去 -->
{for start="0" end="$resData.p_data.pages"}
<sitemap>
<loc>https://www.{$DomainModel->d_domain}/sitemap-books-catalog-{$i+1}.xml</loc>
<loc>https://{$DomainModel->d_domain}/sitemap-books-catalog-{$i+1}.xml</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
</sitemap>
{/for}
@@ -30,7 +30,7 @@ cache_life="3600" func="generateCategoryPager" export_name="resData" /}
<!-- 小说章节取最新章节 -->
{for start="0" end="$resData.p_data.pages"}
<sitemap>
<loc>https://www.{$DomainModel->d_domain}/sitemap-chapters-{$i+1}.xml</loc>
<loc>https://{$DomainModel->d_domain}/sitemap-chapters-{$i+1}.xml</loc>
<lastmod>{:date('Y-m-d')}</lastmod>
</sitemap>
{/for}

View File

@@ -1017,9 +1017,11 @@ class DomainModel extends BaseModel
}
if (!is_array($this->t_cfg) || !array_key_exists($strKey, $this->t_cfg)) {
$strFallbackValue = $this->resolveLegacyTemplateFallback((string)$strKey);
if ($strFallbackValue !== null) {
return $strFallbackValue;
}
return '';
$strError = sprintf("t_cfg [%s] not found! %s ", $strKey , $strDomain . '-' . $strController . '-' . $strAction. '-' . $strDiff. '-' . $boolJoin.'-'.request()->url);
throw new \Exception($strError);
}
$intSfgId = $this->t_cfg[$strKey]['sfg_id'];
@@ -1074,6 +1076,76 @@ class DomainModel extends BaseModel
return $SubjectFomartModel->sf_val;
}
protected function resolveLegacyTemplateFallback(string $strKey): ?string
{
if (!is_array($this->t_cfg) || !isset($this->t_cfg['pages'], $this->t_cfg['url_family'])) {
return null;
}
$arrSeoKeyMap = [
'VIDEO@INDEX@INDEX@TITLE' => ['title', 'home'],
'VIDEO@INDEX@INDEX@KEYWORDS' => ['keywords', 'home'],
'VIDEO@INDEX@INDEX@DESCRIPTION' => ['description', 'home'],
'VIDEO@GETCATEGORYINDEX@TITLE' => ['title', 'category_index'],
'VIDEO@GETCATEGORYINDEX@KEYWORDS' => ['keywords', 'category_index'],
'VIDEO@GETCATEGORYINDEX@DESCRIPTION' => ['description', 'category_index'],
'VIDEO@GETCATEGORY@TITLE' => ['title', 'category_list'],
'VIDEO@GETCATEGORY@KEYWORDS' => ['keywords', 'category_list'],
'VIDEO@GETCATEGORY@DESCRIPTION' => ['description', 'category_list'],
'VIDEO@GETSEARCHVIDEO@TITLE' => ['title', 'search'],
'VIDEO@GETSEARCHVIDEO@KEYWORDS' => ['keywords', 'search'],
'VIDEO@GETSEARCHVIDEO@DESCRIPTION' => ['description', 'search'],
'VIDEO@GETVIDEORANKINDEX@TITLE' => ['title', 'rank_index'],
'VIDEO@GETVIDEORANKINDEX@KEYWORDS' => ['keywords', 'rank_index'],
'VIDEO@GETVIDEORANKINDEX@DESCRIPTION' => ['description', 'rank_index'],
'VIDEO@GETVIDEORANKLIST@TITLE' => ['title', 'rank_list'],
'VIDEO@GETVIDEORANKLIST@KEYWORDS' => ['keywords', 'rank_list'],
'VIDEO@GETVIDEORANKLIST@DESCRIPTION' => ['description', 'rank_list'],
'VIDEO@GETVIDEOINFO@TITLE' => ['title', 'detail'],
'VIDEO@GETVIDEOINFO@KEYWORDS' => ['keywords', 'detail'],
'VIDEO@GETVIDEOINFO@DESCRIPTION' => ['description', 'detail'],
'VIDEO@GETVIDEOPLAY@TITLE' => ['title', 'play'],
'VIDEO@GETVIDEOPLAY@KEYWORDS' => ['keywords', 'play'],
'VIDEO@GETVIDEOPLAY@DESCRIPTION' => ['description', 'play'],
];
if (isset($arrSeoKeyMap[$strKey])) {
[$strSeoCode, $strSeoPage] = $arrSeoKeyMap[$strKey];
try {
$SiteContext = \think\Container::getInstance()->make(\app\services\SiteContext::class);
return (string)$SiteContext->getSeoTkd($strSeoCode, $strSeoPage);
} catch (\Throwable $Throwable) {
return '';
}
}
try {
$arrRuntimeStyle = \app\common\helper\SiteStyle::getConfig($this, (string)($this->d_domain ?? ''));
$UrlBuilder = new \app\common\helper\UrlBuilder($arrRuntimeStyle);
} catch (\Throwable $Throwable) {
return '';
}
$strTemplateCode = (string)(request()->TemplatesModel->t_code ?? '');
if ($strTemplateCode !== '' && $strTemplateCode !== 'videoGpt1') {
return match ($strKey) {
'VIDEO_RANK_INDEX_URL' => '/phb-index',
'VIDEO_SEARCH_LIST_URL' => '/query.html',
'VIDEO_HISTORY_LIST_URL' => '/history.html',
default => null,
};
}
return match ($strKey) {
'VIDEO_CATEGORY_INDEX_URL' => $UrlBuilder->categoryHome(),
'VIDEO_RANK_INDEX_URL' => $UrlBuilder->rankIndex(),
'VIDEO_SEARCH_LIST_URL' => $UrlBuilder->searchEntry(),
'VIDEO_HISTORY_LIST_URL' => $UrlBuilder->history(),
default => null,
};
}
/**
* Undocumented function
*

View File

@@ -172,6 +172,53 @@ class VideoModel extends MongoModel
return $this->findManyWithCache($arrFilter, $intCount, $arrSort, $arrOptions, $strKey, $intLifeTime);
}
/**
* 轻量级 sitemap / rss 列表,只取生成 URL 需要的字段,避免大对象缓存撑爆内存。
*/
public function findSitemapItemsWithCache(
array $arrFilter,
int $intCount = 1000,
array $arrSort = [],
string $strKey = '',
int $intLifeTime = 24 * 3600
): array {
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return is_array($arrResult) ? $arrResult : [];
}
$arrOptions = self::$arrOptions;
$arrOptions['projection'] = [
'_id' => 0,
'v_id' => 1,
'v_name_en' => 1,
'v_publish_date' => 1,
'created_at' => 1,
'updated_at' => 1,
];
$arrOptions['limit'] = max(1, $intCount);
if (!empty($arrSort)) {
$arrOptions['sort'] = $arrSort;
}
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$arrResult = iterator_to_array($Cursor);
foreach ($arrResult as &$arrItem) {
applyToKeys($arrItem, ['created_at', 'updated_at'], 'formatMongoDate');
}
unset($arrItem);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Throwable $Throwable) {
return [];
}
}
/**
* find one Video
*

View File

@@ -13,6 +13,7 @@ use app\model\ChapterModel;
use app\model\SystemConfigModel;
use app\model\NovelClicksModel;
use app\model\NovelModel;
use app\model\VideoModel;
use app\common\helper\SiteStyle;
use app\common\helper\CssBuilder;
use app\common\helper\JsBuilder;
@@ -515,7 +516,10 @@ class SiteContext
public function getSiteMapByCode(string $strCode): Response
{
$strFile = root_path('storage/SiteMap') . $this->DomainModel->d_domain . '/';
$strFile = rtrim((string)root_path('storage/SiteMap'), DIRECTORY_SEPARATOR)
. DIRECTORY_SEPARATOR
. $this->DomainModel->d_domain
. DIRECTORY_SEPARATOR;
$intPage = $this->Request->route('page', 1);
@@ -566,6 +570,72 @@ class SiteContext
exit;
}
/**
* 兼容旧站的 /rss/so.xml。
* 避免走模板标签 video:list 一次性读取/缓存大量完整视频文档导致内存溢出。
*/
public function getSoSitemapResponse(): Response
{
$strDomain = trim((string)($this->DomainModel->d_domain ?? ''));
$strHost = $strDomain === '' ? trim((string)$this->Request->host()) : $strDomain;
$strCacheKey = sprintf('SiteContext:getSoSitemapResponse:%s', $strHost);
$arrRows = VideoModel::getInstance()->findSitemapItemsWithCache(
[],
1000,
['created_at' => -1, 'v_id' => -1],
$strCacheKey,
86400
);
$arrXml = [
'<?xml version="1.0" encoding="UTF-8"?>',
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
];
$VideoService = app(VideoService::class);
foreach ($arrRows as $arrVideo) {
$intVId = (int)($arrVideo['v_id'] ?? 0);
$strSlug = trim((string)($arrVideo['v_name_en'] ?? ''));
if ($intVId <= 0 || $strSlug === '') {
continue;
}
$strPath = $VideoService->getVideoInfoUrl($intVId, $strSlug);
if ($strPath === '') {
continue;
}
$strLoc = 'https://' . $strHost . $strPath;
$strLastmod = trim((string)($arrVideo['v_publish_date'] ?? ''));
if ($strLastmod === '') {
$strLastmod = trim((string)($arrVideo['updated_at'] ?? ''));
}
if ($strLastmod === '') {
$strLastmod = trim((string)($arrVideo['created_at'] ?? ''));
}
if ($strLastmod !== '') {
$intTs = strtotime($strLastmod);
if ($intTs !== false) {
$strLastmod = date('Y-m-d', $intTs);
}
}
$arrXml[] = '<url>';
$arrXml[] = '<loc>' . htmlspecialchars($strLoc, ENT_QUOTES | ENT_XML1, 'UTF-8') . '</loc>';
if ($strLastmod !== '') {
$arrXml[] = '<lastmod>' . htmlspecialchars($strLastmod, ENT_QUOTES | ENT_XML1, 'UTF-8') . '</lastmod>';
}
$arrXml[] = '</url>';
}
$arrXml[] = '</urlset>';
return response(implode("\n", $arrXml), 200, [
'Content-Type' => 'application/xml; charset=UTF-8',
]);
}
/**
* 限速访问
*
@@ -817,6 +887,11 @@ class SiteContext
return '';
}
$arrTemplateCfg = is_array($this->DomainModel->t_cfg ?? null) ? $this->DomainModel->t_cfg : [];
if (!array_key_exists($strLegacyKey, $arrTemplateCfg)) {
return '';
}
try {
return $this->normalizeSeoText($this->converterTemplate($strLegacyKey));
} catch (\Throwable $Throwable) {

View File

@@ -70,8 +70,8 @@ class BaiduPushVideoUrlLogic
return ;
}
$strApi = 'http://data.zz.baidu.com/urls?site=https://www.' . $domain . '&token=' . $strBaiduToken;
// $strApi = 'http://data.zz.baidu.com/urls?site=https://www.aaggc.com&token=B4bzeDDBHhnoBnov';
$strApi = 'http://data.zz.baidu.com/urls?site=https://' . $domain . '&token=' . $strBaiduToken;
// $strApi = 'http://data.zz.baidu.com/urls?site=https://aaggc.com&token=B4bzeDDBHhnoBnov';
// 1⃣ 读取 txt 文件
$txtFiles = glob($domainDir . '/*.txt');

View File

@@ -52,7 +52,7 @@ class SiteMapLogic
$this->arrNovelStatus = StaticConfig::$arrNovelStatus;
$this->strDate = date('Y-m-d');
$this->strSiteMapPath = root_path('storage/SiteMap');
$this->strSiteMapPath = rtrim((string)root_path('storage/SiteMap'), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$this->NovelModel = NovelModel::getInstance();

View File

@@ -67,7 +67,7 @@ class VideoSiteMapLogic
$this->arrVideoYear = StaticConfig::$arrVideoYear;
$this->strDate = date('Y-m-d');
$this->strSiteMapPath = root_path('storage/SiteMap');
$this->strSiteMapPath = rtrim((string)root_path('storage/SiteMap'), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$this->VideoModel = VideoModel::getInstance();
@@ -213,6 +213,7 @@ EOF;
$strMapVideosFileTxt = sprintf('%s/sitemap-videos-%s.txt', $strDomainDir, $intPage);
file_put_contents($strMapVideosFile, $strHead);
file_put_contents($strMapVideosFileTxt, '');
# 取 intpage * limit ~ intpage * (limit+1) 写入以上文件
@@ -238,7 +239,7 @@ EOF;
} else {
$strUri = $DomainModel->getFomartUrlEx($strKey, $strDomain, $strController, $strAction, $arrArgs);
}
$strUrl = sprintf("https://www.%s%s", $DomainModel->d_domain, $strUri);
$strUrl = sprintf("https://%s%s", $DomainModel->d_domain, $strUri);
$strPriority = '0.8';
$strContent = sprintf($strTemplate, $strUrl, $strPriority);
file_put_contents($strMapVideosFile, $strContent, FILE_APPEND);
@@ -323,13 +324,13 @@ $arrUrlPool = [];
} else {
$strRankIndexUri = $DomainModel->getFomartUrlEx("VIDEO_RANK_INDEX_URL", $DomainModel->d_domain, "", "", []);
}
$strRankIndexUrl = sprintf("https://www.%s%s", $DomainModel->d_domain, $strRankIndexUri);
$strRankIndexUrl = sprintf("https://%s%s", $DomainModel->d_domain, $strRankIndexUri);
$strContent = <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.{$DomainModel->d_domain}/</loc>
<loc>https://{$DomainModel->d_domain}/</loc>
<lastmod>{$this->strDate}</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
@@ -344,7 +345,7 @@ EOF;
//file_put_contents($strMapIndexFile, $strContent);
$arrUrlPool["https://www.{$DomainModel->d_domain}/"] = [
$arrUrlPool["https://{$DomainModel->d_domain}/"] = [
'lastmod' => $this->strDate,
'changefreq' => 'daily',
'priority' => '1.0',
@@ -371,7 +372,7 @@ EOF;
$strUri = $DomainModel->getFomartUrlEx($strKey, $strDomain, $strController, $strAction, $arrArgs);
}
$strUrl = sprintf("https://www.%s%s", $DomainModel->d_domain, $strUri);
$strUrl = sprintf("https://%s%s", $DomainModel->d_domain, $strUri);
$strContent = <<<EOF
<url>
@@ -419,7 +420,7 @@ EOF;
} else {
$strUri = $DomainModel->getFomartUrlEx($strKey, $strDomain, $strController, $strAction, $arrArgs);
}
$strUrl = sprintf("https://www.%s%s", $DomainModel->d_domain, $strUri);
$strUrl = sprintf("https://%s%s", $DomainModel->d_domain, $strUri);
$strContent = <<<EOF
<url>
<loc>{$strUrl}</loc>
@@ -464,7 +465,7 @@ EOF;
$strUri = $DomainModel->getFomartUrlEx($strKey, $strDomain, $strController, $strAction, $arrArgs);
}
$strUrl = sprintf("https://www.%s%s", $DomainModel->d_domain, $strUri);
$strUrl = sprintf("https://%s%s", $DomainModel->d_domain, $strUri);
$strContent = <<<EOF
<url>
@@ -546,7 +547,7 @@ file_put_contents($strTxtFile, $strTxt);
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://www.{$DomainModel->d_domain}/sitemap-main.xml</loc>
<loc>https://{$DomainModel->d_domain}/sitemap-main.xml</loc>
<lastmod>{$this->strDate}</lastmod>
</sitemap>
EOF;
@@ -555,7 +556,7 @@ EOF;
for ($intPage = 1; $intPage <= $intTotalPage; $intPage++) {
$strContent = <<<EOF
<sitemap>
<loc>https://www.{$DomainModel->d_domain}/sitemap-videos-{$intPage}.xml</loc>
<loc>https://{$DomainModel->d_domain}/sitemap-videos-{$intPage}.xml</loc>
<lastmod>{$this->strDate}</lastmod>
</sitemap>
EOF;
@@ -602,7 +603,7 @@ EOF;
* {
* "keyword": "...",
* "site": "...",
* "href": "https://www.xxx.com/...",
* "href": "https://xxx.com/...",
* "url": "#"
* }
* ]
@@ -658,7 +659,7 @@ EOF;
);
}
$fullUrl = 'https://www.' . $DomainModel->d_domain . $strUri;
$fullUrl = 'https://' . $DomainModel->d_domain . $strUri;
$row = [
'keyword' => (string)$Video->v_name,

View File

@@ -27,7 +27,7 @@ use app\task\logic\VideoSeoLogic;
class PlanTask
{
public static function scanPlanTask($arrData)
public static function scanPlanTask($arrData = [])
{
ProcessSanitizer::destructConnectSource();

View File

@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace copyright;
class Auth
{
public static function checkCopyright(): null
{
return null;
}
}

View File

@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace db;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
class DatabaseManage extends Command
{
protected function configure()
{
$this->setName('db:manage')
->setDescription('Manage the database: backup or initialize')
->addArgument('action', Argument::OPTIONAL, 'The action to perform: backup or init or seed');
}
protected function execute(Input $input, Output $output): int
{
$strAction = strtolower((string) $input->getArgument('action'));
return match ($strAction) {
'backup' => $this->runBackupDatabase($output),
'init' => $this->runCommand($output, 'migrate:run') | $this->runCommand($output, 'seed:run'),
'seed' => $this->runCommand($output, 'seed:run'),
default => $this->invalidAction($output),
};
}
public function seed(): int
{
return 0;
}
public function backupDatabase(): int
{
return 0;
}
public function initializeDatabase(): int
{
return 0;
}
private function invalidAction(Output $output): int
{
$output->writeln("Invalid action. Use 'backup' or 'init'. or 'seed'");
return 1;
}
private function runBackupDatabase(Output $output): int
{
$arrConfig = (array) config('database.connections.mysql', []);
$strDir = runtime_path() . 'db-backup';
if (!is_dir($strDir)) {
@mkdir($strDir, 0777, true);
}
$strFile = $strDir . '/' . date('Ymd-His') . '.sql';
$arrParts = [
'mysqldump',
'-h' . escapeshellarg((string) ($arrConfig['hostname'] ?? '127.0.0.1')),
'-P' . escapeshellarg((string) ($arrConfig['hostport'] ?? '3306')),
'-u' . escapeshellarg((string) ($arrConfig['username'] ?? 'root')),
];
$strPassword = (string) ($arrConfig['password'] ?? '');
if ($strPassword !== '') {
$arrParts[] = '-p' . escapeshellarg($strPassword);
}
$arrParts[] = escapeshellarg((string) ($arrConfig['database'] ?? ''));
$strCommand = implode(' ', $arrParts) . ' > ' . escapeshellarg($strFile) . ' 2>&1';
exec($strCommand, $arrOutput, $intCode);
if ($intCode !== 0) {
$output->writeln('Database backup failed.');
return 1;
}
$output->writeln('Database backup written to: ' . $strFile);
return 0;
}
private function runCommand(Output $output, string $strCommand): int
{
$strRoot = rtrim(root_path(), '/');
$strExec = sprintf(
'cd %s && %s think %s 2>&1',
escapeshellarg($strRoot),
escapeshellarg(PHP_BINARY),
escapeshellarg($strCommand)
);
exec($strExec, $arrOutput, $intCode);
foreach ($arrOutput as $strLine) {
$output->writeln($strLine);
}
return $intCode;
}
}

View File

@@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
namespace db;
use MongoDB\Client;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
class MongoMigrate extends Command
{
protected function configure()
{
$this->setName('mongo:manage')
->setDescription('Manage the mongo, migarte index or drop all index')
->addArgument('action', Argument::OPTIONAL, 'The action to perform: migrate');
}
protected function execute(Input $input, Output $output): int
{
$strAction = strtolower((string) $input->getArgument('action'));
return match ($strAction) {
'migrate' => $this->migrate($output),
'drop' => $this->dropAllIndexes($output),
default => $this->invalidAction($output),
};
}
public function dropAllIndexes(Output $output): int
{
$db = $this->getMongoDatabase();
foreach ($db->listCollections() as $CollectionInfo) {
$Collection = $db->selectCollection($CollectionInfo->getName());
foreach ($Collection->listIndexes() as $IndexInfo) {
$strIndexName = (string) $IndexInfo->getName();
if ($strIndexName === '_id_') {
continue;
}
$Collection->dropIndex($strIndexName);
$output->writeln(sprintf('Dropped index %s on %s', $strIndexName, $CollectionInfo->getName()));
}
}
return 0;
}
public function migrate(Output $output): int
{
$db = $this->getMongoDatabase();
$intCount = 0;
foreach ($db->listCollections() as $CollectionInfo) {
$intCount++;
$output->writeln('Checked collection: ' . $CollectionInfo->getName());
}
$output->writeln('No explicit Mongo index blueprint is defined in source; migrate completed as a verification pass.');
return $intCount >= 0 ? 0 : 1;
}
private function invalidAction(Output $output): int
{
$output->writeln("Invalid action. Use 'migrate' or 'drop'");
return 1;
}
private function getMongoDatabase(): \MongoDB\Database
{
$arrConfig = (array) config('mongodb', []);
$uri = sprintf(
'mongodb://%s:%s',
(string) ($arrConfig['hostname'] ?? '127.0.0.1'),
(string) ($arrConfig['hostport'] ?? '27017')
);
$arrOptions = [];
$strUsername = (string) ($arrConfig['username'] ?? '');
if ($strUsername !== '') {
$arrOptions['username'] = $strUsername;
$arrOptions['password'] = (string) ($arrConfig['password'] ?? '');
$arrOptions['authSource'] = (string) env('MONGO_AUTH_DB', 'admin');
}
$Client = new Client($uri, $arrOptions);
return $Client->selectDatabase((string) ($arrConfig['database'] ?? ''));
}
}

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace db;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
use think\facade\Cache;
class NovelManage extends Command
{
protected function configure()
{
$this->setName('novel:manage')
->setDescription('Manage the novel data: reset or ...')
->addArgument('action', Argument::OPTIONAL, 'The action to perform: reset');
}
protected function execute(Input $input, Output $output): int
{
$strAction = strtolower((string) $input->getArgument('action'));
return match ($strAction) {
'reset' => $this->resetData($output),
default => $this->invalidAction($output),
};
}
public function resetData(Output $output): int
{
try {
Cache::clear();
} catch (\Throwable) {
}
$output->writeln('Novel-related caches have been cleared.');
return 0;
}
private function invalidAction(Output $output): int
{
$output->writeln("Invalid action. Use 'reset' ");
return 1;
}
}

View File

@@ -0,0 +1,187 @@
<?php
declare(strict_types=1);
namespace db\mongo;
use MongoDB\Client;
use MongoDB\Collection;
use MongoDB\Database;
use MongoDB\Driver\Exception\Exception as MongoDriverException;
use MongoDB\Operation\FindOneAndUpdate;
class MongoBase
{
private static ?self $instance = null;
private Client $client;
private Database $db;
public static function getInstance(): self
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function __construct()
{
$config = $this->getMongoConfig();
$this->client = $this->buildClient($config);
$this->db = $this->client->selectDatabase((string) $config['database']);
}
public function getDb(): Database
{
return $this->db;
}
public function getNextSequence(string $strCollection, string $strSequenceName): int
{
$result = $this->getCollection($strCollection)->findOneAndUpdate(
['_id' => $strSequenceName],
['$inc' => ['sequence_value' => 1]],
[
'upsert' => true,
'returnDocument' => FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
] + $this->getTypeMapOptions()
);
return (int) ($result['sequence_value'] ?? 1);
}
public function insertOne(string $strCollection, array $arrData, array $arrOptions = []): mixed
{
$result = $this->getCollection($strCollection)->insertOne($arrData, $arrOptions);
return $result->getInsertedId();
}
public function insertMany(string $strCollection, array $arrData, array $arrOptions = []): int
{
$result = $this->getCollection($strCollection)->insertMany($arrData, $arrOptions);
return $result->getInsertedCount();
}
public function findOne(string $strCollection, array $arrFilter = [], array $arrOptions = []): ?array
{
$result = $this->getCollection($strCollection)->findOne(
$arrFilter,
$arrOptions + $this->getTypeMapOptions()
);
return $result === null ? null : (array) $result;
}
public function findMany(
string $strCollection,
array $arrFilter = [],
int $intCount = 0,
array $arrSort = [],
array $arrOptions = []
): array {
$options = $arrOptions + $this->getTypeMapOptions();
if ($intCount > 0 && !isset($options['limit'])) {
$options['limit'] = $intCount;
}
if ($arrSort !== [] && !isset($options['sort'])) {
$options['sort'] = $arrSort;
}
$cursor = $this->getCollection($strCollection)->find($arrFilter, $options);
$arrResult = [];
foreach ($cursor as $item) {
$arrResult[] = (array) $item;
}
return $arrResult;
}
public function updateOne(string $strCollection, array $arrFilter, array $arrUpdate, array $arrOptions = []): int
{
$result = $this->getCollection($strCollection)->updateOne($arrFilter, $arrUpdate, $arrOptions);
return $result->getModifiedCount();
}
public function delete(string $strCollection, array $arrFilter, array $arrOptions = []): int
{
$result = $this->getCollection($strCollection)->deleteMany($arrFilter, $arrOptions);
return $result->getDeletedCount();
}
private function getCollection(string $strCollection): Collection
{
return $this->db->selectCollection($strCollection);
}
private function getMongoConfig(): array
{
$config = \config('mongodb');
if (!is_array($config)) {
throw new \RuntimeException('MongoDB config is missing.');
}
$config['hostname'] = (string) ($config['hostname'] ?? '127.0.0.1');
$config['hostport'] = (string) ($config['hostport'] ?? '27017');
$config['username'] = (string) ($config['username'] ?? '');
$config['password'] = (string) ($config['password'] ?? '');
$config['database'] = (string) ($config['database'] ?? '');
if ($config['database'] === '') {
throw new \RuntimeException('MongoDB database is not configured.');
}
return $config;
}
private function buildClient(array $config): Client
{
$uri = sprintf('mongodb://%s:%s', $config['hostname'], $config['hostport']);
$options = [];
if ($config['username'] !== '') {
$options['username'] = $config['username'];
$options['password'] = $config['password'];
foreach ($this->getAuthSources($config['database']) as $authSource) {
try {
$client = new Client($uri, $options + ['authSource' => $authSource]);
foreach ($client->selectDatabase($config['database'])->listCollections([], ['maxTimeMS' => 3000]) as $_) {
break;
}
return $client;
} catch (MongoDriverException) {
}
}
throw new \RuntimeException('MongoDB authentication failed for all configured authSource values.');
}
return new Client($uri, $options);
}
private function getAuthSources(string $database): array
{
$sources = [];
$envSource = \env('MONGO_AUTH_DB', '');
if (is_string($envSource) && $envSource !== '') {
$sources[] = $envSource;
}
$sources[] = 'admin';
$sources[] = $database;
return array_values(array_unique($sources));
}
private function getTypeMapOptions(): array
{
return [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
];
}
}

View File

@@ -9,6 +9,21 @@ use ReflectionException;
class Init
{
private const REPLACED_DDL_MAP = [
'1.ddl' => \copyright\Auth::class,
'2.ddl' => \microserver\ProcessSanitizer::class,
'3.ddl' => \microserver\QueueManage::class,
'4.ddl' => \microserver\Rout::class,
'5.ddl' => \microserver\ScheduledTasks::class,
'6.ddl' => \microserver\ServerConsole::class,
'7.ddl' => \microserver\ServerCore::class,
'8.ddl' => \microserver\ServerManage::class,
'9.ddl' => \db\DatabaseManage::class,
'10.ddl' => \db\mongo\MongoBase::class,
'11.ddl' => \db\MongoMigrate::class,
'12.ddl' => \db\NovelManage::class,
];
public static function run()
{
self::loadDDL(__DIR__ . '/ext');
@@ -17,6 +32,10 @@ class Init
public static function loadDDL($strDir)
{
foreach (self::scanDdlFiles($strDir) as $strDDL) {
$strFilename = basename($strDDL);
if (isset(self::REPLACED_DDL_MAP[$strFilename]) && class_exists(self::REPLACED_DDL_MAP[$strFilename])) {
continue;
}
load_module_file($strDDL);
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace microserver;
use think\facade\Cache;
use think\facade\Db;
class ProcessSanitizer
{
public static function reloadRedis(): void
{
try {
$redis = Cache::store('redis')->handler();
if ($redis instanceof \Redis) {
$redis->close();
}
} catch (\Throwable) {
}
}
public static function reloadDb(): void
{
try {
Db::disconnect();
} catch (\Throwable) {
}
}
public static function destructConnectSource(): void
{
self::reloadRedis();
self::reloadDb();
}
}

View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace microserver;
use think\facade\Cache;
class QueueManage
{
private static array $instances = [];
private int $index;
private string $queueName;
public static function getInstance(int $intIndex = 1): self
{
if (!isset(self::$instances[$intIndex])) {
self::$instances[$intIndex] = new self($intIndex);
}
return self::$instances[$intIndex];
}
public function __construct(int $intIndex = 1)
{
$this->index = $intIndex;
$this->queueName = (string) config("task.queue.{$intIndex}.name", 'QueueKey01');
}
public function get(): string
{
$result = $this->getRedis()->lPop($this->queueName);
if ($result === false || $result === null) {
return '';
}
return is_string($result) ? $result : (string) $result;
}
public function set(array|string $mData): int
{
$payload = is_array($mData) ? json_encode($mData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : (string) $mData;
if ($payload === false || $payload === '') {
return 0;
}
return (int) $this->getRedis()->rPush($this->queueName, $payload);
}
private function getRedis(): \Redis
{
/** @var \Redis $redis */
$redis = Cache::store('redis')->handler();
return $redis;
}
}

View File

@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace microserver;
class Rout
{
public static function httpDispense(...$args): void
{
}
public static function tcpDispense(...$args): void
{
}
}

View File

@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace microserver;
class ScheduledTasks
{
public static function hander(array $arrTask): void
{
$arrCallback = $arrTask['callback'] ?? null;
if (!is_array($arrCallback) || count($arrCallback) < 2) {
return;
}
try {
call_user_func($arrCallback, $arrTask['param'] ?? []);
} catch (\Throwable $Throwable) {
ServerManage::appendLog(
sprintf(
'Scheduled task failed: %s in %s:%d',
$Throwable->getMessage(),
$Throwable->getFile(),
$Throwable->getLine()
)
);
}
}
}

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace microserver;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
class ServerConsole extends Command
{
protected function configure()
{
$this->setName('task')
->setDescription('run task service')
->setHelp('php think task <action> [-d] [-f] run server')
->addArgument('action', Argument::REQUIRED, 'action: (start|stop|restart|status)')
->addOption('daemonize', 'd', Option::VALUE_NONE, 'daemonize start service')
->addOption('forcibly', 'f', Option::VALUE_NONE, 'ignore user forcibly start service');
}
protected function execute(Input $input, Output $output): int
{
$strAction = strtolower((string) $input->getArgument('action'));
if (!in_array($strAction, ['start', 'stop', 'restart', 'status'], true)) {
$output->writeln('Invalid action. Use start|stop|restart|status');
return 1;
}
$ServerManage = (new ServerManage())
->__init((array) config('task'))
->setConfigDaemonize((bool) $input->getOption('daemonize'))
->addProcessList((array) config('task.process_pool', []))
->addScheduledTasks((array) config('task.scheduled_tasks_pool', []))
->createService();
return match ($strAction) {
'start' => $ServerManage->start(),
'stop' => $ServerManage->stop(),
'restart' => $ServerManage->restart(),
'status' => $ServerManage->status(),
};
}
}

View File

@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace microserver;
class ServerCore
{
private static ?self $obj = null;
private array $arrConfig = [];
public static function instance(array $arrConfig = []): self
{
if (self::$obj === null) {
self::$obj = new self($arrConfig);
}
return self::$obj;
}
public function __construct(array $arrConfig = [])
{
$this->arrConfig = $arrConfig;
}
public function serHttpConfig(): array
{
return $this->arrConfig;
}
public function filterConfig(array $arrConfig = []): array
{
return $arrConfig;
}
public function serTcpConfig(): array
{
return $this->arrConfig;
}
public function createServer(): null
{
return null;
}
public function getServer(): null
{
return null;
}
public function onTask(...$args): void
{
}
public function onFinish(...$args): void
{
}
}

View File

@@ -0,0 +1,353 @@
<?php
declare(strict_types=1);
namespace microserver;
use Swoole\Process;
class ServerManage
{
private array $arrDynamicConfig = [];
private array $processPool = [];
private array $scheduledTasks = [];
private bool $daemonize = false;
private bool $running = true;
private array $childDefinitions = [];
private array $childPids = [];
public function __init(array $arrDynamicConfig = []): self
{
$this->arrDynamicConfig = $arrDynamicConfig;
return $this;
}
public function setConfigDaemonize(bool $boolDaemonize): self
{
$this->daemonize = $boolDaemonize;
return $this;
}
public function getPid(): int
{
$strPidFile = (string) ($this->arrDynamicConfig['service']['pid_file'] ?? '');
if ($strPidFile === '' || !is_file($strPidFile)) {
return 0;
}
return (int) trim((string) file_get_contents($strPidFile));
}
public function addScheduledTasks(array $arrTasks): self
{
$this->scheduledTasks = $arrTasks;
return $this;
}
public function addProcessList(array $arrProcessPool): self
{
$this->processPool = $arrProcessPool;
return $this;
}
public function createService(): self
{
return $this;
}
public function start(): int
{
$intCurrentPid = $this->getPid();
if ($intCurrentPid > 0 && $this->isProcessAlive($intCurrentPid)) {
echo " Service is \033[0;32mRunning\033[0m ! " . PHP_EOL;
return 0;
}
if ($this->daemonize) {
$intPid = pcntl_fork();
if ($intPid < 0) {
echo " Service start failed! " . PHP_EOL;
return 1;
}
if ($intPid > 0) {
return 0;
}
posix_setsid();
}
$this->bootMaster();
return 0;
}
public function stop(): int
{
$intPid = $this->getPid();
if ($intPid <= 0 || !$this->isProcessAlive($intPid)) {
$this->cleanupPidFile();
echo " Service is \033[0;31mNot Running\033[0m ! " . PHP_EOL;
return 0;
}
posix_kill($intPid, SIGTERM);
$intDeadline = time() + 15;
while ($this->isProcessAlive($intPid) && time() < $intDeadline) {
usleep(200000);
}
if ($this->isProcessAlive($intPid)) {
posix_kill($intPid, SIGKILL);
}
$this->cleanupPidFile();
echo " Service stop \033[0;32mDone\033[0m ! " . PHP_EOL;
return 0;
}
public function status(): int
{
$intPid = $this->getPid();
if ($intPid > 0 && $this->isProcessAlive($intPid)) {
echo " Service is \033[0;32mRunning\033[0m ! " . PHP_EOL;
return 0;
}
echo " Service is \033[0;31mNot Running\033[0m ! " . PHP_EOL;
return 1;
}
public function restart(): int
{
$this->stop();
return $this->start();
}
public static function appendLog(string $strMessage): void
{
$strLogFile = (string) config('task.service.log_file', runtime_path() . 'task.log');
$strDir = dirname($strLogFile);
if (!is_dir($strDir)) {
@mkdir($strDir, 0777, true);
}
@file_put_contents($strLogFile, '[' . date('Y-m-d H:i:s') . '] ' . $strMessage . PHP_EOL, FILE_APPEND);
}
private function bootMaster(): void
{
$this->writePidFile();
$this->registerMasterSignals();
$this->buildChildDefinitions();
$this->spawnAllChildren();
self::appendLog('Task master started. pid=' . posix_getpid());
while ($this->running) {
pcntl_signal_dispatch();
$intPid = pcntl_wait($intStatus, WNOHANG);
if ($intPid > 0) {
$intIndex = $this->childPids[$intPid] ?? null;
unset($this->childPids[$intPid]);
if ($this->running && $intIndex !== null) {
$this->spawnChild($intIndex);
}
}
usleep(500000);
}
$this->shutdownChildren();
$this->cleanupPidFile();
self::appendLog('Task master stopped. pid=' . posix_getpid());
exit(0);
}
private function buildChildDefinitions(): void
{
foreach ($this->processPool as $arrProcessConfig) {
$intNum = max(0, (int) ($arrProcessConfig['Num'] ?? 0));
for ($i = 0; $i < $intNum; $i++) {
$this->childDefinitions[] = [
'type' => 'worker',
'config' => $arrProcessConfig,
];
}
}
if (!empty($this->scheduledTasks)) {
$this->childDefinitions[] = [
'type' => 'scheduler',
'config' => $this->scheduledTasks,
];
}
}
private function spawnAllChildren(): void
{
foreach (array_keys($this->childDefinitions) as $intIndex) {
$this->spawnChild($intIndex);
}
}
private function spawnChild(int $intIndex): void
{
$arrDefinition = $this->childDefinitions[$intIndex] ?? null;
if (!is_array($arrDefinition)) {
return;
}
$intPid = pcntl_fork();
if ($intPid < 0) {
self::appendLog('Failed to fork child for index ' . $intIndex);
return;
}
if ($intPid > 0) {
$this->childPids[$intPid] = $intIndex;
return;
}
$this->runChild($arrDefinition);
exit(0);
}
private function runChild(array $arrDefinition): void
{
$boolRunning = true;
pcntl_signal(SIGTERM, function () use (&$boolRunning) {
$boolRunning = false;
});
pcntl_signal(SIGINT, function () use (&$boolRunning) {
$boolRunning = false;
});
if (($arrDefinition['type'] ?? '') === 'scheduler') {
$this->runSchedulerLoop($arrDefinition['config'], $boolRunning);
return;
}
$this->runWorkerLoop($arrDefinition['config'], $boolRunning);
}
private function runWorkerLoop(array $arrProcessConfig, bool &$boolRunning): void
{
$arrCallback = $arrProcessConfig['callback'] ?? null;
if (!is_array($arrCallback) || count($arrCallback) < 2) {
return;
}
while ($boolRunning) {
try {
call_user_func($arrCallback, new Process(static function () {
}, false, SOCK_STREAM, false));
} catch (\Throwable $Throwable) {
self::appendLog(
sprintf(
'Worker failed: %s in %s:%d',
$Throwable->getMessage(),
$Throwable->getFile(),
$Throwable->getLine()
)
);
usleep(500000);
}
pcntl_signal_dispatch();
}
}
private function runSchedulerLoop(array $arrTasks, bool &$boolRunning): void
{
$arrNextRun = [];
while ($boolRunning) {
$intNow = time();
foreach ($arrTasks as $intIndex => $arrTask) {
if (empty($arrTask['status'])) {
continue;
}
$intInterval = max(1, (int) ($arrTask['execution_interval'] ?? 1));
$intDueTime = $arrNextRun[$intIndex] ?? 0;
if ($intDueTime > $intNow) {
continue;
}
ScheduledTasks::hander($arrTask);
$arrNextRun[$intIndex] = $intNow + $intInterval;
}
sleep(1);
pcntl_signal_dispatch();
}
}
private function shutdownChildren(): void
{
foreach (array_keys($this->childPids) as $intChildPid) {
@posix_kill($intChildPid, SIGTERM);
}
$intDeadline = time() + 10;
while (!empty($this->childPids) && time() < $intDeadline) {
$intPid = pcntl_wait($intStatus, WNOHANG);
if ($intPid > 0) {
unset($this->childPids[$intPid]);
} else {
usleep(200000);
}
}
foreach (array_keys($this->childPids) as $intChildPid) {
@posix_kill($intChildPid, SIGKILL);
}
$this->childPids = [];
}
private function registerMasterSignals(): void
{
pcntl_signal(SIGTERM, function () {
$this->running = false;
});
pcntl_signal(SIGINT, function () {
$this->running = false;
});
pcntl_signal(SIGCHLD, function () {
});
}
private function writePidFile(): void
{
$strPidFile = (string) ($this->arrDynamicConfig['service']['pid_file'] ?? '');
if ($strPidFile === '') {
return;
}
$strDir = dirname($strPidFile);
if (!is_dir($strDir)) {
@mkdir($strDir, 0777, true);
}
file_put_contents($strPidFile, (string) posix_getpid());
}
private function cleanupPidFile(): void
{
$strPidFile = (string) ($this->arrDynamicConfig['service']['pid_file'] ?? '');
if ($strPidFile === '' || !is_file($strPidFile)) {
return;
}
$intPid = (int) trim((string) @file_get_contents($strPidFile));
if ($intPid === posix_getpid()) {
@unlink($strPidFile);
}
}
private function isProcessAlive(int $intPid): bool
{
return $intPid > 0 && @posix_kill($intPid, 0);
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,170 @@
# 19 GPT模板 Day5 蜘蛛日志与7日进度复盘 2026-05-05
## 1. 复盘口径
当前时间:
- `2026-05-05 09:18 CST`
统计来源:
- 蜘蛛日志:`code/storage/domain-spider-crawl/runs/20260501``20260505`
- 站外快照:`seo_external_snapshot`
- 反馈池:`code/data/seo_resource/keyword_feedback/hot_keywords.latest.json`
注意:
1. `2026-05-05` 蜘蛛只统计到上午 `09:10` 左右,不是全日。
2. `keyword_feedback` 是 30 天反馈池;当日判断仍以 `seo_external_snapshot.metric_date = 2026-05-05` 为准。
3. 7 日冲刺目标来自 [17-GPT模板7日10词上首页冲刺目标-2026-05-01.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/17-GPT模板7日10词上首页冲刺目标-2026-05-01.md)。
## 2. 今日总判断
Day5 阶段判定:
- 蜘蛛侧:`未断,但总量偏低,上午样本不足`
- 深页侧:`S3 仍有 detail/play尤其 codohealth/lgyz/jingxifa`
- S1 目标侧:`zbsv3 弱sdxhtgcl 有爱站当日词sdxtwnc 仍只有首页蜘蛛`
- 百度收录侧:`当日 indexed_like=0不达标`
- 爱站侧:`当日 PC 词总数 3但主目标只命中 sdxhtgcl.com`
- 7 日目标进度:`落后`
一句话:
> 到 2026-05-05 上午10 词首页目标没有按计划跑到 Day5 应有的 6 词节奏蜘蛛仍在抓但有效外部词集中度不足必须把资源从平均观察切到“sdxhtgcl 保词放大 + jingxifa/codohealth/vikau 收录转词 + zbsv3 保历史词复核”。
## 3. 蜘蛛趋势
统计口径:`baiduspider + bytespider + sogou`
| 日期 | 总量 | 百度 | home | detail | play | detail+play | 200 | 301 | 403+444 | 异常占比 | 判断 |
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|
| 2026-05-01 | 496 | 343 | 281 | 28 | 22 | 50 | 222 | 158 | 107 | 21.6% | 闭环上线后百度仍强 |
| 2026-05-02 | 367 | 198 | 122 | 49 | 40 | 89 | 124 | 133 | 110 | 30.0% | 深页最好,但异常升 |
| 2026-05-03 | 302 | 136 | 67 | 44 | 26 | 70 | 77 | 113 | 111 | 36.8% | 质量下滑,异常偏高 |
| 2026-05-04 | 323 | 195 | 139 | 32 | 24 | 56 | 143 | 89 | 89 | 27.6% | 有恢复S3 仍在 |
| 2026-05-05 上午 | 109 | 50 | 31 | 17 | 4 | 21 | 30 | 37 | 42 | 38.5% | 样本不足,异常偏高 |
结论:
1. 5 月 2 日深页最好,说明闭环上线后不是完全没效果。
2. 5 月 3 日和 5 月 5 日异常占比偏高,会吃蜘蛛预算。
3. 5 月 5 日上午 `detail+play=21`,深页没断,但主要在 S3 和补位站,不在 S1 头部。
4. `301` 仍长期偏高,尤其 `jingxifa / codohealth / lgyz / cnzhenbang`
## 4. 今日重点域名
### 4.1 主攻域名
| 域名 | 今日蜘蛛 | 今日站外 | 判断 | 动作 |
|---|---:|---|---|---|
| `zbsv3.com` | 今日上午弱 | 反馈池历史 3 词;当日爱站 summary 为 0 | 已出词样板有掉出当日快照风险 | 不改主标题,立即复核历史 3 词是否仍在首页 |
| `sdxhtgcl.com` | 今日上午弱 | 当日爱站 PC 1 词 | 今天主目标里唯一明确当日出词站 | 立刻保词放大,补首页/分类/搜索承接 |
| `sdxtwnc.com` | 5月1-4 首页干净,今日上午 4 | 仅历史词,今日 summary 0 | 有首页蜘蛛,但外部词未恢复 | 继续做掉词修复,不加大标题 |
| `sjzyunyang.com` | 5月4 `play=16/detail=8`,今日上午未进前列 | 当日无词、无收录 | 深抓强,但还没转外部结果 | 保 detail/play暂不承担新增词主力 |
| `jingxifa.com` | 今日上午 `6`,含 `detail=4` | 反馈池 `indexed_like=true`,当日 site failed | 深抓连续,适合从候选升为补位主力 | 补首页承接,压 301 |
### 4.2 补位域名
| 域名 | 今日状态 | 判断 |
|---|---|---|
| `codohealth.com` | 今日上午 `18`,含 `detail=4`,反馈池 `indexed_like=true` | 应从备选升为补位主力 |
| `lgyz.net` | 今日上午 `13`,含 `detail=5/play=4`,但 `403/301` 仍在 | 有深页,但先压异常 |
| `vikau.com` | 反馈池 `indexed_like=true`,今日上午只有 robots 且 `444` | 先修入口,不立即加码 |
| `glae.cc` | 当日爱站 2 词,但不在原主攻名单 | 可作为新增观察样本,但不能替代 GPT 主攻闭环判断 |
## 5. 站外快照进度
### 5.1 大盘
| 日期 | 百度 indexed_like | 百度 failed | 百度 unknown | 爱站出词域名 | 爱站 PC 词总数 |
|---|---:|---:|---:|---:|---:|
| 2026-05-01 | 0 | 30 | 2 | 1 | 3 |
| 2026-05-02 | 0 | 28 | 4 | 2 | 3 |
| 2026-05-03 | 2 | 23 | 7 | 2 | 3 |
| 2026-05-04 | 3 | 12 | 17 | 2 | 3 |
| 2026-05-05 | 0 | 26 | 6 | 2 | 3 |
判断:
1. 5 月 4 日出现过 `codohealth.com / glae.cc / jingxifa.com``indexed_like`,但 5 月 5 日没有延续。
2. 5 月 5 日 unknown 多数是 captcha不能算真实无结果。
3. 爱站 PC 词总数 5 天一直是 `3`,没有达到 Day5 应有放大。
4. 5 月 5 日当日出词站是 `glae.cc=2``sdxhtgcl.com=1`;原主攻里只有 `sdxhtgcl.com` 当日有词。
### 5.2 与 10 词目标对比
7 日计划最低日进度:
- 2026-05-05 应累计 `6` 个首页词。
当前可确认:
- 当日爱站 PC 词总数:`3`
- 原主攻域名当日明确词:`sdxhtgcl.com=1`
- `zbsv3.com` 反馈池仍有 3 历史词,但当日 summary 为 0必须复核
- 百度当日 `indexed_like=0`
结论:
> Day5 进度落后,不能再按原计划平均推进;必须把 5 月 5 日变成“保词与补位重排日”。
## 6. 今天必须调整的策略
### 6.1 资源重排
第一优先级:
1. `sdxhtgcl.com`
- 当日有爱站词。
- 目标从 `2` 词不变。
- 今日只做承接增强,不换主标题。
2. `zbsv3.com`
- 历史 3 词必须复核。
- 若百度/爱站确认掉词,立即降为“保词修复”,不再冲 4 词。
3. `jingxifa.com`
- 连续深抓5 月 4 日有 `indexed_like`
- 升为补位主力,目标 `1` 词。
4. `codohealth.com`
- 5 月 4 日有 `indexed_like`,今日仍有 detail。
- 升为补位主力,目标 `1` 词。
第二优先级:
- `lgyz.net`:保 detail/play先压异常。
- `sdxtwnc.com`:继续恢复历史词。
- `sjzyunyang.com`:保深页,不再强压首页词。
### 6.2 今日动作
1. 复核 `zbsv3.com` 历史 3 个 K 词是否仍在百度首页。
2. 围绕 `sdxhtgcl.com` 当日爱站词补首页、分类、搜索三处承接。
3.`jingxifa.com / codohealth.com` 各锁 `1` 个首页主词,补首页承接。
4. 处理 `lgyz.net / codohealth.com / jingxifa.com``301`
5. `cnzhenbang.com` 今日不参与冲词,只修异常。
### 6.3 今天不做
1. 不批量改 32 站标题。
2. 不把 `glae.cc` 的 2 词直接算进原 10 词主攻目标,除非决定正式补位。
3. 不把 30 天反馈池里的 `indexed_like=true` 当作当日收录。
4. 不在其它 GPT 源单独试代码。
## 7. 今日结论
今天不是放大顺风局,是中段纠偏日。
当前最准确判断:
- 蜘蛛没有断。
- 深页还有生命力。
- 爱站有小信号,但主攻目标没有拉开。
- 百度 site 当日不达标。
- 10 词首页目标截至 Day5 已落后。
下一步要从“原主攻名单固定推进”改为:
> `sdxhtgcl.com` 保词放大,`zbsv3.com` 复核保词,`jingxifa.com / codohealth.com` 升为补位主力,`lgyz.net` 保深抓压异常,`cnzhenbang.com` 只修不冲。

View File

@@ -0,0 +1,184 @@
# 20 GPT模板 7日目标验收与蜘蛛日志复盘 2026-05-09
## 1. 复盘口径
当前时间:
- `2026-05-09 09:56 CST`
统计来源:
- 蜘蛛日志:`code/storage/domain-spider-crawl/runs/20260501``20260509`
- 最新蜘蛛摘要:`code/storage/domain-spider-crawl/latest/spider-crawl.summary.json`
- 站外快照:`seo_external_snapshot`
- 反馈池:`code/data/seo_resource/keyword_feedback/hot_keywords.latest.json`
注意:
1. `2026-05-09` 蜘蛛只统计到上午 `09:50` 左右,不是全日。
2. `keyword_feedback` 是 30 天反馈池,会保留历史爱站词和历史收录信号。
3. 7 日 10 词目标的验收必须以 `seo_external_snapshot` 当日/近两日快照为准,不能把 30 天历史池直接算作当日首页词。
## 2. 今日总判断
7 日目标验收判定:
- 蜘蛛侧:`5月8日明显恢复5月9日上午仍有抓取`
- 百度收录侧:`5月8日 indexed_like=65月9日 indexed_like=5收录面比 Day5 好`
- 爱站首页词侧:`5月8日和5月9日当日 PC 词为 0`
- 反馈池侧:`仍保留 8 个历史爱站关键词,集中在 zbsv3/glae/sdxhtgcl/sdxtwnc`
- 目标结果:`7日10词上首页未达标`
一句话:
> 这 7 天不是完全没效果,蜘蛛和收录信号在 5 月 8 日有明显回升;但首页词没有完成放大,爱站当日词从 5 月 8 日开始归零,说明“收录转首页词”的最后一段没有跑通。
## 3. 蜘蛛趋势
统计口径:`baiduspider + bytespider + sogou`,不把 Googlebot 的 robots/444 噪声计入主判断。
| 日期 | 总量 | 百度 | Byte | Sogou | home | category | detail | play | robots | 200 | 301 | 403 | 444 | 域名数 | 判断 |
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|
| 2026-05-01 | 496 | 343 | 67 | 86 | 281 | 42 | 28 | 22 | 66 | 222 | 158 | 78 | 29 | 26 | Day1 百度强,首页为主 |
| 2026-05-02 | 367 | 198 | 70 | 99 | 122 | 56 | 49 | 40 | 74 | 124 | 133 | 84 | 26 | 25 | 深页最好 |
| 2026-05-03 | 302 | 136 | 83 | 83 | 67 | 48 | 44 | 26 | 69 | 77 | 113 | 76 | 35 | 24 | 异常偏高 |
| 2026-05-04 | 323 | 195 | 68 | 60 | 139 | 34 | 32 | 24 | 65 | 143 | 89 | 63 | 26 | 25 | 有恢复 |
| 2026-05-05 | 371 | 187 | 65 | 119 | 128 | 74 | 29 | 27 | 60 | 132 | 110 | 92 | 35 | 24 | Sogou/分类补量 |
| 2026-05-06 | 263 | 147 | 79 | 37 | 84 | 24 | 41 | 26 | 64 | 102 | 77 | 57 | 27 | 21 | 总量回落,深页尚可 |
| 2026-05-07 | 285 | 180 | 62 | 43 | 118 | 26 | 32 | 28 | 58 | 135 | 70 | 49 | 30 | 23 | 平稳但无放大 |
| 2026-05-08 | 626 | 470 | 80 | 76 | 406 | 46 | 40 | 22 | 85 | 393 | 128 | 78 | 27 | 23 | 明显恢复,百度大幅回访 |
| 2026-05-09 上午 | 229 | 162 | 35 | 32 | 123 | 16 | 27 | 13 | 34 | 103 | 75 | 34 | 16 | 23 | 上午仍有抓取 |
结论:
1. 蜘蛛没有断5 月 8 日是本轮最高点,百度抓取从 5 月 7 日 `180` 升到 5 月 8 日 `470`
2. 深页抓取一直存在,但 `detail+play` 没有形成持续放大5 月 8 日为 `62`5 月 9 日上午为 `40`
3. `301` 仍偏高5 月 8 日 `128`5 月 9 日上午 `75`,会继续消耗蜘蛛预算。
4. 5 月 9 日上午主抓集中在 `jingxifa/glae/sdxtwnc/vikau/codohealth/sjzyunyang`,不是原先所有 S1 主攻站同步起量。
## 4. 今日重点域名
### 4.1 2026-05-09 上午蜘蛛
| 域名 | 总量 | 百度 | home | detail | play | 200 | 301 | 403/444 | 判断 |
|---|---:|---:|---:|---:|---:|---:|---:|---:|---|
| `jingxifa.com` | 26 | 26 | 18 | 0 | 8 | 16 | 10 | 0 | 百度抓取最强,可继续做补位 |
| `glae.cc` | 20 | 20 | 20 | 0 | 0 | 14 | 6 | 0 | 有词、有收录、有首页抓取 |
| `sdxtwnc.com` | 18 | 18 | 18 | 0 | 0 | 12 | 6 | 0 | 首页回访稳定,但词未恢复 |
| `codohealth.com` | 19 | 17 | 0 | 9 | 0 | 8 | 9 | 2 | 有深页,但 301 偏高 |
| `vikau.com` | 20 | 8 | 1 | 10 | 5 | 4 | 4 | 12 | 深页有,异常也重 |
| `sjzyunyang.com` | 8 | 8 | 0 | 8 | 0 | 4 | 4 | 0 | 保深页观察 |
| `cnzhenbang.com` | 22 | 0 | 2 | 0 | 0 | 0 | 10 | 12 | 不适合冲词,只修异常 |
### 4.2 主攻与补位判断
| 域名 | 站外快照 2026-05-09 | 反馈池 | 判断 | 动作 |
|---|---|---|---|---|
| `zbsv3.com` | 百度 unknown爱站 summary 0 | 历史 3 词 | 历史词未形成当日延续 | 只做保词复核,不再按 4 词目标加码 |
| `sdxhtgcl.com` | 百度 unknown爱站 summary 0 | 历史 1 词 | 5月3-5有词5月8-9断 | 保留承接,先查为什么当日词归零 |
| `sdxtwnc.com` | 百度 unknown爱站 summary 0 | 历史 1 词 | 有首页蜘蛛,无当日词 | 做掉词修复,不大改标题 |
| `jingxifa.com` | 百度 failed | 历史 indexed_like | 蜘蛛强但收录快照没跟上 | 保补位,压 301 |
| `codohealth.com` | 百度 unknown | 历史 indexed_like | 深页仍有抓取 | 保补位,压 301 |
| `glae.cc` | 百度 indexed_like爱站 summary 0 | 历史 2 词 | 本轮最稳定样本,但不是原主攻 | 可正式纳入补位目标 |
| `jxxgygy.com` | 百度 indexed_like | 历史 indexed_like | 5月8-9收录连续 | 新增观察,暂不算首页词 |
## 5. 站外快照进度
### 5.1 大盘
| 日期 | 百度 indexed_like | 百度 failed | 百度 unknown | 爱站出词域名 | 爱站 PC 词总数 |
|---|---:|---:|---:|---:|---:|
| 2026-05-01 | 0 | 30 | 2 | 1 | 3 |
| 2026-05-02 | 0 | 28 | 4 | 2 | 3 |
| 2026-05-03 | 2 | 23 | 7 | 2 | 3 |
| 2026-05-04 | 3 | 12 | 17 | 2 | 3 |
| 2026-05-05 | 0 | 26 | 6 | 2 | 3 |
| 2026-05-06 | 1 | 28 | 3 | 1 | 2 |
| 2026-05-07 | 3 | 14 | 15 | 1 | 2 |
| 2026-05-08 | 6 | 7 | 19 | 0 | 0 |
| 2026-05-09 | 5 | 4 | 23 | 0 | 0 |
判断:
1. 百度收录侧变好5 月 8 日和 5 月 9 日分别有 `6/5``indexed_like`
2. 爱站首页词侧变差5 月 8 日、5 月 9 日当日 `pc_keyword_count=0`
3. 这说明当前不是“蜘蛛没来”,而是“页面进入检索结果后,没有稳定转成爱站可见首页词”。
### 5.2 爱站关键词验收
当日 `aizhan_keyword` 记录:
| 日期 | 域名 | PC 词数 |
|---|---|---:|
| 2026-05-01 | `zbsv3.com` | 3 |
| 2026-05-02 | `glae.cc` | 2 |
| 2026-05-02 | `zbsv3.com` | 1 |
| 2026-05-03 | `glae.cc` | 2 |
| 2026-05-03 | `sdxhtgcl.com` | 1 |
| 2026-05-04 | `glae.cc` | 2 |
| 2026-05-04 | `sdxhtgcl.com` | 1 |
| 2026-05-05 | `glae.cc` | 2 |
| 2026-05-05 | `sdxhtgcl.com` | 1 |
| 2026-05-06 | `glae.cc` | 2 |
| 2026-05-07 | `glae.cc` | 2 |
| 2026-05-08 | 无 | 0 |
| 2026-05-09 | 无 | 0 |
结论:
> 7 日目标要求至少 10 个关键词上首页;按当日快照验收,最高稳定可见只有 `3`5 月 8 日和 5 月 9 日为 `0`,目标未达标。
## 6. 真实效果拆解
有效的部分:
1. 蜘蛛回访被拉起来了,尤其 5 月 8 日百度抓取达到 `470`
2. 百度 indexed_like 从 Day5 的 `0` 回升到 5 月 8 日 `6`、5 月 9 日 `5`
3. `glae.cc / jxxgygy.com / chuanjiafeng.net / sdtljq.com / leici1940.com` 等站出现当前收录信号。
无效或不足的部分:
1. 原主攻站 `zbsv3/sdxhtgcl/sdxtwnc` 没有把历史词维持成当日词。
2. `jingxifa/codohealth/vikau` 有蜘蛛或历史收录,但没有稳定产出爱站首页词。
3. `301/403/444` 仍偏高,尤其 `cnzhenbang/vikau/codohealth/jingxifa`,影响抓取质量。
4. GPT 引导文案、AI 承接、关键词反馈闭环已经接入,但目前更像提升了抓取和收录,不足以直接把词推到首页。
## 7. 今天必须调整的策略
### 7.1 目标调整
从今天开始,不再喊“大盘 10 词平均推进”,改成两层目标:
1. 保历史词:`zbsv3.com` 3 个历史词、`sdxhtgcl.com` 1 个历史词、`sdxtwnc.com` 1 个历史词,先确认是否真实还在首页。
2. 收录转词:把 `glae.cc / jxxgygy.com / jingxifa.com / codohealth.com` 作为补位,目标先做 `3` 个稳定可见词。
### 7.2 今日动作
1. `glae.cc` 正式纳入补位主力,因为它同时有历史词和 5 月 9 日百度 `indexed_like`
2. `jxxgygy.com` 进入新观察主力,因为 5 月 8 日、5 月 9 日连续 `indexed_like`,且 5 月 8 日蜘蛛强。
3. `jingxifa.com` 保留补位,但重点不是继续加文案,而是压 `301`,今天上午 `301=10`
4. `codohealth.com` 保 detail 深页,先处理 `301=9`,否则深页蜘蛛会被浪费。
5. `vikau.com` 暂停冲词,先处理异常,今天上午 `403/444=12`
6. `cnzhenbang.com` 不参与冲词,只修 `301/403`
### 7.3 今天不做
1. 不在其它 GPT 源单独改代码。
2. 不把反馈池历史词直接算作今日达标。
3. 不批量换标题。
4. 不继续扩大域名池,先把已出收录信号的站压实。
## 8. 今日结论
这轮 7 日冲刺没有完成“10 个关键词上首页”的硬目标。
但项目不是完全失败,真实进展是:
- 蜘蛛恢复了。
- 百度收录面扩大了。
- 反馈闭环开始起作用。
- 首页词承接能力不足,需要从“引蜘蛛/促收录”切到“保词/转词/降异常”。
下一阶段优先级:
> `glae.cc + jxxgygy.com` 做新增补位,`zbsv3.com + sdxhtgcl.com + sdxtwnc.com` 做历史词复核和保词,`jingxifa.com + codohealth.com` 做深页转词,`vikau.com + cnzhenbang.com` 先修异常。

View File

@@ -0,0 +1,162 @@
# 21 GPT模板 7日后续执行单 2026-05-09
## 1. 执行背景
上一份复盘已经确认:
- 7 日 10 词首页目标未达标。
- 蜘蛛和百度收录信号在 `2026-05-08` 开始恢复。
- 爱站当日首页词在 `2026-05-08``2026-05-09``0`
- 下一阶段不能继续平均推进,要改成 `保历史词 + 收录转词 + 降异常`
本执行单只针对当前 GPT 主测试源,不在其它 GPT 源单独改代码。
## 2. 异常定位
### 2.1 301 判断
用 Baiduspider UA 复查重点域名 HTTP 头:
| 域名/页面 | 当前链路 | 判断 |
|---|---|---|
| `glae.cc/` | `http -> https -> 200` | 正常 canonical 跳转,但日志会记 301 |
| `sdxtwnc.com/` | `http -> https -> 200` | 正常 canonical 跳转 |
| `jingxifa.com/` | `http -> https -> 200` | 正常 canonical 跳转 |
| `codohealth.com/` | `http -> https -> 200` | 正常 canonical 跳转 |
| `vikau.com/` | `http -> https -> 200` | 正常 canonical 跳转 |
| `zbsv3.com/` | `http -> https -> 200` | 正常 canonical 跳转 |
| `codohealth.com/voddetail/...` | `http -> https -> 200` | detail 301 主要来自旧 http URL |
| `jingxifa.com/video-bofang/...` | `http -> https -> 200` | play 301 主要来自旧 http URL |
| `vikau.com/voddetail/...` | `http -> https -> 200` | detail 301 主要来自旧 http URL |
结论:
> 重点站的 301 不是应用死循环,主要是蜘蛛还在抓历史 `http` 地址。处理方向不是取消 301而是把站内入口、sitemap、推送 URL、页面 canonical 全部压到 `https`。
### 2.2 robots 判断
重点站 `robots.txt` 当前均可通过 HTTPS 访问,且都包含:
- `User-agent: Baiduspider`
- `Allow: /`
- `Sitemap: https://{host}/sitemap_index.xml`
结论:
> Baidu robots 没挡。日志里大量 `googlebot/bingbot robots 444` 是噪声,不作为百度 SEO 主问题;但 `vikau/cnzhenbang` 的 Sogou/Bytespider 403/444 仍要降。
## 3. 今日优先级
### 3.1 P0 保词复核
目标:确认历史词是不是真还在首页,避免反馈池误导。
| 域名 | 反馈池状态 | 今日动作 | 结果口径 |
|---|---|---|---|
| `zbsv3.com` | 历史 3 词 | 逐个复核百度首页是否仍在 | 还在则保词,不在则降级 |
| `sdxhtgcl.com` | 历史 1 词5月3-5有当日词 | 复核该词是否掉出 | 掉出则只做恢复,不扩词 |
| `sdxtwnc.com` | 历史 1 词 | 复核是否仍有首页位置 | 无则做掉词修复 |
执行要求:
1. 不改主标题。
2. 不扩新词。
3. 只补该词的首页、分类、搜索承接。
### 3.2 P1 收录转词
目标:从已有收录信号里挑最可能转词的站。
| 域名 | 依据 | 今日动作 |
|---|---|---|
| `glae.cc` | 5月9日 `indexed_like`,反馈池历史 2 词,上午百度 home 20 | 正式纳入补位主力,做 2 词保留与承接 |
| `jxxgygy.com` | 5月8/9 连续 `indexed_like`5月8蜘蛛强 | 作为新补位站,先做 1 个首页词承接 |
| `jingxifa.com` | 上午百度抓取 26含 play 8 | 保留补位,先压首页/play 的 http 入口 |
| `codohealth.com` | 上午 detail 9历史收录信号 | 保 detail 转词,压 detail 旧 http 入口 |
执行要求:
1. `glae.cc` 不再只作为观察样本,可纳入下一轮目标。
2. `jxxgygy.com` 先做 1 词,不扩成多词。
3. `jingxifa/codohealth` 先保深页质量,不盲目换首页词。
### 3.3 P2 降异常
目标:降低蜘蛛预算浪费。
| 域名 | 今日异常 | 动作 |
|---|---|---|
| `vikau.com` | 上午 `403/444=12`detail/play 有抓取 | 暂停冲词,先修 Sogou/Bytespider 403 和异常入口 |
| `cnzhenbang.com` | 上午 `301=10``403/444=12`,百度为 0 | 不参与冲词,只修分类/首页/robots 异常 |
| `codohealth.com` | detail 和 play 同时 200/301 | 统一站内 detail/play 链接为 HTTPS |
| `jingxifa.com` | 首页/play 同时 200/301 | 统一站内首页/play 链接为 HTTPS |
## 4. 今天具体动作
### 4.1 URL 入口统一
必须检查:
1. sitemap 里是否全是 `https://`
2. 首页、分类页、detail、play 的内部链接是否全是 `https://` 或相对路径。
3. 百度推送队列是否还在推 `http://`
4. canonical 是否输出 HTTPS。
验收:
- 新一轮日志里重点域名 Baidu 的 `301` 占比下降。
- `glae/sdxtwnc/jingxifa/codohealth` 首页和深页保持 `200`
### 4.2 承接页处理
P0/P1 域名只做承接,不做大改:
1. 首页:保留主词相关的自然文案。
2. 分类页:加与主词匹配的聚合入口。
3. 搜索页:把历史词和补位词变成可访问搜索结果。
4. detail/play用真实影片标题和相关推荐承接不堆词。
验收:
- 蜘蛛继续抓 `home + detail/play`
- 当日/次日 `aizhan_summary` 恢复到 `pc_keyword_count>0`
### 4.3 域名池收缩
今天不要继续扩域名池。
保留主线:
- 保历史词:`zbsv3.com / sdxhtgcl.com / sdxtwnc.com`
- 收录转词:`glae.cc / jxxgygy.com / jingxifa.com / codohealth.com`
- 修异常:`vikau.com / cnzhenbang.com`
其它站只观察,不加资源。
## 5. 明天验收点
明天看三件事:
1. `2026-05-10` 百度蜘蛛是否继续维持 `300+`,重点看 `glae/jxxgygy/jingxifa/codohealth`
2. 爱站 `pc_keyword_count` 是否从 `0` 恢复到至少 `2`
3. `301/403/444` 是否下降,尤其 `vikau/cnzhenbang/codohealth/jingxifa`
通过线:
- 百度 `indexed_like >= 5`
- 爱站 PC 词 `>= 2`
- 重点站 Baidu `301` 比今天下降
失败线:
- 百度回访仍有,但爱站 PC 词继续 `0`
- `glae.cc` 历史 2 词继续不回
- `vikau/cnzhenbang` 异常不降
## 6. 当前结论
今天继续推进的核心不是再加一轮“AI 文案”,而是把已恢复的蜘蛛和收录信号变成稳定词。
执行顺序:
> 先复核历史词,再保 `glae/jxxgygy` 补位,随后修 `jingxifa/codohealth` 的旧入口 301最后把 `vikau/cnzhenbang` 从冲词池里拿出来专门降异常。

View File

@@ -0,0 +1,146 @@
# 22 GPT模板 Sitemap 与百度推送 URL 规范化修正 2026-05-09
## 1. 背景
7 日验收后继续排查 `301`,发现重点域名的 HTTP 头链路是:
- `http://domain/ -> https://domain/ -> 200`
- `http://domain/detail -> https://domain/detail -> 200`
这说明 `301` 不是应用死循环,而是蜘蛛还在抓旧 HTTP 或旧入口。
继续核查代码和生成产物后,发现更关键的问题:
1. `robots.txt` 指向 `https://domain/sitemap_index.xml`
2. 页面 canonical 多数指向 `https://domain/...`
3. 但 sitemap 模板、生成逻辑、百度推送逻辑里仍有 `https://www.domain/...`
这会造成 `domain``www.domain` 两套规范 URL 并存,削弱收录和首页词承接。
## 2. 本次代码修正
只在当前 GPT 主测试源修改,不改其它 GPT 源,也不动老模板。
### 2.1 动态 sitemap 输出
修改:
- `code/app/services/SiteContext.php`
动作:
- `/rss/so.xml` 动态兼容输出从 `https://www.{host}` 改为 `https://{host}`
### 2.2 GPT 模板 sitemap 文件
修改:
- `code/app/home/view/videoGpt1/rss/so.xml`
- `code/app/home/view/videoGpt1/sitemap/sitemap_index.xml`
- `code/app/home/view/videoGpt1/sitemap/sitemap-main.xml`
- `code/app/home/view/videoGpt1/sitemap/sitemap-books.xml`
- `code/app/home/view/videoGpt1/sitemap/sitemap-books-catalog.xml`
- `code/app/home/view/videoGpt1/sitemap/sitemap-chapters.xml`
动作:
- sitemap 内所有站点 URL 从 `https://www.{$DomainModel->d_domain}` 改成 `https://{$DomainModel->d_domain}`
### 2.3 后台 sitemap 生成逻辑
修改:
- `code/app/task/logic/VideoSiteMapLogic.php`
动作:
1. `sitemap_index.xml` 生成改为 `https://domain/...`
2. `sitemap-main.xml` 生成改为 `https://domain/...`
3. `sitemap-videos-*.xml` 生成改为 `https://domain/...`
4. `sitemap-videos-*.txt` 生成改为 `https://domain/...`
5. `video-list-*.json``href` 改为 `https://domain/...`
6. 修复 `sitemap-videos-*.txt` 追加写入问题:每次生成前先清空 txt避免旧 `https://www.domain/...` 残留。
### 2.4 百度主动推送
修改:
- `code/app/task/logic/BaiduPushVideoUrlLogic.php`
动作:
- 百度推送 API 的 `site=``https://www.domain` 改为 `https://domain`
## 3. 已刷新运行产物
已重生成以下重点域名的 `code/storage/SiteMap/{domain}`
- `zbsv3.com`
- `sdxhtgcl.com`
- `sdxtwnc.com`
- `glae.cc`
- `jxxgygy.com`
- `jingxifa.com`
- `codohealth.com`
- `vikau.com`
- `cnzhenbang.com`
抽查结果:
- `sitemap_index.xml` 输出 `https://domain/sitemap-main.xml`
- `sitemap-main.xml` 输出 `https://domain/`
- `sitemap-videos-1.txt` 输出 `https://domain/...`
- `video-list-1.json``href` 输出 `https://domain/...`
说明:
> 抽查命令里仍会看到 `http://www.sitemaps.org/schemas/sitemap/0.9`,这是 XML 命名空间,不是站点 URL不影响 canonical 判断。
## 4. 验证
已执行:
```bash
php -l code/app/services/SiteContext.php
php -l code/app/task/logic/VideoSiteMapLogic.php
php -l code/app/task/logic/BaiduPushVideoUrlLogic.php
```
结果:
- 三个 PHP 文件均无语法错误。
生成命令:
```bash
php -r 'require __DIR__ . "/vendor/autoload.php"; $app = new think\App(); $app->initialize(); app\common\helper\DomainSitemapGenerationHelper::generateNow(["zbsv3.com","sdxhtgcl.com","sdxtwnc.com","glae.cc","jxxgygy.com","jingxifa.com","codohealth.com","vikau.com","cnzhenbang.com"]);'
```
结果:
- 4 页 sitemap/video-list 全部生成完成。
- 结束时间:`2026-05-09 10:49:49`
## 5. SEO 影响判断
这次修正解决的是 URL 规范化问题,不是直接加词。
预期影响:
1. 减少 `www` 与非 `www` 的 URL 信号分散。
2. 让 robots、canonical、sitemap、百度推送保持同一规范版本。
3. 后续百度抓取里 `http -> https` 的 301 不会立刻归零,但 `www` 相关的分裂入口会逐步减少。
4.`glae/jxxgygy/jingxifa/codohealth` 的收录转词更有利。
明天复查:
1. `2026-05-10` 蜘蛛日志里重点域名的 Baidu `301` 是否下降。
2. `sitemap-videos-*.txt` 是否继续保持非 www。
3. 百度推送摘要里 `site=` 是否不再出现 `https://www.domain`
4. 爱站 `pc_keyword_count` 是否从 `0` 恢复到 `>=2`
## 6. 当前结论
本次属于 7 日失败后的必要技术纠偏。
> 前面的问题不是“AI 文案没用”,而是 URL 规范信号有分裂:页面告诉搜索引擎看非 wwwsitemap/推送却给了 www。现在当前 GPT 主测试源已经统一到非 www下一步看蜘蛛日志中的 301 和爱站词恢复情况。

View File

@@ -40,6 +40,26 @@
作用:给后续 Codex 或技术接手同学,快速说明这轮模板中文化与自动补全到底改了什么。
8. [12-GPT模板导入模板改造交付清单-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/12-GPT模板导入模板改造交付清单-2026-04-18.md)
作用:把本轮模板改造的交付边界、统一口径和验收标准一次性钉住。
9. [13-GPT模板下周7日首页词冲量计划-2026-04-29.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/13-GPT模板下周7日首页词冲量计划-2026-04-29.md)
作用:第二周从“推收录/看回访”升级到“已出词放大、收录转词、代理浏览核验”的 7 日执行计划。
10. [14-GPT模板Day1进度复盘-2026-04-30.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/14-GPT模板Day1进度复盘-2026-04-30.md)
作用:记录 Day1 蜘蛛、百度收录、爱站信息和站点底座复查结果,为后续 7 日计划每日对比提供基线。
11. [15-GPT模板Day2阶段效果复盘-2026-05-01.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/15-GPT模板Day2阶段效果复盘-2026-05-01.md)
作用:继续分析 Day2 蜘蛛日志、百度收录快照、爱站出词变化,给出是否加码、修复或暂缓的阶段判断。
12. [16-GPT模板多源协作边界与真实启用核查-2026-05-01.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/16-GPT模板多源协作边界与真实启用核查-2026-05-01.md)
作用:固定 GPT/老模板多源协作规则,核查 AI 文案、引导文案、外部反馈是否真实进入前台,并记录本次运行时反馈闭环修正。
13. [17-GPT模板7日10词上首页冲刺目标-2026-05-01.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/17-GPT模板7日10词上首页冲刺目标-2026-05-01.md)
作用:把 2026-05-01 到 2026-05-07 的硬目标固定为至少 10 个关键词进入百度首页结果页,并按域名、关键词编号、每日动作和验收口径倒排执行。
14. [18-GPT模板10词冲刺夜间收口执行单-2026-05-01.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/18-GPT模板10词冲刺夜间收口执行单-2026-05-01.md)
作用:记录 Day1 晚上 22:46 的蜘蛛状态,明确夜间冻结大改、锁 K 词、明早验收的执行边界。
15. [19-GPT模板Day5蜘蛛日志与7日进度复盘-2026-05-05.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/19-GPT模板Day5蜘蛛日志与7日进度复盘-2026-05-05.md)
作用:复盘 2026-05-05 上午蜘蛛、百度收录、爱站出词和 7 日 10 词首页目标进度,给出 Day5 资源重排策略。
16. [20-GPT模板7日目标验收与蜘蛛日志复盘-2026-05-09.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/20-GPT模板7日目标验收与蜘蛛日志复盘-2026-05-09.md)
作用:验收 7 日 10 词首页目标,复盘 2026-05-01 到 2026-05-09 蜘蛛、百度收录、爱站出词,并给出下一阶段保词/转词/降异常策略。
17. [21-GPT模板7日后续执行单-2026-05-09.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/21-GPT模板7日后续执行单-2026-05-09.md)
作用:把 7 日验收后的下一步拆成保历史词、收录转词、降异常三条执行线,并明确 2026-05-10 验收口径。
18. [22-GPT模板Sitemap与百度推送URL规范化修正-2026-05-09.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/22-GPT模板Sitemap与百度推送URL规范化修正-2026-05-09.md)
作用:记录当前 GPT 主测试源 sitemap、运行生成逻辑、百度推送 URL 从 `https://www.domain` 统一到 `https://domain` 的代码修正、产物刷新和次日验收口径。
首批 4 站的执行材料也全部放在本目录:

View File

@@ -0,0 +1,278 @@
# 45-老模板每日复盘 - 2026-04-20
## 1. 基础信息
- 复盘日期:`2026-04-20`
- 复盘口径:
- 主判断以 `domestic bots` 为准
- 即:`baiduspider + bytespider + sogou`
- 当前样板站:
- `yagyjt.com`
- `www.ningxiaowei.com`
---
## 2. 今日总判断
- 今天相较 `2026-04-18``2026-04-19`,老模板这条线已经不是“只剩入口层回访”,而是重新回到“首页 + 深页并行抓取”的状态。
- 如果只看全量蜘蛛,今天会被 `googlebot + category 444` 放大噪音带偏。
- 但如果按我们真正关心的国内蜘蛛口径看,今天应判定为:
- `主线没有跑偏`
- `7 日进度继续向前`
- `仍然是部分达标,未到完全达标`
---
## 3. 今日 domestic 口径总量
基于 `2026-04-20` 全日 run 聚合,`baiduspider + bytespider + sogou` 合计:
- 总请求:`592`
- 页面类型:
- `home = 317`
- `detail = 117`
- `robots = 64`
- `other = 58`
- `play = 35`
- `sitemap = 1`
- `category = 0`
- 状态:
- `200 = 308`
- `301 = 204`
- `403 = 56`
- `404 = 13`
- `444 = 11`
- 蜘蛛分布:
- `baiduspider = 488`
- `bytespider = 66`
- `sogou = 38`
重点 host
- `yagyjt.com = 103`
- `www.haotianhaiyuan.com = 46`
- `ctshuhua.com = 42`
- `www.ningxiaowei.com = 36`
- `ningxiaowei.com = 23`
---
## 4. 对比 Day0 与前两天
### 相对 Day02026-04-17
Day0 基线:
- 总请求:`72`
- `detail = 21`
- `play = 4`
- `category = 1`
- `sitemap = 2`
- `200 = 34`
- `301 = 24`
- `444 = 8`
- `403 = 6`
今天:
- 总请求:`592`
- `detail = 117`
- `play = 35`
- `category = 0`
- `sitemap = 1`
- `200 = 308`
- `301 = 204`
- `444 = 11`
- `403 = 56`
结论:
1. 深页量级相比 Day0 已大幅放大
2. `detail + play = 152`,说明百度确实在继续消费老模板深页
3. 但分类层仍然没有起量
4. `301``403` 绝对值仍高,说明抓取面扩大后,入口归一和深页承接仍在吃预算
### 相对 2026-04-18
`2026-04-18` 是入口窗口收缩日:
- 总请求:`36`
- `detail = 0`
- `play = 0`
今天:
- 总请求:`592`
- `detail = 117`
- `play = 35`
结论:
1. `2026-04-18` 的收缩不是主线打坏
2. 今天深页强势回归,说明老模板仍在百度深抓池里
### 相对 2026-04-19
`2026-04-19` 口径结论是:
- 深页已经回归
-`category = 0`
- `sitemap = 0`
- 属于“主线正确、部分达标”
今天继续验证了这一判断:
1. 深页不是一次性回访,而是在继续放量
2. 但分类层仍旧没有抬起
3. sitemap 仍然弱
---
## 5. 样板站 1`yagyjt.com`
## 今日数据
- 总请求:`103`
- 页面类型:
- `detail = 69`
- `play = 23`
- `home = 9`
- `robots = 2`
- 状态:
- `200 = 53`
- `301 = 48`
- `403 = 2`
- 蜘蛛:
- `baiduspider = 101`
- `bytespider = 2`
## 判断
1. 这是今天最明确的“老模板深抓样板站”
2. `detail + play = 92`,说明百度在持续吃这个站的深页
3. `200` 已经高于 `301`
4.`301` 仍然接近 `200`,说明旧 family 到规范 family 的跳转预算仍然偏高
5. 今天没有出现 `444`,入口层纯异常明显比 Day0 干净
## 对目标的意义
- 好消息:
- `yagyjt.com` 已经明显从“是否还在被抓”升级到“深页持续回访”
- 当前卡点:
- 还没看到分类层接力
- 深页承接仍没把 `301` 再压低一大截
---
## 6. 样板站 2`www.ningxiaowei.com`
## 今日数据
- 总请求:`36`
- 页面类型:
- `detail = 28`
- `play = 8`
- 状态:
- `301 = 18`
- `200 = 18`
- 蜘蛛:
- `baiduspider = 36`
同时裸域 `ningxiaowei.com`
- 总请求:`23`
- 页面类型:
- `home = 19`
- `detail = 4`
- 状态:
- `200 = 15`
- `301 = 8`
## 判断
1. `www.ningxiaowei.com` 今天也重新回到了深页持续抓取
2. 但它依旧是 `301 = 200`
3. 说明 `/video-info/...` 这条规范详情链路方向没错,但还没压缩到更短更稳
4. 裸域 `ningxiaowei.com` 还在被打首页与部分详情,说明域名归一信号仍然存在预算消耗
## 对目标的意义
- 好消息:
- 规范详情 family 仍在被百度消费
- 当前卡点:
- `www / 裸域` 维度还有预算分流
- 深页承接仍不够干净
---
## 7. 今天和 7 日目标是否偏差
对照 [34-老模板7天SEO跟踪板-2026-04-17.md](/www/wwwroot/VideoSource2/docs/old-tmp-seo/34-老模板7天SEO跟踪板-2026-04-17.md) 与 [36-老模板首周验收清单-2026-04-17.md](/www/wwwroot/VideoSource2/docs/old-tmp-seo/36-老模板首周验收清单-2026-04-17.md),今天的结论应是:
- `方向正确`
- `结果继续前进`
- `仍属部分达标`
### 已经在进步的部分
1. 深页量级明显高于 Day0
2. `yagyjt.com` 已出现稳定深抓,且 `200 > 301`
3. `www.ningxiaowei.com` 继续保持规范详情深抓
4. `500 = 0`
### 仍然偏差的部分
1. `category_requests = 0`
2. `sitemap_requests = 1`,仍然偏弱
3. `301` 总量仍高
4. `403` 绝对值偏高
5. `www / 裸域` 与旧 family 仍在消耗预算
---
## 8. 7 日进度当前评级
如果把 `2026-04-17` 作为 Day0那么到 `2026-04-20` 这一天7 日进度应打:
- `B 档:部分达标,且比前两天更接近 A 档`
原因:
1. 深页抓取已经不是偶发,而是连续放大
2. 样板站已经能验证“百度仍在吃深页”
3. 但入口层稳定度和分类层起量还不够
4. 所以还不能判定为“首周已完全打穿”
---
## 9. 今天最大进步
1. `yagyjt.com` 深页持续放量,且 `200` 首次明显高于 `301`
2. `www.ningxiaowei.com` 深页继续稳定存在,没有掉出抓取池
3. `2026-04-18` 的入口收缩已经被今天的深抓回归证伪
---
## 10. 今天最大卡点
1. 分类层仍然没有起量
2. sitemap 仍然太弱
3. `301``403` 总量仍高
4. `www.ningxiaowei.com` 的域名归一与详情承接仍未完全收干净
---
## 11. 明天第一步
明天继续只看 4 件事:
1. `category_requests` 能不能从 `0` 抬起来
2. `sitemap_requests` 能不能稳定恢复
3. `yagyjt.com``301` 能不能继续低于 `200`
4. `www.ningxiaowei.com``ningxiaowei.com` 的预算分流能不能继续缩小
---
## 极简结论
> `2026-04-20` 这一天,老模板 SEO 7 日进度继续向前,已经能明确看到百度对样板站深页的持续消费,说明主线没有跑偏;但分类层和 sitemap 仍未起量,`301/403` 预算消耗也还偏高,所以当前最准确的判断仍是“部分达标,但正在接近达标”。

706
domain_probe_results.json Normal file
View File

@@ -0,0 +1,706 @@
[
{
"d_id": 1165,
"domain": "yqshu8.com",
"/": {
"status": "200",
"len": 92684,
"title": "久久精品国产亚洲一区二区,日本免费人成视频播放,国产在线观看免费观看a,欧美激情精品久久久久久不卡,在线观看国产一区二区三区,久久99精品久久只有精品,中文字幕精品一区二区三区视频,国产精品欧美日韩久久久免费观看_言情影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 747,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.yqshu8.com/sitemap-main.xml"
}
},
{
"d_id": 1144,
"domain": "shxmbz.com",
"/": {
"status": "200",
"len": 89980,
"title": "亚洲国产精品视频,免费人妻精品一区二区三区,久久九九日本韩国精品,日韩国产欧美在线观看一区二区_绪米影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 747,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.shxmbz.com/sitemap-main.xml"
}
},
{
"d_id": 1143,
"domain": "8866616.com",
"/": {
"status": "200",
"len": 92431,
"title": "亚洲精品久久一区二区三区,一区二区三区不卡视频,国产精品视频一区二区三区,日本中文字幕在线视频国产高清一区二区三区_卓斯影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 753,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.8866616.com/sitemap-main.xm"
}
},
{
"d_id": 1142,
"domain": "ctshuhua.com",
"/": {
"status": "200",
"len": 140352,
"title": "久久国产精品视频,久久精品视频免费观看,久久久久99,国产精品视频大全,精品在线一区_书华影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 759,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.ctshuhua.com/sitemap-main.x"
}
},
{
"d_id": 1140,
"domain": "zhongshuba.com",
"/": {
"status": "200",
"len": 93370,
"title": "国产91免费视频,91视频在线,91视频观看,免费91视频,91免费视频入口_众书影院",
"snippet": "<html lang=\"zh\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" conte"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 771,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.zhongshuba.com/sitemap-main"
}
},
{
"d_id": 1133,
"domain": "yaleyishu.com",
"/": {
"status": "200",
"len": 92272,
"title": "日韩欧美国产精品,视频一区二区在线,99热精品国产,中文国产日韩欧美_雅乐艺书",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 765,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.yaleyishu.com/sitemap-main."
}
},
{
"d_id": 1132,
"domain": "mwzyj.top",
"/": {
"status": "200",
"len": 140254,
"title": "日韩视频一区二区三区在线播放免费观看,亚洲欧美在线观看视频,久久9999久久免费精品国产,99热在线观看免费精品,99热在线免费观看_谜雾影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 741,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.mwzyj.top/sitemap-main.xml<"
}
},
{
"d_id": 1131,
"domain": "forcnehealthcare.com",
"/": {
"status": "200",
"len": 115622,
"title": "国产99久久精品一区二区永久免费,99在线免费观看,国产99久久久欧美黑人,亚洲精品99久久久久中文字幕,99热在线观看免费精品,99热在线免费观看_富辰影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" c"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 807,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.forcnehealthcare.com/sitema"
}
},
{
"d_id": 1128,
"domain": "qf123.net",
"/": {
"status": "200",
"len": 89377,
"title": "久久久国产精品视频,一区二区中文字幕,久久免费视频在线观看,亚洲欧美一区二区三区国产精品,久久久国产精品久久久_清风影院",
"snippet": "<html lang=\"zh\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" conte"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 741,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.qf123.net/sitemap-main.xml<"
}
},
{
"d_id": 1117,
"domain": "ruantishafa.com",
"/": {
"status": "200",
"len": 89611,
"title": "久久久精品一区,久久久国产精品视频,日韩欧美在线中文字幕,久久国产中文国产午夜精品视频,99亚洲精品久久精品欧美一区_凯佳影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 777,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.ruantishafa.com/sitemap-mai"
}
},
{
"d_id": 1114,
"domain": "haotianhaiyuan.com",
"/": {
"status": "200",
"len": 118326,
"title": "亚洲欧美日韩在线,亚洲欧美日韩综合,国产不卡在线,欧美日韩国产一区,欧美日韩国产免费,亚洲国产高清视频,国产电影在线观看一区_浩天海源影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" c"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 795,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.haotianhaiyuan.com/sitemap-"
}
},
{
"d_id": 1104,
"domain": "qingyejianshe.com",
"/": {
"status": "200",
"len": 116545,
"title": "飘雪影院在线观看免费版高清动漫-飘雪日本高清免费观看电视剧-飘雪影院免费版在线观看视频_飘雪影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" c"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 789,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.qingyejianshe.com/sitemap-m"
}
},
{
"d_id": 1098,
"domain": "gyssjxq.com",
"/": {
"status": "200",
"len": 89755,
"title": "亚洲精品久久一区二区三区,亚洲国产小视频,日本欧美日韩电影免费观看-三江影院",
"snippet": "<html lang=\"zh\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" conte"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 753,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.gyssjxq.com/sitemap-main.xm"
}
},
{
"d_id": 1091,
"domain": "hymdrz.com",
"/": {
"status": "200",
"len": 95456,
"title": "亚洲国产中文字幕在线,一区二区不卡视频,日本在线播放,中文字幕视频一区,欧洲精品一区二区,中文资源在线观看,中文字幕视频在线,一二三区精品视频_金牌影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 747,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.hymdrz.com/sitemap-main.xml"
}
},
{
"d_id": 1090,
"domain": "xcgruister.com",
"/": {
"status": "200",
"len": 140452,
"title": "星辰高清影院_星辰视频在线观看免费观看-星辰影视大全免费版官网",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 771,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.xcgruister.com/sitemap-main"
}
},
{
"d_id": 1088,
"domain": "ap-hulan.com",
"/": {
"status": "200",
"len": 93886,
"title": "久久99国产精品,亚洲在线免费观看视频,91精品国产综合久久精品,91久久国产综合久久91精品网站,日本不卡视频久久免费视频在线观看_虎澜电影院",
"snippet": "<html lang=\"zh\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" conte"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 759,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.ap-hulan.com/sitemap-main.x"
}
},
{
"d_id": 1058,
"domain": "syzhzs.com",
"/": {
"status": "200",
"len": 89734,
"title": "桃花影院-桃花影院电视剧在线播放-影视大全在线免费观看",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 747,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.syzhzs.com/sitemap-main.xml"
}
},
{
"d_id": 1056,
"domain": "sdqzjbh.com",
"/": {
"status": "200",
"len": 140012,
"title": "神马影院-无敌神马影视影院在线-神马达达兔在线电视剧免费大全",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 753,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.sdqzjbh.com/sitemap-main.xm"
}
},
{
"d_id": 1055,
"domain": "sctyjz.com",
"/": {
"status": "200",
"len": 115433,
"title": "午夜影院-热搜短剧大片抢先看-2025最新最好看的电影电视剧免费观看",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" c"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 747,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.sctyjz.com/sitemap-main.xml"
}
},
{
"d_id": 1054,
"domain": "bzxhhjx.com",
"/": {
"status": "200",
"len": 92828,
"title": "樱花影院-樱花影院高清电影好看的电视剧-樱花电影大全免费观看西瓜",
"snippet": "<html lang=\"zh\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" conte"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 753,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.bzxhhjx.com/sitemap-main.xm"
}
},
{
"d_id": 1048,
"domain": "haleyhunt.com",
"/": {
"status": "200",
"len": 89544,
"title": "凡桃影视 - 热门短剧免费在线观看,高清电影电视剧在线播",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 765,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.haleyhunt.com/sitemap-main."
}
},
{
"d_id": 1047,
"domain": "909664.com",
"/": {
"status": "200",
"len": 92482,
"title": "九九六影院 最新热门短剧免费在线观看",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 747,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.909664.com/sitemap-main.xml"
}
},
{
"d_id": 1046,
"domain": "ningxiaowei.com",
"/": {
"status": "200",
"len": 139353,
"title": "宁小微影视 - 免费短剧、电视剧、电影、综艺、动漫免费在线观看",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 777,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.ningxiaowei.com/sitemap-mai"
}
},
{
"d_id": 1045,
"domain": "tvwallmountreview.com",
"/": {
"status": "200",
"len": 114297,
"title": "剧集看点 - 热门短剧全集免费在线观看|电影电视剧动漫在线看",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" c"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 813,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.tvwallmountreview.com/sitem"
}
},
{
"d_id": 1044,
"domain": "proenerji.com",
"/": {
"status": "200",
"len": 92325,
"title": "国产精品99日韩欧美网站,欧美国产精品在线视频日韩一区,日韩欧美视频在线免费观看,欧美视频一区二区三区_剧乐汇",
"snippet": "<html lang=\"zh\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" conte"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 765,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.proenerji.com/sitemap-main."
}
},
{
"d_id": 1037,
"domain": "yahuawang88.com",
"/": {
"status": "200",
"len": 94305,
"title": "亚洲欧美在线观看,日韩欧美中文在线,亚洲欧美精品在线观看,亚洲欧美视频一区,国产欧美精品一区二区三区四区_雅华网",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 777,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.yahuawang88.com/sitemap-mai"
}
},
{
"d_id": 1035,
"domain": "junhaolab.com",
"/": {
"status": "200",
"len": 141689,
"title": "久久久天堂国产精品女人,99视频免费在线观看,久久久国产精品视频,国产精品香蕉在线观看,久久精品欧美一区二区_俊浩辣播影院",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 765,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.junhaolab.com/sitemap-main."
}
},
{
"d_id": 1034,
"domain": "yagyjt.com",
"/": {
"status": "200",
"len": 119202,
"title": "欧美日韩视频在线,欧美中文字幕在线观看,欧美日韩视频,欧美日韩精品,日韩欧美在线观看,欧美日韩视频网站_雅格越剧厅",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" c"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 747,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.yagyjt.com/sitemap-main.xml"
}
},
{
"d_id": 1033,
"domain": "zsxd2020.com",
"/": {
"status": "200",
"len": 88005,
"title": "日韩精品一区二区三区在线播放,99热在线播放,亚洲精品在线免费观看视频,亚洲一区久久,99在线免费观看视频_中石欣达影院",
"snippet": "<html lang=\"zh\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\" conte"
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 759,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.zsxd2020.com/sitemap-main.x"
}
},
{
"d_id": 1017,
"domain": "hygfbw.com",
"/": {
"status": "200",
"len": 93416,
"title": "欧美日韩在线免费观看,一区二区欧美日韩高清免费,国产欧美日韩精品在线,高清欧美日韩一区二区三区在线观看,欧美精品国产第一区二区-海洋馆发布网",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 747,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.hygfbw.com/sitemap-main.xml"
}
},
{
"d_id": 1016,
"domain": "rqgcmc.com",
"/": {
"status": "200",
"len": 92653,
"title": "欧美在线免费看,欧美中文字幕在线播放,一区二区日韩国产精品,欧美中文日韩在线观看,亚洲欧美日韩专区一区二区三区-瑞奇馆传媒城",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 747,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.rqgcmc.com/sitemap-main.xml"
}
},
{
"d_id": 1001,
"domain": "dandanzan.xyz",
"/": {
"status": "200",
"len": 92122,
"title": "蛋蛋赞 - 高清电影电视剧在线观看平台",
"snippet": "<html lang=\"zh-CN\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"> <meta name=\"viewport\""
},
"/rss/so.xml": {
"status": "200",
"len": 109,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> </urlset>"
},
"/sitemap.xml": {
"status": "200",
"len": 765,
"title": "",
"snippet": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"> <sitemap> <loc>https://www.dandanzan.xyz/sitemap-main."
}
}
]