@@ -392,7 +392,7 @@ def album_comment(self,
392
392
)
393
393
394
394
resp = self .post ('/ajax/album_comment' ,
395
- headers = JmModuleConfig .album_comment_headers ,
395
+ headers = self .album_comment_headers ,
396
396
data = data ,
397
397
)
398
398
@@ -467,6 +467,26 @@ def check_special_http_code(cls, resp):
467
467
+ (f'URL=[{ url } ]' if url is not None else '' )
468
468
)
469
469
470
+ album_comment_headers = {
471
+ 'authority' : '18comic.vip' ,
472
+ 'accept' : 'application/json, text/javascript, */*; q=0.01' ,
473
+ 'accept-language' : 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' ,
474
+ 'cache-control' : 'no-cache' ,
475
+ 'content-type' : 'application/x-www-form-urlencoded; charset=UTF-8' ,
476
+ 'origin' : 'https://18comic.vip' ,
477
+ 'pragma' : 'no-cache' ,
478
+ 'referer' : 'https://18comic.vip/album/248965/' ,
479
+ 'sec-ch-ua' : '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"' ,
480
+ 'sec-ch-ua-mobile' : '?0' ,
481
+ 'sec-ch-ua-platform' : '"Windows"' ,
482
+ 'sec-fetch-dest' : 'empty' ,
483
+ 'sec-fetch-mode' : 'cors' ,
484
+ 'sec-fetch-site' : 'same-origin' ,
485
+ 'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
486
+ 'Chrome/114.0.0.0 Safari/537.36' ,
487
+ 'x-requested-with' : 'XMLHttpRequest' ,
488
+ }
489
+
470
490
471
491
# 基于禁漫移动端(APP)实现的JmClient
472
492
class JmApiClient (AbstractJmClient ):
@@ -556,7 +576,7 @@ def fetch_detail_entity(self, apid, clazz):
556
576
url ,
557
577
params = {
558
578
'id' : apid ,
559
- }
579
+ },
560
580
)
561
581
562
582
self .require_resp_success (resp , url )
@@ -571,11 +591,13 @@ def fetch_scramble_id(self, photo_id):
571
591
resp = self .req_api (
572
592
self .API_SCRAMBLE ,
573
593
params = {
574
- "id" : photo_id ,
575
- "mode" : "vertical" ,
576
- "page" : "0" ,
577
- "app_img_shunt" : "1" ,
578
- }
594
+ 'id' : photo_id ,
595
+ 'mode' : 'vertical' ,
596
+ 'page' : '0' ,
597
+ 'app_img_shunt' : '1' ,
598
+ 'express' : 'off' ,
599
+ 'v' : time_stamp (),
600
+ },
579
601
)
580
602
581
603
scramble_id = PatternTool .match_or_default (resp .text ,
@@ -713,21 +735,41 @@ def favorite_folder(self,
713
735
return JmPageTool .parse_api_to_favorite_page (resp .model_data )
714
736
715
737
def req_api (self , url , get = True , ** kwargs ) -> JmApiResp :
716
- # set headers
717
- headers , key_ts = self .headers_key_ts
718
- kwargs ['headers' ] = headers
738
+ ts = self .decide_headers_and_ts (kwargs , url )
719
739
720
740
if get :
721
741
resp = self .get (url , ** kwargs )
722
742
else :
723
743
resp = self .post (url , ** kwargs )
724
744
725
- return JmApiResp .wrap (resp , key_ts )
745
+ return JmApiResp (resp , ts )
746
+
747
+ # noinspection PyMethodMayBeStatic
748
+ def decide_headers_and_ts (self , kwargs , url ):
749
+ # 获取时间戳
750
+ if url == self .API_SCRAMBLE :
751
+ # /chapter_view_template
752
+ # 这个接口很特殊,用的密钥 18comicAPPContent 而不是 18comicAPP
753
+ # 如果用后者,则会返回403信息
754
+ ts = time_stamp ()
755
+ token , tokenparam = JmCryptoTool .token_and_tokenparam (ts , secret = JmMagicConstants .APP_TOKEN_SECRET_2 )
756
+
757
+ elif JmModuleConfig .use_fix_timestamp :
758
+ ts , token , tokenparam = JmModuleConfig .get_fix_ts_token_tokenparam ()
759
+
760
+ else :
761
+ ts = time_stamp ()
762
+ token , tokenparam = JmCryptoTool .token_and_tokenparam (ts )
763
+
764
+ # 计算token,tokenparam
765
+ headers = kwargs .get ('headers' , JmMagicConstants .APP_HEADERS_TEMPLATE .copy ())
766
+ headers .update ({
767
+ 'token' : token ,
768
+ 'tokenparam' : tokenparam ,
769
+ })
770
+ kwargs ['headers' ] = headers
726
771
727
- @property
728
- def headers_key_ts (self ):
729
- key_ts = time_stamp ()
730
- return JmModuleConfig .new_api_headers (key_ts ), key_ts
772
+ return ts
731
773
732
774
@classmethod
733
775
def require_resp_success (cls , resp : JmApiResp , orig_req_url : str ):
@@ -743,11 +785,22 @@ def require_resp_success(cls, resp: JmApiResp, orig_req_url: str):
743
785
# 暂无
744
786
745
787
def after_init (self ):
746
- # cookies = self.__class__.fetch_init_cookies(self)
747
- # self.get_root_postman().get_meta_data()['cookies'] = cookies
788
+ # 保证拥有cookies,因为移动端要求必须携带cookies,否则会直接跳转同一本子【禁漫娘】
789
+ if JmModuleConfig .api_client_require_cookies :
790
+ self .ensure_have_cookies ()
748
791
749
- self .get_root_postman ().get_meta_data ()['cookies' ] = JmModuleConfig .get_cookies (self )
750
- pass
792
+ from threading import Lock
793
+ client_init_cookies_lock = Lock ()
794
+
795
+ def ensure_have_cookies (self ):
796
+ if self .get_meta_data ('cookies' ):
797
+ return
798
+
799
+ with self .client_init_cookies_lock :
800
+ if self .get_meta_data ('cookies' ):
801
+ return
802
+
803
+ self ['cookies' ] = JmModuleConfig .get_cookies (self )
751
804
752
805
753
806
class FutureClientProxy (JmcomicClient ):
0 commit comments