Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
tj_tool
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
牟俊洁
tj_tool
Commits
503eaa36
Commit
503eaa36
authored
Dec 11, 2025
by
白满斌
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
新
parent
9ba65111
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
505 additions
and
81 deletions
+505
-81
BatchDetail.php
app/Console/Commands/BatchDetail.php
+74
-19
BatchExportUserPhone.php
app/Console/Commands/BatchExportUserPhone.php
+60
-35
test.php
app/Console/Commands/test.php
+28
-27
Decryptor.php
app/Http/Services/Decryptor.php
+296
-0
GgongkaoLeidaCrawler.php
app/Http/Services/GgongkaoLeidaCrawler.php
+0
-0
t.php
public/t.php
+47
-0
No files found.
app/Console/Commands/BatchDetail.php
View file @
503eaa36
...
...
@@ -126,7 +126,7 @@ class BatchDetail extends Command
dump
(
$id
,
$max
);
$total
=
0
;
$LeidaModel
->
whereBetween
(
'id'
,
[
$id
,
$max
])
->
select
([
'*'
])
->
chunkById
(
50
,
function
(
$list
)
use
(
&
$LeidaModel
)
{
$LeidaModel
->
whereBetween
(
'id'
,
[
$id
,
$max
])
->
select
([
'*'
])
->
chunkById
(
50
,
function
(
$list
)
use
(
&
$LeidaModel
,
&
$total
)
{
$nowTime
=
time
();
$list
=
$list
->
toArray
();
foreach
(
$list
as
$key
=>
$value
)
{
...
...
@@ -134,13 +134,45 @@ class BatchDetail extends Command
$articleId
=
self
::
getLastNumberFromUrl
(
$value
[
'url'
]);
$str
=
'appid=uqsFgLOVbuPrfn1v&articleId='
.
$articleId
.
'&from_device=h5×tamp='
.
time
()
.
'&token=
569fff2952c0317c29f3308df15cd75d11d15fmern1cdeol3f9tcfo31cdnb3o9o5yd03&userId=26239811
'
;
$str
=
'appid=uqsFgLOVbuPrfn1v&articleId='
.
$articleId
.
'&from_device=h5×tamp='
.
time
()
.
'&token=
3d24d79a5420c8fe1af5d74f71fc72a211d15fk7z41cdeu6tzo6fsl41cdngpeu2j1px4&userId=26137696
'
;
$signStr
=
md5
(
urlencode
(
$str
.
'&secret=Hf6yn1JPb1QZxniWhIPv1IrHbWeLh2e8'
));
$url
=
'https://api.gongkaoleida.com/api/FrontBackSecure/article/detailUserPc?'
.
$str
.
'&sign='
.
$signStr
;
// URL: https://api.gongkaoleida.com/api/FrontBackSecure/article/detailUserPc?appid=uqsFgLOVbuPrfn1v&articleId=2720773&from_device=h5×tamp=1765414971&token=2ada686c9962ad44f0544e43ea24080e11d154q7q71cdesi46q1sey51cdnf0p14eeca5&userId=7941535&sign=7a8a2a3da73e9c762ad6b785f8a882c4
// URL: https://api.gongkaoleida.com/api/FrontBackSecure/article/detailUserPc?appid=uqsFgLOVbuPrfn1v&articleId=2721189&from_device=h5×tamp=1765421999&token=0f196df3dcfbb78b83a4e1d18fc9fe9611d155dxb81cdeo6jkh9wuv81cdnap4evmis78&userId=9047780&sign=6cac7679cb76b1f0b74377d711847687
// https://api.gongkaoleida.com/api/v6_0_3_0/job/jobList?cursor=&branchId=0&examId=717862&page=1&searchKey=&uuid=a5d91f5a-0628-4ad0-84ce-83f8514d13bf&from_device=android×tamp=1765433032&sign=3a45a404bdc9616bcd995185b6890935&appid=8tQhhq32HIxOH72p&osVersion=29&devVersion=6.2.0.0&appLaunchChannel=default&token=f65258b207d7f3a8af87063d74531ba211d15fliu41cdev1qkuochan1cdnhkbf90yemn&userId=26198428
// 13164251418:0f196df3dcfbb78b83a4e1d18fc9fe9611d155dxb81cdeo6jkh9wuv81cdnap4evmis78 -- 9047780
// 17310088217:cbf6a15cf45c95f89a664f3534f64eae11d15fnc6h1cdetb9sj5pczd1cdnftumxibabd -- 26283113
// junjie:f65258b207d7f3a8af87063d74531ba211d15fliu41cdev1qkuochan1cdnhkbf90yemn -- 26198428
$param
=
[
'remindId'
=>
0
,
'articleId'
=>
$articleId
,
'from_device'
=>
'ios'
,
'timestamp'
=>
time
(),
'appid'
=>
'8tQhhq32HIxOH72p'
,
'osVersion'
=>
'29'
,
'devVersion'
=>
'6.2.0.0'
,
'appLaunchChannel'
=>
'default'
,
'token'
=>
'f65258b207d7f3a8af87063d74531ba211d15fliu41cdev1qkuochan1cdnhkbf90yemn'
,
'userId'
=>
'26198428'
,
];
ksort
(
$param
);
$argStr
=
''
;
foreach
(
$param
as
$key
=>
$val
)
{
$argStr
.=
$key
.
"="
.
trim
(
$val
,
' '
)
.
"&"
;
}
$argStr2
=
$argStr
.
'secret=GO1GgDeC1qIr7KcuGfZIGTHk5R3RM1KT'
;
$signStr2
=
md5
(
urlencode
(
$argStr2
));
$url
=
'https://api.gongkaoleida.com/api/v6_0_3_0/article/detail?'
.
$argStr
.
'&sign='
.
$signStr2
;
try
{
$refer
=
$url
;
...
...
@@ -150,31 +182,35 @@ class BatchDetail extends Command
// 获取响应
$statusCode
=
$response
->
getStatusCode
();
$content
=
json_decode
(
$response
->
getBody
()
->
getContents
(),
true
);
$total
++
;
if
(
$statusCode
!=
200
){
dd
(
'状态码异常:'
.
$statusCode
,
$value
[
'id'
],
$content
);
}
if
(
$content
[
'code'
]
!=
1
){
if
(
!
in_array
(
$content
[
'code'
],
[
0
,
1
])
){
dd
(
$value
[
'id'
],
$content
);
}
$sourceData
=
$content
[
'data'
][
'articleInfo'
]
??
[];
if
(
empty
(
$sourceData
)){
dd
(
'数据异常:'
.
$value
[
'id'
]);
}
$from_url
=
$sourceData
[
'sourcePageUrl'
];
$from_title
=
$sourceData
[
'origin'
];
$from_detail
=
json_encode
(
$sourceData
);
$updateData
=
[
'from_url'
=>
$from_url
,
'from_title'
=>
$from_title
,
'from_detail'
=>
$from_detail
,
];
$LeidaModel
->
updateData
([
'id'
=>
$value
[
'id'
]],
$updateData
);
$this
->
saveRetToFile
(
json_encode
(
$content
),
$value
[
'id'
]);
// $sourceData = $content['data']['articleInfo'] ?? [];
// if(empty($sourceData)){
// dd('数据异常:'.$value['id']);
// }
// $from_url = $sourceData['sourcePageUrl'];
// $from_title = $sourceData['origin'];
// $from_detail = json_encode($sourceData);
//
// $updateData = [
// 'from_url' => $from_url,
// 'from_title' => $from_title,
// 'from_detail' => $from_detail,
// ];
// $LeidaModel->updateData(['id'=>$value['id']], $updateData);
dump
(
'done:'
.
$value
[
'id'
])
;
echo
'done:'
.
$value
[
'id'
]
.
' total:'
.
$total
.
' '
;
sleep
(
5
);
sleep
(
3
);
}
catch
(
\Exception
$e
)
{
...
...
@@ -207,4 +243,23 @@ class BatchDetail extends Command
}
/**
* 保存HTML内容到文件
*/
public
function
saveRetToFile
(
string
$html
,
$id
)
:
string
{
$filename
=
$id
.
'.txt'
;
$path
=
storage_path
(
'app/crawled/'
.
$filename
);
// 确保目录存在
if
(
!
is_dir
(
dirname
(
$path
)))
{
mkdir
(
dirname
(
$path
),
0755
,
true
);
}
file_put_contents
(
$path
,
$html
);
return
$path
;
}
}
app/Console/Commands/BatchExportUserPhone.php
View file @
503eaa36
...
...
@@ -17,7 +17,7 @@ class BatchExportUserPhone extends Command
*
* @var string
*/
protected
$signature
=
'leida:gongkao {page : 要爬取的page}'
;
protected
$signature
=
'leida:gongkao {page : 要爬取的page}
{type : 要到哪个type} {area : 要到哪个area}
'
;
/**
* The console command description.
...
...
@@ -37,7 +37,6 @@ class BatchExportUserPhone extends Command
//省-市-0-考试类型-招考公告
public
static
$ksType
=
[
// '公务员' => '-0-0-2-124',
"教师"
=>
"-0-0-59-124"
,
"事业单位"
=>
"-0-0-3-124"
,
"医疗"
=>
"-0-0-60-124"
,
...
...
@@ -58,37 +57,37 @@ class BatchExportUserPhone extends Command
// 1117 => "安徽",
// 1 => "北京",
// 1255 => "福建",
2129
=>
"广东"
,
3191
=>
"甘肃"
,
2290
=>
"广西"
,
2723
=>
"贵州"
,
37
=>
"河北"
,
1849
=>
"湖北"
,
705
=>
"黑龙江"
,
1654
=>
"河南"
,
2429
=>
"海南"
,
1979
=>
"湖南"
,
627
=>
"吉林"
,
878
=>
"江苏"
,
1359
=>
"江西"
,
498
=>
"辽宁"
,
374
=>
"内蒙古"
,
3357
=>
"宁夏"
,
3304
=>
"青海"
,
2500
=>
"四川"
,
1482
=>
"山东"
,
859
=>
"上海"
,
232
=>
"山西"
,
3063
=>
"陕西"
,
19
=>
"天津"
,
2980
=>
"西藏"
,
3390
=>
"新疆"
,
2826
=>
"云南"
,
1004
=>
"浙江"
,
//
2129 => "广东",
//
3191 => "甘肃",
//
2290 => "广西",
//
2723 => "贵州",
//
37 => "河北",
//
1849 => "湖北",
//
705 => "黑龙江",
//
1654 => "河南",
//
2429 => "海南",
//
1979 => "湖南",
//
627 => "吉林",
//
878 => "江苏",
//
1359 => "江西",
//
498 => "辽宁",
//
374 => "内蒙古",
//
3357 => "宁夏",
//
3304 => "青海",
//
2500 => "四川",
//
1482 => "山东",
//
859 => "上海",
//
232 => "山西",
//
3063 => "陕西",
//
19 => "天津",
//
2980 => "西藏",
//
3390 => "新疆",
//
2826 => "云南",
//
1004 => "浙江",
2460
=>
"重庆"
,
3508
=>
"香港"
,
3509
=>
"澳门"
,
3507
=>
"台湾"
,
//
3508 => "香港",
//
3509 => "澳门",
//
3507 => "台湾",
];
...
...
@@ -106,6 +105,9 @@ class BatchExportUserPhone extends Command
{
$initpage
=
$this
->
argument
(
'page'
);
$typeStr
=
$this
->
argument
(
'type'
);
$areaStr
=
$this
->
argument
(
'area'
);
$LeidaModel
=
new
LeidaModel
();
...
...
@@ -122,12 +124,35 @@ class BatchExportUserPhone extends Command
]);
$firstDone
=
false
;
// 是否已处理第一个特殊循环
$found
=
false
;
// 是否找到了起始键, 考试类型从哪个开始
$areafound
=
false
;
// 是否找到了起始键, 考试类型从哪个开始
$lianxuNone
=
0
;
// 连续三次是未爬取到就die;
foreach
(
self
::
$ksArea
as
$pid
=>
$areaName
)
{
// 如果还没找到起始键
if
(
!
$areafound
)
{
// 如果当前键就是起始键
if
(
$pid
==
$areaStr
)
{
$areafound
=
true
;
// 标记已找到
}
else
{
continue
;
}
}
foreach
(
self
::
$ksType
as
$typeName
=>
$typeIds
)
{
// 如果还没找到起始键
if
(
!
$found
)
{
// 如果当前键就是起始键
if
(
$typeName
==
$typeStr
)
{
$found
=
true
;
// 标记已找到
}
else
{
continue
;
}
}
$refer
=
'https://www.gongkaoleida.com/area/3510-0-0-59-124'
;
// 确定当前外层循环的起始页
$startPage
=
$firstDone
==
true
?
1
:
$initpage
;
...
...
@@ -147,7 +172,7 @@ class BatchExportUserPhone extends Command
'Connection'
=>
'keep-alive'
,
'Sec-Ch-Ua'
=>
'"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"'
,
'Referer'
=>
$refer
,
'Cookie'
=>
"Hm_lvt_f721d958b1ffbdd95625a927f9bbe719=1764753040; HMACCOUNT=D3E8E8384EAB7DAC; Hm_lvt_a85566772a4d8c7093230e45128ffa8f=1764753040; _c_WBKFRo=qpwRYzkl3x5zkB59FmtRBA7hNLLyiTF2HfalK5J5; _nb_ioWEgULi=; vipInfo=%7B%22isVip%22%3A0%2C%22vipGrade%22%3A0%2C%22vipExpire%22%3A0%7D; gkld_captchaSecret=2f246381c807d7085d53e20ef141809c; userId=11317419; token=c1c6a9fdf0bea1fe6a46314e3dd8c17111d156qkkr1cdejzbb1znjle1cdn6hw5gc9gxe; acw_
sc__v2=197d84838-b78ec3f20861d54bee402608fc7cc3a5e15a044e3e021f6f64; acw_tc=0b34264217652651756636995ed7562c242228d8abe852a130a3ec737b74dd; Hm_lpvt_a85566772a4d8c7093230e45128ffa8f=1765265176; Hm_lpvt_f721d958b1ffbdd95625a927f9bbe719=1765265176; XSRF-TOKEN=eyJpdiI6Iit0Y3ZzMWFJTnFyZFZQYVU0SU5XQWc9PSIsInZhbHVlIjoiNnNUMWF1MDFvTVpycFpKVHc3cVFuSlYwVTQ1T3RaUVE2MTVsVnVoOVdLaGdlVEpVNUs1WGFNZFk5XC9FSXQ4TkwiLCJtYWMiOiI1NDE3ODQyZjg2YWUyNWEzNjg2ODNmNTJhNDAxMjlmZDMwZDVmYmNmNzBhNjdmNjEwNWY5NzEzZDVhOTAzNDdjIn0%3D; gkld_session=eyJpdiI6IkRtck9JblFURGdcL1RNVU5iRWN4MENBPT0iLCJ2YWx1ZSI6Ikc4T09hMW1QbFpYeEhmQnM0VUlEbkw5d3ZXMTIyZmtEVlFhdlpyT3AzdlwvOElBQkkxM0dFNkhFdnc1aFNnRVZwT2FPa3dUVUx6OGxRdTJGM2ViN2gyb2htVTFZVXhLZHdocjRNbm5wUmdGVXZ1UUdlaU1vVGNwOEpaOHN5SkhSSSIsIm1hYyI6IjczNGQ4ZGU2Y2ExZDdkMTk3ODU0ZGU4N2VjMWRiMGJkMzRkNWQyZDQ2YTc2YzJiMWZiY2RlZWViZGRhODE0ZmM
ifQ%3D%3D"
,
'Cookie'
=>
"Hm_lvt_f721d958b1ffbdd95625a927f9bbe719=1764753040; HMACCOUNT=D3E8E8384EAB7DAC; Hm_lvt_a85566772a4d8c7093230e45128ffa8f=1764753040; _c_WBKFRo=qpwRYzkl3x5zkB59FmtRBA7hNLLyiTF2HfalK5J5; _nb_ioWEgULi=; vipInfo=%7B%22isVip%22%3A0%2C%22vipGrade%22%3A0%2C%22vipExpire%22%3A0%7D; gkld_captchaSecret=2f246381c807d7085d53e20ef141809c; userId=11317419; token=c1c6a9fdf0bea1fe6a46314e3dd8c17111d156qkkr1cdejzbb1znjle1cdn6hw5gc9gxe; acw_
tc=0a09ec3e17653592476737214ebeae1d398493b77b9696dfeea355956a779e; acw_sc__v2=197d84838-b2b66fad0989c27cec1040019734a2073a611a674a08611730; Hm_lpvt_f721d958b1ffbdd95625a927f9bbe719=1765360707; Hm_lpvt_a85566772a4d8c7093230e45128ffa8f=1765360707; XSRF-TOKEN=eyJpdiI6IjRGMlljQVJSWFpweURuKzkzQ2lDY0E9PSIsInZhbHVlIjoiS3RLbXlBVkM4V0lUZTh1aExUa2ZtaWRLSnhUNzlDUzJGb2NsY3ZBRjROdHZpNmJTR3lWV2gxa2JwSWRrMVlLOCIsIm1hYyI6IjMwNjM2Njg5MzJhNWExNmNkMzliZDkzMTAzYjQxZjYwOTYzNDc1YmI3MzhiNTAxZmI1ZjEzM2YyNGFiMDkxMWYifQ%3D%3D; gkld_session=eyJpdiI6IklKWXdUalwvdTJVTkhJSkpsQzBTV1NBPT0iLCJ2YWx1ZSI6IkJWZkQ0aUdMeEVqT0ptUkJGM3B6SW5aVmdSSTMzUHl3VFN6a3NDRmZUZWxvY0xIRVZONFhiOTA3SDRHZ2NQZnpzQzBzRXhTZEtYZzkzbWNiUXBiZFwvazdiU0VrV0pMWldRNVRKdWZFVTg4UXVrSmdqOWlOWmRUdjlvbjJ1blY1UyIsIm1hYyI6Ijk0N2QwNGI0MWUzZDJmZmM1OGZiYTJjOTk5OWI0OGFiZjQ2NjFmODQyZTM4MGZlMmE1OWJiNDM3OWE4NDRhYjI
ifQ%3D%3D"
,
];
$refer
=
$url
;
...
...
@@ -162,7 +187,7 @@ class BatchExportUserPhone extends Command
// dd($content, $url);
// Storage::put('1.html', $content);
$ret
=
BaseService
::
htmlExplain
(
$url
,
$content
,
$areaName
);
sleep
(
7
);
sleep
(
6
);
if
(
$lianxuNone
>=
3
){
...
...
app/Console/Commands/test.php
View file @
503eaa36
...
...
@@ -6,7 +6,7 @@ use Illuminate\Console\Command;
use
GuzzleHttp\Client
;
use
GuzzleHttp\Cookie\CookieJar
;
use
Illuminate\Support\Facades\Cache
;
use
App\Http\Services\Decryptor
;
class
test
extends
Command
{
protected
$signature
=
'crawl:dynamic-token'
;
...
...
@@ -20,38 +20,39 @@ class test extends Command
public
function
handle
()
{
// 示例加密数据
$encryptedData
=
"K0retCPdI@kG41DJ5wRYc-W8RT9NsePsLMAknEnd4g7KeOxkrlicfiHfb*tts8VRwSzrjpguE1CYpfZH0\/8epwIayZrEoL5qFWBbhaBhzwLmYvuqRdBhQdWJ8yHbo362R8iHfiD+q66DYjwMZp2WPKtCjzQVtGHXU1qdFWm\/JSFeDjuYk8ZRivh0TTuuqUjlek+2RF8e16bIVFfScB+cLrImNFo1l\/fL7bPtpFDyZRdWVXnKZ\/iRLiLZAiAtTqB6VgpanceHU69NMLwqn3p7fQ6rqeZc6qINxZSOaMf53S\/Yqw2J5g2PzlQ+xpyhVv\/WiuIATqFy1ZWWWg9UeHbWa3PAywmZ201dvOMZatR03RC\/CsOVRKYNkFVYoIg7ECPKDMdZh70R9vwWYqivFde07G8+iStPC\/egJMp64GodBh2aKqwyv8\/3Hmy8UCB8zPobJGeKHE0nNUUpcCsBAMXKs4lQWqtyISFTXqEcXB\/ciISWjSN68k0gdCEoE0xDOdIayWsAS4ptwRTz\/SCNz7GHgcSIzar3RsKXVlvo\/R9jVCRekR5\/hLIovp\/phgHRMiKBSKp9\/HrvwN0rpsZULDy7iwmkX95C4RCWs8JDo3dczdeoVJz9HLCdInF9Fsi3K7+pEeTxNtL5pEBnjclvE1LCL9Nz+dGtt5RfIWADUyQkzQcbqvaPz8\/FTIINMC9hYYgTOx93nurSdG1bgjZTgMxxcGsHEGgxuGAc7U+hxRdALOHQbiFr9K1h4+PN1Ik79T6POvtoowPTO92goA+muISy8DWls2Whal9\/TFlAvqXI1rRzbJ6EU8GWHl1qtGRBoV7vGFanfbWPubOh1A74i2VysQdQJXh0wuHDU88h5otDNuvLLs39yhYVJfZJQCM9QnlLgEHtxU7sWZP+39pCDzn33mU6YxTxp6CkzJeWUoy555LtzSoHvwmOwQyiDG7XhnHYt41WYO7mTT7B+eJH7ev1mHoqPUAuFZa+yv27V5FifE8+\/3LjNdZ+tfXdCRAdOEn7H7gw\/MVuBpuFaVlbtSUiNNksVTzbCRD9xMzuTvClvJwWmS9q\/Iu37yx7CyPiHEG\/0KSVOKEFn8GPKjpjw2FoQO8ScDFKLclhNIzo0qIUAdmSHOnn8VzDFUrfNgTON1sDSQ2gA\/FTYNYl+oaZL1l57LoCviaJHdbcGQZ2qZbsqmPGaF5BkvwMJ6bWJWDpMA\/8VcpPYj\/mvRiA+aJfeB\/U61YwNDGJ17Ac8SGOCBItL5eEchk993Mq2FR\/ziKNKZb10r5IRsgns5pPn7GoJT\/83vyprEQuMrNAu7xuL\/pcda1xTH35eFS9E5A\/CvdxeYgjCGl0gvpSOAxCSF5HtlFgZ\/PCAVyTMyKMZbKwdxA2LPZ+nQpM19mwRKiKvo57Giu74wCjUhvz\/95kAUWdsgQUa6dYsDPuqKhL5Qr6dN2DNojpb8WLZ3zhZIwPZHWIF5ogqiQwZPwlryadIo1tqveqZbTQ0SOJ8HJZ0DuDTWUXrzAQPWgCw\/\/6aWtSmuOgUGDBeVM2BxK77LUHeYngIuKyb4wiPymx8OHo\/KZWTymcmyrLi5+pQMsoITVgq5oDNZpUSFzIfnqqjduplmszyKphHddmfcBqb5qFaeSjnH7XQNWmYiigo8moCN3KveJHcoBcPnfJiyaOjfvpLaUgnuZYbAnIW5bayPQZKiIphTB1CnMN9GQOwuOlhcF3\/dMdIyjofne7wzKPIm1dgaQtGOvfdU5NZYzmczniHwhDuQpLs0J8TZg1\/DZ1Y6HuhMDH6hycOm7LTE+XvDaQLrKWpKT5\/ObVNMQWtQsyTSuXuvnYqJV6+8DUvs70CmislkNa4LeCLisQE2F1hwbBcMR9ZY4Wuw9MWnaqoYwm8z5GYZkVoKta125fk\/GcdmxvNfX2GT8iUAwIaubr0u2BXKV4ncIIUAhkW4kynIfYY\/18eTmrpaZUVhfcuFSZvSYWQEDUqPJM8s+8rnp6uMMCpVIGw3l5+PW2gkOMC1ncbpGvB4MXSoILrMQQXcj2fzQ8T\/uuZAwqZgGjuE141PuHRd4aJp8MCac5rJIQ9aE1wLzheZHVqG6602TaugjPray74ztjb5XgPzNOvZqF2HpUuAogyVYza++1BuN7uCAV0ofCdrA73iILOKZm0j0+mOi94TngskhdfoX3opS1Pjv17hSH3Jyg29B\/6JG7FHKzuC+78HRBxdxS16mjTG\/6d+rv\/CzBq5YKkJhe7uhy3v1IGrK7d0S9LZklJmcF+jIO8vXc6VHsaytmi5zXB\/+dUAExuz02ubupFFdl\/mw4xyTaG1BTcw+ScRihz7ai0IeC7e8T1RsFsj5ZlWIT6GDyf9TQnesgpOViCa\/kfcJb6LwJF3EN0T4pJYWHtlZ5lGcF6sB3fCMkk1Ry+LDVrtyQqLsSyuOV\/\/Hl3bW16ikfyYMRDlJZE+8n0vAfJcyN5\/5s4kUb2Ir4gIIZp5O8N7JKvGJRiw9XNiK\/qlHFUVrZOIFeWGR0akiGp0OM7\/kHs4QsZnwUp3bxLk4Nu4w5fTurCTOyjdJ+I6pGjnhjTAZW32NGkqrythcOfppcfjsw\/BuODICaidoGVUUtJruyGpqqomehxGQiueJXsAWOAFrDJ5OulO79kcIKxop7UOE8DQUAZnQOBeQe0UmkgN6WoRcQ41wRP1w19j9b1apw4k\/j\/MYefPFMTfaJiTQNPO5MKo3uqk8nwx3tXJATmxe+F+wYig9ZrdsmEWs5kt+RCY0xISn9K02\/S3WacQArfmj02vdsyzBrUBkP0JrZCo6H7VCdIrFdAk1nsB67+DzkDTrJwlnb7G0OUnMH8QBv5oPHU2CJc\/YHxme+zEszsg6MEedNdrEM+oPEsP3LY2mlqWcSN6GljqqctBSk0QDEBA84W9B+Y1whW09w46isyLsulrctBu8ETqvpeATEeFJWHvirVXVYv3er1+H84KV2uZxQXRYv15Sbq44\/msseWRDsdVcmP5ibihwAOFUOrr9DwnR+urX5CoSc\/EwJJ+t6WV+WWziUY4P2h\/52txc4dlB1meT8x0Jy9iWmMtTsNKv\/xscsv7jyrmoSfaKEBjWcUvkNi0iJjffQP55qxNbQnk4aUh42u7euSXjgS3YKwCdf+J3Tyif1JDEgd02hNhdy+bQ6i3WiDPZ8hVwcJHlAEY7E+VZ5Qc9zUyNaV6G1CjtAp4oiEYQgXKL55DbmMAD+UHeWCNf5jIPG0dZcdeSTTeDFBKLICVRSLxjIsIMYNwoISWmVoSJJRbR42c4Y6XlppE7gbAqUsr+dUiq2jrb70xCrlu5DJyOQZXOAp2WocSJEJsA6Wmduv10XPQRMm\/SSwVWgtRwlHszr5pBZUvqYMkggA6xzDeJ9YsqKf99x6C3gHROgeeS6uRiWVZtyVh6p7uHTtxG7aL6qEaQwsyheC09tI+3Yr5isaLxVBUDLYtG6mjaqKdNImtGEj9WxO9kuEZmqdBE4Au40jGGMRm5OTF+uTKdTzN2z6ZSJAv+\/EjZULRHmpkShdiWaH5qvJ7PxlxYpQ=="
;
try
{
// 方法1:简单解密
$decrypted
=
Decryptor
::
decrypt
(
$encryptedData
);
// https://api.gongkaoleida.com/api/FrontBackSecure/article/detailUserPc?appid=uqsFgLOVbuPrfn1v&articleId=2716421&from_device=h5×tamp=1765185164&token=569fff2952c0317c29f3308df15cd75d11d15fmern1cdeol3f9tcfo31cdnb3o9o5yd03&userId=26239811&sign=a11b430c7a5610930bd603b7c6d05df5
// https://api.gongkaoleida.com/api/FrontBackSecure/article/detailUserPc?appid=uqsFgLOVbuPrfn1v&articleId=2455556&from_device=h5×tamp=1765185842&token=c1c6a9fdf0bea1fe6a46314e3dd8c17111d156qkkr1cdejzbb1znjle1cdn6hw5gc9gxe&userId=11317419&sign=ebf4a4832ade58f2a45b772d273a838c
// https://api.gongkaoleida.com/api/FrontBackSecure/article/detailUserPc?appid=uqsFgLOVbuPrfn1v&articleId=2305006&from_device=h5×tamp=1765251531&token=569fff2952c0317c29f3308df15cd75d11d15fmern1cdeol3f9tcfo31cdnb3o9o5yd03&userId=26239811&sign=31b7c0372a445598bbbe40aabb987acc
$s
=
'appid=uqsFgLOVbuPrfn1v&articleId=2305006&from_device=h5×tamp=1765251531&token=569fff2952c0317c29f3308df15cd75d11d15fmern1cdeol3f9tcfo31cdnb3o9o5yd03&userId=26239811'
;
$s
.=
'&secret=Hf6yn1JPb1QZxniWhIPv1IrHbWeLh2e8'
;
dd
(
md5
(
urlencode
(
$s
)),
$s
);
dd
(
333
);
$this
->
initializeClient
();
// 1. 启动会话
$this
->
startSession
();
// 2. 爬取目标页面
$url
=
$this
->
argument
(
'url'
);
$result
=
$this
->
smartRequest
(
$url
);
// 方法2:获取详细结果
$result
=
Decryptor
::
decryptWithResult
(
$encryptedData
);
dd
(
$result
);
if
(
$result
[
'success'
])
{
$this
->
processResult
(
$result
);
dd
([
'success'
=>
true
,
'data'
=>
json_decode
(
$result
[
'data'
],
true
),
// 假设返回JSON
'original'
=>
$encryptedData
]);
}
else
{
dd
([
'success'
=>
false
,
'error'
=>
$result
[
'error'
],
'exception'
=>
$result
[
'exception'
]
?
$result
[
'exception'
]
->
getMessage
()
:
null
],
400
);
}
}
catch
(
\Exception
$e
)
{
dd
([
'success'
=>
false
,
'error'
=>
'Decryption failed'
,
'message'
=>
$e
->
getMessage
()
],
500
);
}
return
0
;
}
...
...
app/Http/Services/Decryptor.php
0 → 100755
View file @
503eaa36
<?php
namespace
App\Http\Services
;
use
Exception
;
/**
* 对应Java的C21499a类
* 实现AES解密、GZIP解压和特定数据格式处理
*/
class
Decryptor
{
/**
* 主要解密方法,对应Java的m111788d/d方法
* @param string $data 加密数据
* @return string 解密后的数据
*/
public
static
function
decrypt
(
string
$data
)
:
string
{
$result
=
self
::
decryptWithResult
(
$data
);
return
$result
[
'success'
]
?
$result
[
'data'
]
:
$data
;
}
/**
* 详细的解密方法,返回包含状态的结果
* @param string $data 加密数据
* @return array 解密结果
*/
public
static
function
decryptWithResult
(
string
$data
)
:
array
{
$sb
=
$data
;
$iIndexOf
=
strpos
(
$data
,
"dI@kG"
);
$str
=
"fdi7/mzlL2iar+hn0tz0Ev/Y8enbWJpt"
;
$z
=
false
;
$string
=
null
;
if
(
$iIndexOf
!==
false
)
{
$i2
=
$iIndexOf
+
5
;
$i3
=
$i2
+
1
;
if
(
$i2
<
strlen
(
$data
))
{
$strValueOf
=
$data
[
$i2
];
$intValue
=
intval
(
$strValueOf
);
if
(
$intValue
==
1
||
$intValue
==
3
)
{
$sb
=
substr
(
$sb
,
0
,
$iIndexOf
)
.
substr
(
$sb
,
$i3
);
$string
=
$sb
;
if
(
$intValue
==
3
)
{
$z
=
true
;
}
}
elseif
((
$intValue
==
2
||
$intValue
==
4
)
&&
$i3
<
strlen
(
$data
))
{
$i4
=
intval
(
$data
[
$i3
]);
$sb
=
substr
(
$sb
,
0
,
$iIndexOf
)
.
substr
(
$sb
,
$i2
+
2
);
$string2
=
$sb
;
$i5
=
$i4
+
64
;
if
(
$i5
<
strlen
(
$string2
))
{
$strSubstring
=
substr
(
$string2
,
$i4
,
64
);
$strSubstring2
=
(
$i4
%
2
==
1
)
?
substr
(
$strSubstring
,
0
,
32
)
:
substr
(
$strSubstring
,
32
,
32
);
$sb2
=
''
;
for
(
$i6
=
0
;
$i6
<
strlen
(
$strSubstring2
);
$i6
++
)
{
$cCharAt
=
$strSubstring2
[
$i6
];
if
(
ctype_digit
(
$cCharAt
))
{
$sb2
.=
((
intval
(
$cCharAt
)
<<
$i4
)
%
10
);
}
else
{
$sb2
.=
$cCharAt
;
}
}
$string3
=
$sb2
;
$sb3
=
substr
(
$string2
,
0
,
$i4
)
.
substr
(
$string2
,
$i5
);
$string
=
$sb3
;
$z
=
(
$intValue
==
4
);
$str
=
$string3
;
}
else
{
$str
=
"shdshdi&1232sndh+*aspqw"
;
$string
=
null
;
}
}
}
}
if
(
$string
===
null
)
{
return
[
'success'
=>
false
,
'data'
=>
$data
,
'error'
=>
'No valid data to decrypt'
,
'exception'
=>
null
];
}
try
{
$keyBytes
=
self
::
stringToBytes
(
$str
);
$aVar
=
self
::
decryptCore
(
$string
,
$keyBytes
,
$z
);
if
(
$aVar
[
'success'
])
{
return
$aVar
;
}
else
{
if
(
$aVar
[
'exception'
]
!==
null
)
{
// 记录异常,但继续执行
error_log
(
"Decryption exception: "
.
$aVar
[
'exception'
]
->
getMessage
());
}
return
[
'success'
=>
false
,
'data'
=>
$data
,
'error'
=>
$aVar
[
'error'
],
'exception'
=>
$aVar
[
'exception'
]
];
}
}
catch
(
Exception
$e
)
{
error_log
(
"Decryption failed: "
.
$e
->
getMessage
());
return
[
'success'
=>
false
,
'data'
=>
$data
,
'error'
=>
'Decryption failed: '
.
$e
->
getMessage
(),
'exception'
=>
$e
];
}
}
/**
* 核心解密方法,对应Java的m111790b/b方法
* @param string $encryptText 加密文本
* @param array $key 密钥字节数组
* @param bool $isGzip 是否GZIP压缩
* @return array 解密结果
* @throws Exception
*/
private
static
function
decryptCore
(
string
$encryptText
,
array
$key
,
bool
$isGzip
)
:
array
{
try
{
// Base64解码
$bArrDecode
=
base64_decode
(
$encryptText
);
if
(
$bArrDecode
===
false
)
{
throw
new
Exception
(
"Base64 decode failed"
);
}
$bArrDecodeBytes
=
self
::
stringToBytes
(
$bArrDecode
);
$length
=
count
(
$bArrDecodeBytes
);
// 检查长度是否为16的倍数
if
(
$length
%
16
!=
0
)
{
throw
new
Exception
(
"need 16X"
);
}
// 准备AES解密
$keyString
=
self
::
bytesToString
(
$key
);
$decrypted
=
openssl_decrypt
(
$bArrDecode
,
'AES-128-ECB'
,
$keyString
,
OPENSSL_RAW_DATA
);
if
(
$decrypted
===
false
)
{
throw
new
Exception
(
"AES decryption failed"
);
}
$bArr
=
self
::
stringToBytes
(
$decrypted
);
// 应用自定义块处理
$bArr2
=
array_fill
(
0
,
$length
,
0
);
// 处理第一个块
$firstBlock
=
array_slice
(
$bArr
,
0
,
16
);
$transformedFirst
=
self
::
transformKey
(
$firstBlock
);
array_splice
(
$bArr2
,
0
,
16
,
$transformedFirst
);
// 处理后续块
$i2
=
16
;
while
(
$i2
<
$length
)
{
$i3
=
$i2
+
16
;
$block
=
array_slice
(
$bArr
,
$i2
,
16
);
$transformedBlock
=
self
::
transformKey
(
$block
);
for
(
$i4
=
0
;
$i4
<
16
&&
(
$i2
+
$i4
)
<
$length
;
$i4
++
)
{
$bArr2
[
$i2
+
$i4
]
=
$transformedBlock
[
$i4
]
^
$bArrDecodeBytes
[(
$i2
-
16
)
+
$i4
];
}
$i2
=
$i3
;
}
// 转换为字符串
$decryptedString
=
self
::
bytesToString
(
$bArr2
);
$strTrim
=
trim
(
$decryptedString
);
// 如果是GZIP压缩,则解压
if
(
$isGzip
)
{
$decompressed
=
self
::
gzipDecompress
(
$bArr2
);
if
(
$decompressed
!==
null
)
{
$strTrim
=
$decompressed
;
}
}
return
[
'success'
=>
true
,
'data'
=>
$strTrim
,
'error'
=>
null
,
'exception'
=>
null
];
}
catch
(
Exception
$e
)
{
return
[
'success'
=>
false
,
'data'
=>
null
,
'error'
=>
'failed: '
.
$e
->
getMessage
(),
'exception'
=>
$e
];
}
}
/**
* 密钥转换方法,对应Java的m111787c方法
* @param array $block 16字节块
* @return array 转换后的16字节块
*/
private
static
function
transformKey
(
array
$block
)
:
array
{
$result
=
array_fill
(
0
,
16
,
0
);
for
(
$i
=
0
;
$i
<
16
;
$i
++
)
{
$value
=
$block
[
$i
]
&
0xFF
;
$xorred
=
$value
^
$i
;
$shifted
=
$xorred
>>
1
;
$result
[
$i
]
=
((
$xorred
<<
7
)
|
$shifted
)
&
0xFF
;
}
return
$result
;
}
/**
* GZIP解压方法,对应Java的m111786a方法
* @param array $data 字节数组
* @return string|null 解压后的字符串
*/
private
static
function
gzipDecompress
(
array
$data
)
:
?
string
{
try
{
$bytesString
=
self
::
bytesToString
(
$data
);
// 尝试使用gzdecode解压
$decompressed
=
@
gzdecode
(
$bytesString
);
if
(
$decompressed
===
false
)
{
// 如果失败,尝试使用gzinflate
$decompressed
=
@
gzinflate
(
substr
(
$bytesString
,
10
,
-
8
));
if
(
$decompressed
===
false
)
{
throw
new
Exception
(
"GZIP decompression failed"
);
}
}
return
$decompressed
;
}
catch
(
Exception
$e
)
{
error_log
(
"GZIP decompression error: "
.
$e
->
getMessage
());
return
null
;
}
}
/**
* 辅助方法:字符串转字节数组
* @param string $str 字符串
* @return array 字节数组
*/
private
static
function
stringToBytes
(
string
$str
)
:
array
{
return
array_values
(
unpack
(
'C*'
,
$str
));
}
/**
* 辅助方法:字节数组转字符串
* @param array $bytes 字节数组
* @return string 字符串
*/
private
static
function
bytesToString
(
array
$bytes
)
:
string
{
$chars
=
array_map
(
'chr'
,
$bytes
);
return
implode
(
''
,
$chars
);
}
/**
* 对应Java的m111789e方法(虽然未使用,但保留)
* @param array $signedBytes 有符号字节数组
* @return array 无符号字节数组
*/
public
static
function
toUnsignedBytes
(
array
$signedBytes
)
:
array
{
$result
=
[];
foreach
(
$signedBytes
as
$byte
)
{
$result
[]
=
$byte
&
0xFF
;
}
return
$result
;
}
}
\ No newline at end of file
app/Http/Services/GgongkaoLeidaCrawler.php
deleted
100755 → 0
View file @
9ba65111
This diff is collapsed.
Click to expand it.
public/t.php
View file @
503eaa36
...
...
@@ -131,3 +131,50 @@ if ($mainContent->length > 0) {
?>
<?php
namespace
App\Http\Controllers
;
use
App\Http\Controllers\Controller
;
use
App\Utils\Decryptor
;
class
DecryptionController
extends
Controller
{
public
function
decryptData
()
{
// 示例加密数据
$encryptedData
=
"1V167UQdI@kG46qz9ERADHf7UcYGbEX/05GD/3mxnCSUlgSRrxT5UFfjKWS*+MYww..."
;
try
{
// 方法1:简单解密
$decrypted
=
Decryptor
::
decrypt
(
$encryptedData
);
// 方法2:获取详细结果
$result
=
Decryptor
::
decryptWithResult
(
$encryptedData
);
if
(
$result
[
'success'
])
{
return
response
()
->
json
([
'success'
=>
true
,
'data'
=>
json_decode
(
$result
[
'data'
],
true
),
// 假设返回JSON
'original'
=>
$encryptedData
]);
}
else
{
return
response
()
->
json
([
'success'
=>
false
,
'error'
=>
$result
[
'error'
],
'exception'
=>
$result
[
'exception'
]
?
$result
[
'exception'
]
->
getMessage
()
:
null
],
400
);
}
}
catch
(
\Exception
$e
)
{
return
response
()
->
json
([
'success'
=>
false
,
'error'
=>
'Decryption failed'
,
'message'
=>
$e
->
getMessage
()
],
500
);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment