fix: parse nested feikuai player payload
This commit is contained in:
@@ -136,6 +136,23 @@ class TestFeikuaiSpider(unittest.TestCase):
|
|||||||
self.assertEqual(encoded["parse"], 0)
|
self.assertEqual(encoded["parse"], 0)
|
||||||
self.assertEqual(encoded["url"], "https://cdn.example.com/v2.m3u8")
|
self.assertEqual(encoded["url"], "https://cdn.example.com/v2.m3u8")
|
||||||
|
|
||||||
|
@patch.object(Spider, "_request_html")
|
||||||
|
def test_player_content_handles_live_nested_player_payload(self, mock_request_html):
|
||||||
|
mock_request_html.return_value = """
|
||||||
|
<script type="text/javascript">
|
||||||
|
var player_aaaa={"flag":"play","encrypt":2,"trysee":0,"points":0,
|
||||||
|
"link_current":"\\/vodplay\\/236443-1-1.html","link":"\\/vodplay\\/236443-{sid}-{nid}.html",
|
||||||
|
"link_next":"","link_pre":"",
|
||||||
|
"vod_data":{"vod_name":"\\u6076\\u5973\\u5b66\\u9662","vod_actor":"","vod_director":"Jamie Grefe","vod_class":"\\u5267\\u60c5"},
|
||||||
|
"url":"JTY4JTc0JTc0JTcwJTczJTNBJTJGJTJGJTYzJTY0JTZFJTJFJTc5JTdBJTdBJTc5JTc2JTY5JTcwJTJEJTMyJTM5JTJFJTYzJTZGJTZEJTJGJTMyJTMwJTMyJTM2JTMwJTM0JTMyJTM1JTJGJTMyJTMzJTMyJTM5JTMxJTVGJTM0JTM1JTM5JTM2JTM3JTYzJTM3JTMzJTJGJTY5JTZFJTY0JTY1JTc4JTJFJTZEJTMzJTc1JTM4",
|
||||||
|
"from":"1080zyk","server":"no","note":"","id":"236443","sid":1,"nid":1}
|
||||||
|
</script>
|
||||||
|
"""
|
||||||
|
result = self.spider.playerContent("feikuai", "/vodplay/236443-1-1.html", {})
|
||||||
|
self.assertEqual(result["parse"], 0)
|
||||||
|
self.assertEqual(result["jx"], 0)
|
||||||
|
self.assertEqual(result["url"], "https://cdn.yzzyvip-29.com/20260425/23291_45967c73/index.m3u8")
|
||||||
|
|
||||||
@patch.object(Spider, "_request_html")
|
@patch.object(Spider, "_request_html")
|
||||||
def test_player_content_falls_back_when_script_missing(self, mock_request_html):
|
def test_player_content_falls_back_when_script_missing(self, mock_request_html):
|
||||||
mock_request_html.return_value = "<html><body>empty</body></html>"
|
mock_request_html.return_value = "<html><body>empty</body></html>"
|
||||||
|
|||||||
+31
-2
@@ -143,11 +143,40 @@ class Spider(BaseSpider):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
def _extract_player_data(self, html):
|
def _extract_player_data(self, html):
|
||||||
matched = re.search(r"player_aaaa\s*=\s*(\{[\s\S]*?\})", str(html or ""))
|
body = str(html or "")
|
||||||
|
matched = re.search(r"player_aaaa\s*=\s*\{", body)
|
||||||
if not matched:
|
if not matched:
|
||||||
return {}
|
return {}
|
||||||
|
start = matched.end() - 1
|
||||||
|
depth = 0
|
||||||
|
in_string = False
|
||||||
|
escape = False
|
||||||
|
end = -1
|
||||||
|
for index in range(start, len(body)):
|
||||||
|
char = body[index]
|
||||||
|
if in_string:
|
||||||
|
if escape:
|
||||||
|
escape = False
|
||||||
|
elif char == "\\":
|
||||||
|
escape = True
|
||||||
|
elif char == '"':
|
||||||
|
in_string = False
|
||||||
|
continue
|
||||||
|
if char == '"':
|
||||||
|
in_string = True
|
||||||
|
continue
|
||||||
|
if char == "{":
|
||||||
|
depth += 1
|
||||||
|
continue
|
||||||
|
if char == "}":
|
||||||
|
depth -= 1
|
||||||
|
if depth == 0:
|
||||||
|
end = index + 1
|
||||||
|
break
|
||||||
|
if end < 0:
|
||||||
|
return {}
|
||||||
try:
|
try:
|
||||||
return json.loads(matched.group(1))
|
return json.loads(body[start:end])
|
||||||
except Exception:
|
except Exception:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user