我正在做一些练习,用Python练习网络抓取,我想得到这个雅虎页面(纽约证券交易所美国银行)表格的第一行("总收入")的值。
查看页面源代码,我的想法是找到第一个出现的<div class="" data-test="fin-row">
并获取值,但我不确定如何在第一个div中导航
下面我展示了第一行显示的HTML代码:
<div class="" data-test="fin-row">
<div class="D(tbr) fi-row Bgc($hoverBgColor):h">
<div class="D(tbc) Ta(start) Pend(15px)--mv2 Pend(10px) Bxz(bb) Py(8px) Bdends(s) Bdbs(s) Bdstarts(s) Bdstartw(1px) Bdbw(1px) Bdendw(1px) Bdc($seperatorColor) Pos(st) Start(0) Bgc($lv2BgColor) fi-row:h_Bgc($hoverBgColor) Pstart(15px)--mv2 Pstart(10px)">
<div class="D(ib) Va(m) Ell Mt(-3px) W(215px)--mv2 W(200px) undefined" title="Total Revenue">
<button aria-label="Total Revenue" class="P(0) M(0) Va(m) Bd(0) Fz(s) Mend(2px) tgglBtn">
<svg class="H(16px) Fill($primaryColor) Stk($primaryColor) tgglBtn:h_Fill($linkColor) tgglBtn:h_Stk($linkColor) Cur(p)" width="16" style="stroke-width:0;vertical-align:bottom" height="16" viewBox="0 0 48 48" data-icon="caret-right">
<path d="M33.447 24.102L20.72 11.375c-.78-.78-2.048-.78-2.828 0-.78.78-.78 2.047 0 2.828l9.9 9.9-9.9 9.9c-.78.78-.78 2.047 0 2.827.78.78 2.047.78 2.828 0l12.727-12.728z"></path>
</svg>
</button>
<span class="Va(m)">Total Revenue</span>
</div>
<div class="W(3px) Pos(a) Start(100%) T(0) H(100%) Bg($pfColumnFakeShadowGradient) Pe(n) Pend(5px)"></div>
</div>
<div class="Ta(c) Py(6px) Bxz(bb) BdB Bdc($seperatorColor) Miw(120px) Miw(100px)--pnclg Bgc($lv1BgColor) fi-row:h_Bgc($hoverBgColor) D(tbc)" data-test="fin-col"><span>90,742,000</span></div>
<div class="Ta(c) Py(6px) Bxz(bb) BdB Bdc($seperatorColor) Miw(120px) Miw(100px)--pnclg D(tbc)" data-test="fin-col"><span>89,113,000</span></div>
<div class="Ta(c) Py(6px) Bxz(bb) BdB Bdc($seperatorColor) Miw(120px) Miw(100px)--pnclg Bgc($lv1BgColor) fi-row:h_Bgc($hoverBgColor) D(tbc)" data-test="fin-col"><span>85,528,000</span></div>
<div class="Ta(c) Py(6px) Bxz(bb) BdB Bdc($seperatorColor) Miw(120px) Miw(100px)--pnclg D(tbc)" data-test="fin-col"><span>91,244,000</span></div>
<div class="Ta(c) Py(6px) Bxz(bb) BdB Bdc($seperatorColor) Miw(120px) Miw(100px)--pnclg Bgc($lv1BgColor) fi-row:h_Bgc($hoverBgColor) D(tbc)" data-test="fin-col"><span>91,247,000</span></div>
</div>
<div></div>
在我的代码中,我使用Selenium来处理页面。不确定这是否是最好的方式,但对于urlopen等其他库,我无法看到HTML内容。我可以打开页面,点击接受按钮,但在那之后,我不知道如何在第一个div中导航;AttributeError:"NoneType"对象没有属性"get_text">
import requests
from urllib.request import urlopen, Request
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
url = "https://finance.yahoo.com/quote/BAC/financials?p=BAC"
driver.get(url)
html = driver.page_source
soup = BeautifulSoup(html, "html.parser")
# Click accept button
aceitar = driver.find_element(By.NAME, "agree")
aceitar.click()
# Find the div of the Revenue row <div class="" data-test="fin-row">
primeiraLinha = soup.find("div", {"class":""})
print(primeiraLinha.get_text())
顺便说一句,我认为硒使这个过程非常缓慢。
这里有一个Selenium解决方案,可以在pandas数据帧中获取整个表。
需要导入
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd
启动web驱动程序
# Replace your CHROME DRIVER path here
chrome_path = r"C:UsershpoddarDesktopToolschromedriver_win32chromedriver.exe"
s = Service(chrome_path)
driver = webdriver.Chrome(service=s)
获取页面
driver.get('https://finance.yahoo.com/quote/BAC/financials?p=BAC')
等待表加载
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//div[@class="D(tbhg)"]')))
获取标题行
headers_elem = driver.find_elements(By.XPATH, '//div[@class="D(tbhg)"]/div/div')
col_headers = [header.text for header in headers_elem]
df = pd.DataFrame(columns = col_headers)
df
输出:
Empty DataFrame
Columns: [Breakdown, TTM, 12/30/2021, 12/30/2020, 12/30/2019, 12/30/2018]
Index: []
从表中获取行
在这里,表中的每一行都存储在rows
中
rows = driver.find_elements(By.XPATH, '//div[@class="D(tbrg)"]//div[@data-test="fin-row"]')
for row in rows:
row_values = row.find_elements(By.XPATH, 'div/div')
df.loc[len(df)] = [row_value.text for row_value in row_values]
输出:
这给了我们预期的输出:
Breakdown | 018年12月30日||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 总收入 | >td style="text-align:left;">9074200089113000 | >td style="ext-align:left;">8552800091244000 | |||||||||||||
1 | 信贷损失准备金 | >td style="text-align:left|||||||||||||||
2 | 无息支出 | 3 | 特别收入费用 | td style="text-align:right;">4税前收入 | 5 | 税收条款 | 3521000 | 6 | 净收入普通股股东 | 7 | Com股东可用的稀释NI | 26565000 | >td style="ext-align:left基本EPS||||
9 | 稀释每股收益 | td style="text-align:right;">10基本平均股票 | td style="text-align:right;">11稀释平均股票 | td style="text-align:right;">12INTEREST_INCOME_AFER_PROVISION_FOR_LOAN_LOSS | >4708000013 | 持续经营净收入;已停止操作 | 28018000 | >td style="text align:left标准化收入|||||||||
15 | 货币市场投资总额 | 16 | 对账折旧 | 17 | 持续经营净收入少数股东净权益 | >2801800031978000 | >17894000 | 27430000 | 81447000||||||||
18 | 不包括商誉的异常项目总数 | td style="text-align:right;">19异常项目总数 | td style="text-align:right;">20计算税率 | td style="text-align:right;">21特殊项目的税收影响 | /table>