簡體   English   中英

如何在具有多個表格的網頁上調用特定表格

[英]How to call specific table on webpage with multiple tables

我正在嘗試從本網站https://www.wsj.com/market-data上的特定表格中提取信息。 到目前為止,這是我的代碼。 我是 python 的新手,以防它不明顯。 我只想提取 Bonds 表中的信息。 我可以索引表以便我可以通過索引 # 調用特定的表嗎?

from selenium import webdriver
from bs4 import BeautifulSoup
import requests
browser=webdriver.Chrome
chrome_path=r"C:\Users\ddai\AppData\Local\Programs\Python\Python37\chromedriver.exe"
driver=webdriver.Chrome(chrome_path)
url2="https://wsj.com/market-data"
driver.get(url2)
html=driver.execute_script("return document.documentElement.outerHTML")
sel_soup=BeautifulSoup(html,'html.parser') 
print(len(sel_soup.findAll("table"))) 

你可以。 你有幾種方法可以解決這個問題。 我認為您發布的代碼獲取了頁面的完整 HTML,如果是這樣,您可以使用它。 在頁面上,如果使用 Chrome,請按F12 - 這可以讓您看到完整的 HTML(或者只是在 Python 中打印它並查看)。

選項 1:按名稱“債券”抓取表格

看看DOM是如何組織的——名稱“Bonds”是表的表親,因此將它與表聯系起來有點棘手。 大大簡化的布局:

<div>
    <div>
        <h3><span>Bonds</span></h3>
    </div>
    <article></article>
    <div class="WSJTables--tableWrapper--2oPULowO WSJBase--card--3gQ6obvQ ">
        <table class="WSJTables--table--1SdkiG8p WSJTheme--table--2a-shks_ ">
            <thead class="WSJTables--table__head--hprNkLrs WSJTheme--table__head--3n6NRMJE ">

不過,這張桌子和名字“Bonds”共享祖父母。 您可以使用正則表達式來查找標題鍵——比如<h(?<hNum>[1-6]).*>.*Bonds.*</h\\k<hNum>> ——然后找到通過查找<table.*>下一個實例,或者使用一些 DOM 映射工具,您可以向上移動到祖父母,然后縮小到表,從而找到腳本中的下一個表。 然后,您可以找到完整、精美的 HTML 表單並從那里解析它。 這種方法可能是最可靠的,因為可以更改您搜索的名稱以查找任何其他表。

或者,您也可以通過其類名搜索表,這似乎是唯一的,但不能保證是唯一的,因此接近於硬編碼。


選項 2:索引

在索引方法中,您可以找到所有<table.*>.*?</table> ,循環遍歷它們並將它們分配給一個數組。 但是,您可能需要對所需的表索引進行硬編碼:如果債券表是要建立索引的第 5 個表,則必須將其引用為table[5] ,這不太理想。 如果這是一個簡單的臨時程序,或者頁面會長時間保持相對靜止,這種方法可以正常工作,並且會相對簡單。 但是,如果頁面的布局發生了根本變化,或者您的程序需要是動態的,那么構建更可靠的方法可能是值得的。

一旦您選擇了所需標簽所在的容器的標題,其余的就很容易了。 您還可以僅使用請求從腳本標簽獲取表格,然后使用json()對內容進行后期處理。 但是,請嘗試使用下面的腳本來使用 selenium 獲取表格內容。

from selenium import webdriver
from bs4 import BeautifulSoup

with webdriver.Chrome() as driver:
    driver.get("https://wsj.com/market-data")
    sel_soup = BeautifulSoup(driver.page_source,'html.parser') 
    for items in sel_soup.select_one("[class*='card__header']:contains(Bonds)").find_parent().select("table tr"):
        data = [item.get_text(strip=True) for item in items.select("th,td")]
        print(data)

輸出:

