Scraping stock names from Chartink screener

Question:

I am trying to scrape available list of stocks from a chartink screener, at any given time.

Example screener: https://chartink.com/screener/15-minute-stock-breakouts

The Inspect element option shows me stock names in between HTML tags (between ‘td’ and ‘tr’).
But when I print the output on Python page, stock names are missing (nothing available between ‘td’ and ‘tr’).
Leads me to suspect whether Chartink site is scraping-proof. Or maybe it’s my limited knowledge.

Can you please give it a shot, and advise. And if not Python, would I be able to get the stock list via any other tool (like VBA)? I am using Microsoft Edge on Windows 11.

Below is the code. As you would see I have tried different things, but failed.

import pandas as pd
# from selenium import webdriver
# from selenium.webdriver.common.by import By
import numpy as np
import schedule
from datetime import datetime
import requests
from bs4 import BeautifulSoup

page = requests.get("https://chartink.com/screener/15-minute-stock-breakouts")
soup = BeautifulSoup(page.content, 'lxml')
print(soup)

# url = 'https://chartink.com/screener/15-minute-stock-breakouts'
# driver = webdriver.Edge(executable_path=r'C:UserskashkDownloadsedgedriver_win64msedgedriver.exe')
# driver.get(url)
# pd.read_html(driver.find_element(by=By.XPATH, value='//*[@id="DataTables_Table_0"]').get_attribute('outerHTML'))
Asked By: Kashyap

||

Answers:

The data is loaded dynamically and is retrieved from a XHR so if you are using Selenium, you probably have to wait for the data to be loaded first.

Below method uses XMLHTTP approach and seems to work for me:

Option Explicit

Sub Chartink()
    Dim reqObj As Object
    Set reqObj = CreateObject("MSXML2.XMLHTTP")
    
    With reqObj
        .Open "GET", "https://chartink.com/screener/15-minute-stock-breakouts", False
        .Send
        
        Dim reqDoc As Object
        Set reqDoc = CreateObject("HTMLFile")
        reqDoc.body.innerHTML = .responseText
        
        'Retrieve the CSRF token that is required for XHR later
        Dim metaEle As Object
        Set metaEle = reqDoc.getElementsByName("csrf-token")(0)
    
        'Retrieve the JSON data
        .Open "POST", "https://chartink.com/screener/process", False
        .setRequestHeader "x-csrf-token", metaEle.Content
        .setRequestHeader "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"
        .Send "scan_clause=(+%7B57960%7D+(+%5B0%5D+15+minute+close+%3E+%5B-1%5D+15+minute+max(+20+%2C+%5B0%5D+15+minute+close+)+and+%5B0%5D+15+minute+volume+%3E+%5B0%5D+15+minute+sma(+volume%2C20+)+)+)+"
                
        Dim resultDict As Scripting.Dictionary
        Set resultDict = JsonConverter.ParseJson(.responseText)
        
        Dim i As Long
        For i = 1 To resultDict("data").Count
            Debug.Print resultDict("data")(i)("name") & vbTab & resultDict("data")(i)("close") & vbTab & resultDict("data")(i)("volume")
        Next i
    End With
End Sub

You will need VBA-JSON and reference to Microsoft Scripting Runtime for the JsonConverter.ParseJson method.

Answered By: Raymond Wu
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.