fix: support nested cupfox player data

This commit is contained in:
Harold
2026-04-19 20:39:48 +08:00
parent 2287f36881
commit c070e216e5
2 changed files with 64 additions and 2 deletions
+18
View File
@@ -123,6 +123,24 @@ class TestCupfoxSpider(unittest.TestCase):
self.assertEqual(data["url"], "vid-1")
self.assertEqual(data["from"], "lineA")
def test_extract_player_data_supports_nested_object_literal(self):
html = """
<script>
var player_aaaa={
"flag":"play",
"encrypt":0,
"vod_data":{"vod_name":"八千里路云和月","vod_actor":"王阳,万茜"},
"url":"DJP5QlL6j66wOTl+NrtIwkJCenh0ZVBlTHJzTWJWd0Y1eTNBd1crTmt5NmpjK05XOTFxb25iSTJ4d2RSUms4YllrVVhSU2xyK0JGcFFZZThibmVqU1BWUFlEMnVWTUpQVmR1Vm9FZHJJWlFaaHNaR3pmTHYwbjVyUE11dkdwbzVOMTJpRFpBK3cvYUl5RnNuQXNaelFZZ0plWVhWYitFenJOMHhUZz09",
"from":"rb",
"server":"no"
};
</script>
"""
data = self.spider._extract_player_data(html)
self.assertEqual(data["encrypt"], 0)
self.assertEqual(data["vod_data"]["vod_name"], "八千里路云和月")
self.assertEqual(data["from"], "rb")
def test_decode2_recovers_shifted_text(self):
encoded = "QXdCQ2tE"
self.assertEqual(self.spider._decode2(encoded), "P0")
+46 -2
View File
@@ -160,14 +160,58 @@ class Spider(BaseSpider):
return second["text"]
def _extract_player_data(self, html_text):
matched = re.search(r"player_aaaa\s*=\s*(\{[\s\S]*?\})\s*;?", str(html_text or ""))
text = str(html_text or "")
matched = re.search(r"player_aaaa\s*=", text, re.I)
if not matched:
return None
object_start = text.find("{", matched.end())
if object_start < 0:
return None
raw_object = self._extract_balanced_object(text, object_start)
if not raw_object:
return None
try:
return json.loads(matched.group(1))
return json.loads(raw_object)
except Exception:
return None
def _extract_balanced_object(self, text, start_index):
raw = str(text or "")
if start_index < 0 or start_index >= len(raw) or raw[start_index] != "{":
return ""
depth = 0
in_string = False
quote_char = ""
escaped = False
for index in range(start_index, len(raw)):
char = raw[index]
if in_string:
if escaped:
escaped = False
elif char == "\\":
escaped = True
elif char == quote_char:
in_string = False
continue
if char in ('"', "'"):
in_string = True
quote_char = char
continue
if char == "{":
depth += 1
continue
if char == "}":
depth -= 1
if depth == 0:
return raw[start_index : index + 1]
return ""
def _decode2(self, encoded):
if not encoded:
return ""