【问题标题】:Get data form table in beautiful soup从beautifulsoup中的表中获取数据
【发布时间】:2020-07-02 19:36:31
【问题描述】:

我正在尝试通过此页面检索股票的“流通股”:

https://www.sec.gov/cgi-bin/viewer?action=view&cik=320193&accession_number=0000320193-20-000052&xbrl_type=v#

(点击“财务报表”-“简明合并资产负债表(未经审计)(括号内)”)

数据在左行表格的底部,我正在使用漂亮的汤,但在检索份额计数时遇到问题。

我正在使用的代码:

import requests
from bs4 import BeautifulSoup

URL = 'https://www.sec.gov/cgi-bin/viewer?action=view&cik=320193&accession_number=0000320193-20-000052&xbrl_type=v#'
page = requests.get(URL)

soup = BeautifulSoup(page.content, 'html.parser')

rows = soup.find_all('tr')

for row in rows:
    document = row.find('a', string='Common stock, shares outstanding (in shares)')
    shares = row.find('td', class_='nump')
    if None in (document, shares):
        continue
    print(document)
    print(shares)

这不返回任何内容,但所需的输出是4,323,987,000

有人可以帮我检索这些数据吗?

谢谢!

【问题讨论】:

    标签: python python-3.x beautifulsoup


    【解决方案1】:

    这是一个 JS 渲染的页面。使用Selenium

    from selenium import webdriver
    from webdriver_manager.chrome import ChromeDriverManager
    from time import sleep
    # import requests
    from bs4 import BeautifulSoup
    url = 'https://www.sec.gov/cgi-bin/viewer?action=view&cik=320193&accession_number=0000320193-20-000052&xbrl_type=v#'
    
    driver = webdriver.Chrome(ChromeDriverManager().install())
    driver.set_window_size(1024, 600)
    driver.maximize_window()
    driver.get(url)
    time.sleep(10) # <--- waits for 10 seconds so that page can gets rendered
    # action = webdriver.ActionChains(driver)
    # print(driver.page_source) # <--- this will give you source code 
    soup = BeautifulSoup(driver.page_source)
    rows = soup.find_all('tr')
    
    for row in rows:
        shares = row.find('td', class_='nump')
        if shares:
            print(shares)
    

    <td class="nump">4,334,335<span></span>
    </td>
    <td class="nump">4,334,335<span></span>
    </td>
    


    更好的使用:

    shares = soup.find('td', class_='nump')
    if shares:
        print(shares.text.strip())
    

    4,334,335
    

    【讨论】:

    • 感谢您的回答。你能向我解释一下 webdriver_manager.chrome 是什么吗?找不到像这样命名的包,webdrivermanager也不行。
    • 不幸的是,我无法复制您的结果,因为我无法弄清楚 webdrive_manager.chrome 的含义。你能帮我解决这个问题吗?
    【解决方案2】:

    啊,刮 EDGAR 文件的乐趣 :(...

    您没有得到预期的输出,因为您找错了地方。您拥有的网址是 ixbrl 查看器。数据来自这里:

    url = 'https://www.sec.gov/Archives/edgar/data/320193/000032019320000052/R1.htm'
    

    您可以通过查看开发人员中的网络选项卡找到该 url,或者,您可以简单地将查看器 url 转换为该 url:例如,320193&amp; 数字是 cik 编号等。

    一旦你弄清楚了,剩下的就很简单了:

    req = requests.get(url)
    soup = bs(req.text,'lxml')
    soup.select_one('.nump').text.strip()
    

    输出:

    '4,334,335'
    

    编辑:

    要按“流通股”搜索,请尝试:

    targets = soup.select('tr.ro')
    for target in targets:
        targ = target.select('td.pl')
        for t in targ:
            if "Shares Outstanding" in t.text:
                print(target.select_one('td.nump').text.strip())
    

    还不如把这个扔进去:另一种不同的方法是使用 xpath 来代替,使用 lxml 库:

    import lxml.html as lh
    
    doc = lh.fromstring(req.text)
    doc.xpath('//tr[@class="ro"]//td[@class="pl "][contains(.//text(),"Shares Outstanding")]/following-sibling::td[@class="nump"]/text()')[0]
    

    【讨论】:

    • 感谢您指出这一点,我会解决这个问题并让您知道它是否有效
    • 好吧,所以您的解决方案运行良好,尽管它存在一个问题。这将检索“.nump”的第一次出现,但在某些情况下,可以在第二次或第三次出现时找到份额计数。是否可以通过使用“实体普通股,已发行股票”而不是“.nump”来检索它?似乎无法弄清楚如何做到这一点
    • @Jackey12345 是的,这是可能的——假设它们具有相同的内部结构。见编辑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 2017-05-12
    • 1970-01-01
    • 2023-03-20
    • 2021-10-31
    • 2021-07-07
    • 1970-01-01
    相关资源
    最近更新 更多