['Country', 'Yield(%)', 'Yield Chg']
['U.S. 10 Year', '2.040', '0.090']
['Germany 10 Year', '-0.362', '0.034']
['U.K. 10 Year', '0.739', '0.059']
['Japan 10 Year', '-0.163', '-0.008']
['Australia 10 Year', '1.293', '-0.010']
['China 10 Year', '3.176', '-0.012']

單擊查看綁定頁面時,您可以在網絡選項卡中找到另一個端點。 可以解析返回的 json 以檢索表。 這會帶回比您提供的 url 中顯示的信息多一點的信息,但包括您需要的信息。

import requests
from bs4 import BeautifulSoup as bs
import pandas as pd
import re

def get_bond_info(r):
    data = r['data']['instruments']
    results = []
    for item in data:
        results.append(
        {'Name': item['djLegalName'],
         'CPN (%)': item['couponPercent'],
         'LATEST SPREAD OVER TREASURY': item['spread'],
         'YLD (%)': item['yieldPercent'],
         'YLD CHG': item['yieldChange']
        }
        ) 
    df = pd.DataFrame(results, columns = ['Name', 'CPN (%)', 'Spread','YLD (%)','YLD CHG' ])
    return df

identifier = '''{"application":"WSJ",
                "bonds":[
                    {"symbol":"TMUBMUSD10Y","name":"U.S."},
                    {"symbol":"TMBMKDE-10Y","name":"Germany"},
                    {"symbol":"TMBMKGB-10Y","name":"U.K."},
                    {"symbol":"TMBMKJP-10Y","name":"Japan"},
                    {"symbol":"TMBMKAU-10Y","name":"Australia"},
                    {"symbol":"AMBMKRM-10Y","name":"China"},
                    {"symbol":"TMBMKNZ-10Y","name":"New Zealand"},
                    {"symbol":"TMBMKFR-10Y","name":"France"},
                    {"symbol":"TMBMKIT-10Y","name":"Italy"},
                    {"symbol":"TMBMKES-10Y","name":"Spain"}
                ]
             }'''


url = 'https://www.wsj.com/market-data/bonds?id=' + re.sub('\n\s+','',identifier) + '&type=mdc_governmentbonds'
r = requests.get(url).json()
print(get_bond_info(r))

如果您熟悉構造,則可以檢索其他信息,例如不同的時間段

import requests
from bs4 import BeautifulSoup as bs
import pandas as pd

url = 'https://www.wsj.com/market-data/bonds?id={"application":"WSJ","instruments":[{"symbol":"BOND/BX//TMUBMUSD30Y","name":"30-Year Bond"},{"symbol":"BOND/BX//TMUBMUSD10Y","name":"10-Year Note"},{"symbol":"BOND/BX//TMUBMUSD07Y","name":"7-Year Note"},{"symbol":"BOND/BX//TMUBMUSD05Y","name":"5-Year Note"},{"symbol":"BOND/BX//TMUBMUSD03Y","name":"3-Year Note"},{"symbol":"BOND/BX//TMUBMUSD02Y","name":"2-Year Note"},{"symbol":"BOND/BX//TMUBMUSD01Y","name":"1-Year Bill"},{"symbol":"BOND/BX//TMUBMUSD06M","name":"6-Month Bill"},{"symbol":"BOND/BX//TMUBMUSD03M","name":"3-Month Bill"},{"symbol":"BOND/BX//TMUBMUSD01M","name":"1-Month Bill"}]}&type=mdc_quotes'
r = requests.get(url).json()
data = r['data']['instruments']
results = []
for item in data:
    results.append(
    {'Name': item['formattedName'],
     'CPN (%)': item['bond']['couponRate'],
     'PRC CHG': item['bond']['formattedTradePriceChange'],
     'YLD (%)': item['bond']['yield'],
     'YLD CHG': item['bond']['yieldChange']
    }
    )

df = pd.DataFrame(results, columns = ['Name', 'CPN (%)', 'PRC CHG','YLD (%)','YLD CHG' ])
print(df)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM