2025, Oct 02 23:33

Selenium में नया टैब खुलने पर current_url क्यों नहीं बदलता और समाधान

Selenium में नए टैब पर क्लिक के बाद current_url वही क्यों रहता है, window_handles से सही टैब पर switch_to कैसे करें, और onclick से लक्ष्य URL बनाकर तेज़ी से पढ़ें।

यदि Selenium में क्लिक करने से नया ब्राउज़र टैब खुलता है, तो तुरंत current_url कॉल करने पर प्रायः मूल पेज का URL ही मिलता है। ड्राइवर तब तक पहले टैब पर ही केंद्रित रहता है जब तक आप उसे स्पष्ट रूप से स्विच करने के लिए नहीं कहते। इसी वजह से नए खुले टैब का URL लेना शुरुआत में उलझन भरा लग सकता है।

समस्या को पुनरुत्पादित करना

नीचे दिया स्क्रिप्ट solrenview.com खोलता है, इंस्टॉलर के आधार पर फ़िल्टर करता है, एक सुझाव चुनता है और ऐसे नतीजे पर क्लिक करता है जो दूसरे टैब में खुलता है। ब्राउज़र में नया टैब सक्रिय दिखने के बावजूद, प्रिंट हुआ URL वही पुराना रहता है।

import time
import os, sys
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
print(f"Program name: {os.path.basename(__file__)}")
TRY_MODE = True
EXIT_AFTER = 10
SAVE_EVERY = 1
WAIT_SEC = 1
base_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
print("Checking Browser driver...")
chrome_opts = Options()
chrome_opts.add_argument("start-maximized")
chrome_opts.add_argument('--use-gl=swiftshader')
chrome_opts.add_argument('--disable-gpu')
chrome_opts.add_argument('--no-sandbox')
chrome_opts.add_argument('--disable-dev-shm-usage')
chrome_opts.add_argument("start-maximized")
chrome_opts.add_argument('--log-level=3')
chrome_opts.add_argument('--enable-unsafe-swiftshader')
svc = Service()
browser = webdriver.Chrome(service=svc, options=chrome_opts)
sync = WebDriverWait(browser, 10)
home_url = "https://www.solrenview.com/"
browser.get(home_url)
sync.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@id='gMapsFr']")))
browser.execute_script("arguments[0].click();", sync.until(EC.element_to_be_clickable((By.XPATH, '//label[@for="ByInstaller"]'))))
time.sleep(0.5)
sync.until(EC.presence_of_element_located((By.XPATH, '//input[@id="searchBox"]'))).clear()
time.sleep(0.5)
sync.until(EC.presence_of_element_located((By.XPATH, '//input[@id="searchBox"]'))).send_keys("Barrier Solar Inc.")
time.sleep(0.5)
browser.execute_script("arguments[0].click();", sync.until(EC.element_to_be_clickable((By.XPATH, '//div[@id="autoSuggestionsList"]//li'))))
time.sleep(3)
browser.execute_script("arguments[0].click();", sync.until(EC.element_to_be_clickable((By.XPATH, f'(//a[contains(text(), "Double E")])[{1}]'))))
current_url = browser.current_url
print(current_url)
input("Press!")

असल में क्या हो रहा है

Selenium स्वतः नए खुले विंडो या टैब पर संदर्भ नहीं बदलता। क्लिक से दूसरा टैब खुलता है, पर ड्राइवर का फोकस मूल टैब पर ही रहता है, इसलिए current_url उसी पहले टैब का मान देता है। यह व्यवहार डिजाइन के अनुसार है और Selenium के विंडो/टैब हैंडलिंग में दस्तावेज़ित है। URL पढ़ने से पहले जिस टैब का निरीक्षण करना है, उस पर स्विच करना आवश्यक है।

Selenium दस्तावेज़: विंडो और टैब के साथ काम करना

सीधा समाधान: नए टैब पर स्विच करें

window_handles से आखिरी हैंडल लें, उस पर स्विच करें, और तब URL पढ़ें। इस स्थिति में दूसरा टैब अंतिम हैंडल होगा।

last_tab = browser.window_handles[-1]
browser.switch_to.window(last_tab)
print(browser.current_url)

विकल्प: स्विच किए बिना लक्ष्य URL बनाएं

पेज पर लक्ष्य एंकर onclick जैसे SiteUrlFunc(5746) का उपयोग करते हैं। onclick के अंदर का id वास्तविक गंतव्य के siteId पैरामीटर से मेल खाता है। आप onclick पढ़कर id निकाल सकते हैं और लिंक खोले बिना सीधे URL बना सकते हैं।

target = browser.find_element(By.XPATH, f'(//a[contains(text(), "Double E")])[{1}]')
handler = target.get_attribute('onclick')
print('on_click:', handler)
site_id = handler.replace("SiteUrlFunc(", "").replace(");", "")
print('number:', site_id)
print(f"https://www.solrenview.com/SolrenView/mainFr.php?siteId={site_id}")

