From ed20f938b6486e9f534a730460a45ffec05ccef6 Mon Sep 17 00:00:00 2001 From: Nikolaos Pothitos Date: Thu, 19 Mar 2026 04:01:32 +0200 Subject: [PATCH] Fix ondemand.s.js URL parsing for new X response format X changed the ondemand.s.js format (Mar 2026). The response now uses a numeric index and a separate hash for the filename instead of the previous pattern. Update ON_DEMAND_FILE_REGEX and add ON_DEMAND_HASH_PATTERN to resolve the script URL correctly; adjust INDICES_REGEX and group index for key_byte_indices. Resolves #408 #409 --- twikit/x_client_transaction/transaction.py | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/twikit/x_client_transaction/transaction.py b/twikit/x_client_transaction/transaction.py index f4771fc9..e1466e1d 100644 --- a/twikit/x_client_transaction/transaction.py +++ b/twikit/x_client_transaction/transaction.py @@ -13,9 +13,9 @@ from .utils import float_to_hex, is_odd, base64_encode, handle_x_migration ON_DEMAND_FILE_REGEX = re.compile( - r"""['|\"]{1}ondemand\.s['|\"]{1}:\s*['|\"]{1}([\w]*)['|\"]{1}""", flags=(re.VERBOSE | re.MULTILINE)) -INDICES_REGEX = re.compile( - r"""(\(\w{1}\[(\d{1,2})\],\s*16\))+""", flags=(re.VERBOSE | re.MULTILINE)) + r""",(\d+):["']ondemand\.s["']""", flags=(re.VERBOSE | re.MULTILINE)) +ON_DEMAND_HASH_PATTERN = r',{}:"([0-9a-f]+)"' +INDICES_REGEX = re.compile(r"\[(\d+)\],\s*16") class ClientTransaction: @@ -42,14 +42,19 @@ async def get_indices(self, home_page_response, session, headers): key_byte_indices = [] response = self.validate_response( home_page_response) or self.home_page_response - on_demand_file = ON_DEMAND_FILE_REGEX.search(str(response)) + response_str = str(response) + on_demand_file = ON_DEMAND_FILE_REGEX.search(response_str) if on_demand_file: - on_demand_file_url = f"https://abs.twimg.com/responsive-web/client-web/ondemand.s.{on_demand_file.group(1)}a.js" - on_demand_file_response = await session.request(method="GET", url=on_demand_file_url, headers=headers) - key_byte_indices_match = INDICES_REGEX.finditer( - str(on_demand_file_response.text)) - for item in key_byte_indices_match: - key_byte_indices.append(item.group(2)) + on_demand_file_index = on_demand_file.group(1) + hash_regex = re.compile(ON_DEMAND_HASH_PATTERN.format(on_demand_file_index)) + hash_match = hash_regex.search(response_str) + if hash_match: + filename = hash_match.group(1) + on_demand_file_url = f"https://abs.twimg.com/responsive-web/client-web/ondemand.s.{filename}a.js" + on_demand_file_response = await session.request(method="GET", url=on_demand_file_url, headers=headers) + key_byte_indices_match = INDICES_REGEX.finditer(str(on_demand_file_response.text)) + for item in key_byte_indices_match: + key_byte_indices.append(item.group(1)) if not key_byte_indices: raise Exception("Couldn't get KEY_BYTE indices") key_byte_indices = list(map(int, key_byte_indices))