@@ -184,37 +184,51 @@ def reset_beautiful_soup(self, bf: BeautifulSoup):
184184
185185 @staticmethod
186186 def get_beautiful_soup (response ):
187- encoding = (
188- response .encoding
189- if response .encoding is not None and response .encoding != "ISO-8859-1"
190- else response .apparent_encoding
191- )
192- html_content = response .content .decode (encoding )
193- beautiful_soup = BeautifulSoup (html_content , "html.parser" )
194- meta_list = beautiful_soup .find_all ("meta" )
195- charset_list = Fork .get_charset_list (meta_list )
196- if len (charset_list ) > 0 :
197- charset = charset_list [0 ]
198- if charset != encoding :
199- try :
200- html_content = response .content .decode (charset , errors = "replace" )
201- except Exception as e :
202- maxkb_logger .error (f"{ e } : { traceback .format_exc ()} " )
203- return BeautifulSoup (html_content , "html.parser" )
204- return beautiful_soup
187+ encoding_list = Fork .get_encoding_list (response )
188+ for encoding in encoding_list :
189+ try :
190+ return BeautifulSoup (response .content .decode (encoding ), "html.parser" )
191+ except (LookupError , UnicodeDecodeError ):
192+ continue
193+
194+ fallback_encoding = encoding_list [0 ] if len (encoding_list ) > 0 else "utf-8"
195+ html_content = response .content .decode (fallback_encoding , errors = "replace" )
196+ return BeautifulSoup (html_content , "html.parser" )
197+
198+ @staticmethod
199+ def get_encoding_list (response ):
200+ charset_list = Fork .get_charset_list (response .content )
201+ if response .encoding is not None and response .encoding != "ISO-8859-1" :
202+ charset_list .append (response .encoding )
203+ if response .apparent_encoding is not None :
204+ charset_list .append (response .apparent_encoding )
205+ result = []
206+ for charset in charset_list :
207+ normalized_charset = Fork .normalize_charset (charset )
208+ if normalized_charset is not None and normalized_charset not in result :
209+ result .append (normalized_charset )
210+ return result
205211
206212 @staticmethod
207- def get_charset_list (meta_list ):
213+ def get_charset_list (content ):
208214 charset_list = []
209- for meta in meta_list :
210- if meta .attrs is not None :
211- if "charset" in meta .attrs :
212- charset_list .append (meta .attrs .get ("charset" ))
213- elif meta .attrs .get ("http-equiv" , "" ).lower () == "content-type" and "content" in meta .attrs :
214- match = re .search (r"charset=([^\s;]+)" , meta .attrs ["content" ], re .I )
215- if match :
216- charset_list .append (match .group (1 ))
217- return charset_list
215+ content_head = content [:8192 ]
216+ charset_list .extend (re .findall (rb"<meta[^>]+charset=['\"]?\s*([a-zA-Z0-9._-]+)" , content_head , re .I ))
217+ charset_list .extend (
218+ re .findall (rb"<meta[^>]+content=['\"][^'\"]*charset=([a-zA-Z0-9._-]+)" , content_head , re .I )
219+ )
220+ return [
221+ charset .decode ("ascii" , errors = "ignore" )
222+ for charset in charset_list
223+ if len (charset ) > 0
224+ ]
225+
226+ @staticmethod
227+ def normalize_charset (charset ):
228+ if charset is None :
229+ return None
230+ normalized_charset = charset .strip ().strip ("\" '" ).lower ()
231+ return normalized_charset if len (normalized_charset ) > 0 else None
218232
219233 @staticmethod
220234 def _sandbox_requests_get (base_fork_url : str , headers : dict ):
0 commit comments