दोनों तरीकों के साथ पूर्ण उदाहरण

नीचे दिया एंड-टू-एंड स्क्रिप्ट दिखाता है कि कैसे onclick से URL बनाया जाए, और साथ ही नया टैब खुलने के बाद उस पर स्विच करके ब्राउज़र से सीधे URL लिया जाए।

import time
import os, sys
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
print(f"Program name: {os.path.basename(__file__)}")
TRY_MODE = True
EXIT_AFTER = 10
SAVE_EVERY = 1
WAIT_SEC = 1
base_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
print("Checking Browser driver...")
chrome_opts = Options()
chrome_opts.add_argument("start-maximized")
chrome_opts.add_argument('--use-gl=swiftshader')
chrome_opts.add_argument('--disable-gpu')
chrome_opts.add_argument('--no-sandbox')
chrome_opts.add_argument('--disable-dev-shm-usage')
chrome_opts.add_argument("start-maximized")
chrome_opts.add_argument('--log-level=3')
chrome_opts.add_argument('--enable-unsafe-swiftshader')
svc = Service()
browser = webdriver.Chrome(service=svc, options=chrome_opts)
sync = WebDriverWait(browser, 10)
home_url = "https://www.solrenview.com/"
browser.get(home_url)
sync.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@id='gMapsFr']")))
browser.execute_script("arguments[0].click();", sync.until(EC.element_to_be_clickable((By.XPATH, '//label[@for="ByInstaller"]'))))
time.sleep(0.5)
sync.until(EC.presence_of_element_located((By.XPATH, '//input[@id="searchBox"]'))).clear()
time.sleep(0.5)
sync.until(EC.presence_of_element_located((By.XPATH, '//input[@id="searchBox"]'))).send_keys("Barrier Solar Inc.")
time.sleep(0.5)
browser.execute_script("arguments[0].click();", sync.until(EC.element_to_be_clickable((By.XPATH, '//div[@id="autoSuggestionsList"]//li'))))
time.sleep(3)
browser.execute_script("arguments[0].click();", sync.until(EC.element_to_be_clickable((By.XPATH, f'(//a.contains(text(), "Double E")])[{1}]'))))
print(f"{browser.current_url = }")
# onclick से URL तैयार करें
anchor = browser.find_element(By.XPATH, f'(//a[contains(text(), "Double E")])[{1}]')
onclick_val = anchor.get_attribute('onclick')
print('onclick:', onclick_val)
site_id = onclick_val.replace("SiteUrlFunc(", "").replace(");", "")
print('number:', site_id)
print(f"generated: https://www.solrenview.com/SolrenView/mainFr.php?siteId={site_id}")
# नए खुले टैब पर स्विच करें और उसका URL प्रिंट करें
last_tab = browser.window_handles[-1]
browser.switch_to.window(last_tab)
print(f"last : {browser.current_url = }")
# वापस पहले टैब पर स्विच करें
first_tab = browser.window_handles[0]
browser.switch_to.window(first_tab)
print(f"first: {browser.current_url = }")
input("Press ENTER to close")

यह क्यों मायने रखता है

वेब ऐप्स में मल्टी-टैब और मल्टी-विंडो फ्लो सामान्य हैं। यह मान लेना कि Selenium ब्राउज़र में दिख रहे सक्रिय टैब के साथ चल देगा, सूक्ष्म बग, अविश्वसनीय एसेर्शन और भ्रामक लॉग तक ले जाता है। संदर्भ को स्पष्ट रूप से स्विच करना या उपलब्ध एट्रिब्यूट्स से लक्ष्य URL निकालना ऑटोमेशन को स्थिर और पारदर्शी रखता है। जब टैब प्रबंधन इरादतन होता है, तो परिणाम संग्रह, नेविगेशन नियंत्रण और टियरडाउन लॉजिक पूर्वानुमेय हो जाते हैं।

मुख्य बातें

जब किसी क्लिक से नया टैब खुलता है, ड्राइवर तब तक मूल संदर्भ में ही रहता है जब तक आप उसे स्विच नहीं कराते। सही टैब चुनने के लिए window_handles का उपयोग करें और फिर current_url पढ़ें। अगर पेज onclick जैसे एट्रिब्यूट में गंतव्य पैरामीटर उजागर करता है, तो आप बिना स्विच किए भी अंतिम URL बना सकते हैं। ये दोनों तकनीकें पास रखना डिबगिंग के दौरान समय बचाता है और टेस्ट फ्लो को अधिक निर्धारक बनाता है।

यह लेख StackOverflow के प्रश्न (लेखक: Rapid1898) और furas के उत्तर पर आधारित है।