Estou tentando acessar dados de cerca de 500 ações do "https://www.nseindia.com/report-detail/eq_security" para os quais mencionei as etapas.
- Abra a URL
- insira o símbolo da ação e clique na primeira opção do menu suspenso.
- Clique em 1W para abrir os dados semanais.
- Da tabela, extraia dados de uma data específica para Quantidade Total Negociada, Nº de Negociações, Qtd. Entregável e % Qtd Diária para Qtd. Negociada.
- Salve esses dados em um arquivo CSV.
Então meu arquivo CSV conterá 5 colunas e cerca de 500 linhas, como abaixo.
Criei o código abaixo, mas esses são os problemas que estou enfrentando.
- Ele está abrindo o Chrome novamente para cada símbolo, tentei apagar o símbolo anterior e inserir um novo, mas não está funcionando. Portanto, ele está coletando os mesmos dados para todas as ações
- Não tenho dados históricos, então, se eu quiser ter dados de 3 meses para cada ação, preciso clicar em "3M" para coletar todos os dados. Mas não sei como fazer isso? Por favor, compartilhe este código separadamente.
Atualizarei a lista para incluir todas as ações e farei isso diariamente, então só preciso alterar a data no código no futuro.
Abaixo está o código que tenho:
import undetected_chromedriver as uc
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import time
import csv
import os
# Step 1: Create a list of stock symbols (for illustration purposes, here are a few)
# You can replace this with a list of 500 stock symbols
stock_symbols = ["INFY", "TCS", "RELIANCE", "HDFCBANK", "ITC"] # Add all 500 symbols here
# Define the CSV file name
csv_file = "nse_data.csv"
# Check if file already exists (to avoid writing headers again)
file_exists = os.path.isfile(csv_file)
# Step 2: Open browser and go to URL
driver = uc.Chrome()
driver.get("https://www.nseindia.com/report-detail/eq_security")
driver.maximize_window()
wait = WebDriverWait(driver, 10)
# Function to get data for a single stock
def get_stock_data(symbol):
# Step 1: Clear the symbol input field and enter new symbol
symbol_input = wait.until(EC.element_to_be_clickable((By.ID, "hsa-symbol")))
# Clear the input field by sending backspace
symbol_input.click()
symbol_input.clear() # Clear the previous symbol
# Wait a moment to ensure the field is cleared before entering the new symbol
time.sleep(0.5) # Add a small delay for clarity
# Enter the new symbol
symbol_input.send_keys(symbol) # Enter the new symbol
print(f"✅ Selected symbol '{symbol}'")
time.sleep(2)
# Step 2: Click on the first dropdown option
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@id='hsa-symbol_listbox']//div//div[1]"))).click()
print(f"✅ Clicked on the first option for '{symbol}'")
time.sleep(5)
# Step 3: Click on the 1W button
one_week_button = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="oneW"]')))
one_week_button.click()
print(f"✅ Clicked on the 1W button for {symbol}")
time.sleep(5)
# Step 4: Parse the table and extract data for a specific date
target_date = "11-Apr-2025"
soup = BeautifulSoup(driver.page_source, "html.parser")
table = soup.find("table", {"id": "hsaTable"})
rows = table.find_all("tr")
# Get headers to map column names to index
headers = [th.text.strip() for th in rows[0].find_all("th")]
# Mapping the column names we care about
columns_of_interest = ["Date", "Total Traded Quantity", "No. of Trades", "Deliverable Qty", "% Dly Qt to Traded Qty"]
indices = {col: headers.index(col) for col in columns_of_interest}
# Look for the row with the target date
for row in rows[1:]:
cols = [td.text.strip() for td in row.find_all("td")]
if cols and cols[indices["Date"]] == target_date:
extracted_data = {
"Symbol": symbol,
"Date": cols[indices["Date"]],
"Total Traded Quantity": cols[indices["Total Traded Quantity"]],
"No. of Trades": cols[indices["No. of Trades"]],
"Deliverable Qty": cols[indices["Deliverable Qty"]],
"% Dly Qt to Traded Qty": cols[indices["% Dly Qt to Traded Qty"]],
}
print(f"✅ Data for {symbol} on {target_date}:")
for key, val in extracted_data.items():
print(f"{key}: {val}")
break
else:
print(f"❌ No data found for date: {target_date} for {symbol}")
extracted_data = None
return extracted_data
# Write data for multiple stocks
for symbol in stock_symbols:
extracted_data = get_stock_data(symbol)
if extracted_data:
# Write to CSV
with open(csv_file, mode="a", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=extracted_data.keys())
# Write header only once
if not file_exists:
writer.writeheader()
# Write the row
writer.writerow(extracted_data)
print(f"✅ Data for {symbol} written to CSV.")
# Close the browser when all data is collected
driver.quit()
print("✅ All data extraction completed.")
Em relação à sua primeira pergunta, você precisa se certificar de que o valor no campo de entrada esteja limpo antes de inserir o próximo símbolo. Use o código abaixo para fazer isso.
Código completo:
SEGUNDA PERGUNTA: Não tenho certeza se é isso que você está procurando. Veja o código abaixo para clicar em3M
ATUALIZAÇÃO - Resposta à segunda pergunta:
Verifique o código abaixo. Removi a lógica da data-alvo (11 de abril). O código abaixo buscará dados da 3M e os gravará em um arquivo CSV.