您好,我想抓取我最初使用Bs4的该网站,可以很好地获取某些元素。部门,名称等。但是我无法使用它来获取财务数据。下面我复制了一些page_source,在这种情况下,“-”应为0.0663。我相信我正在尝试抓取javascript,并且四处张望,没有看到的解决方案对我有用。我想知道是否有人可以帮助我解决这个问题。
尽管我将不胜感激,如果有人可以发布一些有效的代码,如果您也能指出正确的方向,以了解在html中寻找的内容,我将不胜感激,该内容向我展示了我需要做什么以及如何做得到它有点东西。
URL:https://www.tradingview.com/symbols/LSE-TSCO/
HTML:
<span class="tv-widget-fundamentals__label apply-overflow-tooltip">
Return on Equity (TTM)
</span>
<span class="tv-widget-fundamentals__value apply-overflow-tooltip">
—
</span>
Python代码:
url = "https://www.tradingview.com/symbols/LSE-TSCO/"
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get(url)
html = driver.page_source
答案 0 :(得分:2)
要获取净值,请诱发WebDriverWait
()并等待visibility_of_element_located
()并位于xpath以下。
driver.get(url)
print(WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,"//span[contains(.,'Return on Equity (TTM)')]/following-sibling::span[1]"))).text)
您需要导入以下库。
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
答案 1 :(得分:1)
您可以使用xpath
获得股本回报率equity = driver.find_element_by_xpath('/html/body/div[2]/div[4]/div/div/div/div/div/div[2]/div[2]/div[2]/div/div[2]/div[1]/div/div/div[1]/div[3]/div[3]/span[2]').text
print(equity)
答案 2 :(得分:0)
这里的问题不是元素是否存在,而是页面加载所需的时间。所有这些动态图的页面看起来都很沉重。即使在完全加载页面之前,也开始创建DOM并使用默认值。
WebDriverWait
和find_element_*
可以在当前不存在该元素但需要一定时间才能显示时使用。在您的上下文中,它从一开始就存在,并且添加不会有多大作用。这也是为什么得到“-”的原因,因为该元素以其默认值存在。
要解决此问题或减少问题,您可以添加代码以等待文档readyState完成
可以使用以下方法:
def wait_for_page_ready_state(driver):
wait = WebDriverWait(driver, 20)
def _ready_state_script(driver):
return driver.execute_async_script(
"""
var callback = arguments[arguments.length - 1];
callback(document.readyState);
""") == 'complete'
wait.until(_ready_state_script)
wait_for_page_ready_state(driver)
然后,由于您将bs4引入游戏中,因此我将在这里使用它:
financials = {}
for el in BeautifulSoup(driver.page_source, "lxml").find_all('div', {"class": "tv-widget-fundamentals__row"}):
try:
key = re.sub('\s+', ' ', el.find('span', {"class": "tv-widget-fundamentals__label "
"apply-overflow-tooltip"}).text.strip())
value = re.sub('\s+', ' ', el.find('span', {"class": "tv-widget-fundamentals__value"}).text.strip())
financials[key] = value
except AttributeError:
pass
这将为您提供金融卡所需的一切价值。
您现在可以打印所需的值:
print(financials['Return on Equity (TTM)'])
输出:
'0.0663'
当然,您也可以对硒进行上述操作,但希望提供您开始使用的硒。
要注意,这并不保证总是返回正确的值。在我的情况下可能会这样做,但是由于您知道默认值,因此可以添加一个while循环,直到默认更改为止。
[编辑] 循环运行代码后,我达到默认值1/5倍。解决该问题的一种方法是创建一个方法并循环直到达到阈值。在我的发现中,您将始终用数字更新约90%的值。如果使用默认值失败,则所有其他值也都位于“-”。一种方法是使用阈值(即50%,并且仅在达到阈值时才返回值)。
def get_financial_card_values(default_value='—', threshold=.5):
financials = {}
while True:
for el in BeautifulSoup(driver.page_source, "lxml").find_all('div', {"class": "tv-widget-fundamentals__row"}):
try:
key = re.sub('\s+', ' ', el.find('span', {"class": "tv-widget-fundamentals__label "
"apply-overflow-tooltip"}).text.strip())
value = re.sub('\s+', ' ', el.find('span', {"class": "tv-widget-fundamentals__value"}).text.strip())
financials[key] = value
except AttributeError:
pass
number_of_updated_values = [value for value in financials.values() if value != default_value]
if len(number_of_updated_values) / len(financials) > threshold:
return financials
使用这种方法,我能够始终检索您期望的值。请注意,如果所有值都不会改变(站点问题),则您将永远处于循环中,您可能希望使用计时器而不是while True
。只是想指出这一点,但我认为它不会发生。