From 4a62e2895676398e5c2dcce697597abbddb07a2c Mon Sep 17 00:00:00 2001 From: ryanstoic Date: Thu, 26 Mar 2026 23:24:57 -0700 Subject: [PATCH] fix: update ondemand.s regex for new webpack chunk format X changed how the ondemand.s JS bundle is referenced in their HTML. The old format embedded the hash directly next to the chunk name: 'ondemand.s': 'abc123' The new format uses a numeric chunk index that maps to the hash in a separate JavaScript object: ,1234:"ondemand.s" ... ,1234:"abc123" This updates ON_DEMAND_FILE_REGEX to capture the chunk index, adds ON_DEMAND_HASH_PATTERN for the second lookup, and updates INDICES_REGEX to match the new format. The get_indices method now does a two-step lookup: find the chunk index, then resolve it to the file hash. Fixes #408 Fixes #409 --- twikit/x_client_transaction/transaction.py | 25 ++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/twikit/x_client_transaction/transaction.py b/twikit/x_client_transaction/transaction.py index f4771fc9..ac6b2e06 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,17 @@ 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)) - 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_match = ON_DEMAND_FILE_REGEX.search(str(response)) + if on_demand_match: + chunk_index = on_demand_match.group(1) + hash_match = re.search( + ON_DEMAND_HASH_PATTERN.format(chunk_index), str(response)) + if hash_match: + file_hash = hash_match.group(1) + on_demand_file_url = f"https://abs.twimg.com/responsive-web/client-web/ondemand.s.{file_hash}a.js" + on_demand_file_response = await session.request(method="GET", url=on_demand_file_url, headers=headers) + for item in INDICES_REGEX.finditer(on_demand_file_response.text): + 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))