Reputation: 485
I am working on a school project to get the real-time stock price on JPMorgan Website. I would like to get all the data shown in <div class="price_area">
. I have tried beautifulsoup and yahoo api but still cannot get what I want. So, it my first time to try selenium but I have no idea how to run the javascript by it. Here is my code:
def getStockPrice():
driver = webdriver.Chrome()
driver.get("http://www.jpmhkwarrants.com/en_hk/market-statistics/underlying/underlying-terms/code/1")
try:
stock_index = WebDriverWait(driver, 10).until(
driver.find_element_by_class_name('price_area').find_element_by_class_name('price')
)
finally:
driver.quit()
But it shows the error 'WebElement' is not callable. How can I get the real-time price, % change and the open price. Thanks.
Upvotes: 1
Views: 3511
Reputation: 126
That data isn't real-time.
You have to pay for real time data usually.
If your project involves any type of paper trading/analysis, know that everything you pull from a scrape will probably be delayed by 5-15min. I've heard Bloomberg has a free api, but I don't know if the real time data is free. Check out Interactive Brokers API. I'm pretty sure access to the data is free, and it allows you to connect to a paper trading account to test strategies, and algorithms.
Upvotes: 0
Reputation: 84465
You can use requests
and BeautifulSoup
to get the three items you mention using the Ajax query string call
import requests
from bs4 import BeautifulSoup
url= 'http://www.jpmhkwarrants.com/en_hk/ajax/terms_quick_search?_=1543832902362'
res = requests.get(url)
soup = BeautifulSoup(res.content, "lxml")
items = [item.text for item in soup.select('.price,.percentage.rise,li:nth-of-type(3) span')]
print(items)
Result:
The real time box has its own Ajax call of:
http://www.jpmhkwarrants.com/en_hk/ajax/market-terms-real-time-box/code/0700?_=1543832902364
You can use that to retrieve all items in that box.
import requests
from bs4 import BeautifulSoup
url= 'http://www.jpmhkwarrants.com/en_hk/ajax/market-terms-real-time-box/code/0700?_=1543832902364'
res = requests.get(url)
soup = BeautifulSoup(res.content, "lxml")
items = [item.text.strip().split('\n') for item in soup.select('.price_area div')]
tidied = [item for sublist in items for item in sublist if item and item !='Change (%)']
print(tidied)
Result:
Upvotes: 1
Reputation: 19154
to use .find_element_by_*
in WebDriverWait
you have to use lambda
function like
stock_index = WebDriverWait(driver, 10).until(
lambda d: d.find_element_by_class_name('price_area').find_element_by_class_name('price')
)
and don't forget to call .text
to get the content
def getStockPrice():
driver = webdriver.Chrome()
driver.get("http://www.jpmhkwarrants.com/en_hk/market-statistics/underlying/underlying-terms/code/0700")
try:
stock_index = WebDriverWait(driver, 10).until(
lambda x: x.find_element_by_class_name('price_area')
)
price = stock_index.find_element_by_class_name('price')
percentage = stock_index.find_element_by_css_selector('.percentage.rise')
open_price = stock_index.find_element_by_css_selector('ul li span')
print('Current price: ' + price.text)
print('Percentage: ' + percentage.text)
print('Open price: ' + open_price.text)
except:
print('wait timeout, element not found')
finally:
driver.quit()
Upvotes: 2