Как можно парсить данные с Python?
Как достать данные о цене акции тут: https://www.tinkoff.ru/invest/stocks/RDS.A/ Пытался сделать так, но выходит None:
link_ticker = "https://www.tinkoff.ru/invest/stocks/RDS.A/"
data_base = requests.get(link_ticker).text
data = BeautifulSoup(data_base, "html.parser")
price = data.find('text', {'class': 'Tooltip__tooltipText_1PLnU'})
print(price)
Ответы (4 шт):
# небольшой напилинг selenium Firefox
# (Можно обойтись без него но мне лень переписывать WebDriverWait тем более что он там проверен и работает как надо)
from selenium.common.exceptions import *
from selenium.webdriver import Firefox
from selenium.webdriver import FirefoxOptions
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.firefox.webelement import FirefoxWebElement
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait
class FirefoxBrowser(Firefox):
def __init__(self,
silent_mode: bool = False,
driver: str = 'geckodriver',
close_timeout: int = 0,
max_window: bool = True,
no_images: bool = True):
"""
Надстройка к драйверу selenium Firefox. С персональной кастомизацией
:param silent_mode: логическое, по умолчанию False отвечает за отображение окна браузера.;
:param driver: указывает расположение файла `geckodriver`. Если файл находится не в директории проекта (не забываем скачать бинарник (exe'шник для Windows) и закинуть его в папку со скриптом либо в любую из PATH)
необходимо указать полный путь к файлу, или добавить путь к файлу в переменную PATH;
:param close_timeout: время задержки до закрытия окна браузера после завершения работы. По умолчании 0 сек.; # чето не зашло у меня с этим параметром поэтому не используется
:param max_window: параметр отвечающий за развертывание окна браузера до максимального размера при запуске
:param no_images: блокировка изображений на сайтах.
"""
self.__close_timeout = close_timeout
if silent_mode:
max_window = False
opt = FirefoxOptions()
opt.headless = silent_mode
profile = FirefoxProfile()
if no_images:
profile.set_preference('permissions.default.image', 2)
super().__init__(options=opt,
executable_path=driver,
firefox_profile=profile)
if max_window:
self.maximize_window()
def scroll_to_element(self, element: FirefoxWebElement):
self.execute_script("arguments[0].scrollIntoView();", element)
def wait_for_element(self, by: By, ident: str, timeout: int = 5):
try:
WebDriverWait(self, timeout).until(
expected_conditions.presence_of_all_elements_located(
(by, ident)
)
)
return self.find_element(by, ident)
except TimeoutException:
return None
@property
def action(self):
return ActionChains(self)
Теперь собственно ответ на вопрос:
site = FirefoxBrowser()
# Если смущают "спецэффекты" в виде открывающегося окна Firefox
# то можно site = FirefoxBrowser(silent_mode=True)
site.get('https://www.tinkoff.ru/invest/stocks/RDS.A/')
needed = site.wait_for_element(By.CLASS_NAME, 'Tooltip__tooltipText_1PLnU')
if needed:
print(needed.text)
# 33,1
Смотрите в инспектор браузера на вкладке Network откуда сайт берет данные.
Этот сайт отдает данные по АПИ без авторизации:
отправляете POST с json на https://api.tinkoff.ru/trading/symbols/candles?sessionId=DjsxrsV2k8Rphjmmeity5Z1TmHyDF2VO.ds-prod-api27 где sessionId похоже не обязательна
{"from":"2020-07-05T12:27:46+03:00","to":"2020-07-19T12:27:46+03:00","resolution":60,"ticker":"RDS.A"}
получаете свечки в json
{"payload":{
"candles":
[{"o":33.94,"c":33.37,"h":33.94,"l":33.1,"v":1370,"date":1594018800},
....,
{"o":33.1,"c":33.1,"h":33.1,"l":33.1,"v":4,"date":1595023200}]
},
"trackingId":"1446f81bd84cfc2e",
"time":"2020-07-19T12:29:31.739+03:00",
"status":"Ok"}
o,c - открытие, закрытие h,l - верхниее, нижнее
import requests
payloads = {
"from": "2020-07-05T12:27:46+03:00",
"to": "2020-07-19T12:27:46+03:00",
"resolution": 60,
"ticker": "RDS.A"
}
response = requests.post('https://api.tinkoff.ru/trading/symbols/candles', json=payloads)
print(response.json())
# {'payload': {'candles': [{'o': 33.94, 'c': 33.37, 'h': 33.94, 'l': 33.1, 'v': 1370, 'date': 1594018800}, ...вырезанно... , {'o': 33.1, 'c': 33.1, 'h': 33.1, 'l': 33.1, 'v': 4, 'date': 1595023200}]}, 'trackingId': '94e8ec7237cc65fc', 'time': '2020-07-19T12:49:19.202+03:00', 'status': 'Ok'}
Работает также и с GET.
А что мешает через bs4 просто парсить всю страницу по ссылке,а там уже поиском по строке найти нужный параметр?
https://api-invest.tinkoff.ru/smartfeed-public/v1/feed/api/brands/Royal%20Dutch%20Shell%20PLC/news?sessionId=sv4DAPcPfLkb4QQXD1xq37gi1d8v98Sh.ds-prod-api48&limit=10
Это самый простой вариант без Post запросов...
from requests_html import HTMLSession
session = HTMLSession()
response = session.get('https://www.tinkoff.ru/invest/stocks/RDS.A/')
response.html.render()
get_price = response.html.xpath('//*[@class="Tooltip__tooltipText_1PLnU"]//text()')
print(get_price)