Как вызвать конкретную таблицу на веб-странице с несколькими таблицами - PullRequest
1 голос
/ 05 июля 2019

Я пытаюсь получить информацию из определенной таблицы на этом сайте https://www.wsj.com/market-data. Это мой код до сих пор.Я новичок в Python в случае, если это не очевидно.Я хочу вытащить только информацию в таблице облигаций.Могу ли я индексировать таблицу, чтобы можно было вызывать определенные таблицы по индексу #?

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"))) 

Ответы [ 3 ]

1 голос
/ 05 июля 2019

Вы могли бы.У вас есть пара подходов к этому.Я предполагаю, что код, который вы разместили, захватывает полный HTML-код страницы, и если это так, вы можете поиграть с этим.На странице, если вы используете Chrome, нажмите F12 - это позволит вам увидеть полный HTML-код (или просто распечатать его на Python и быстро посмотреть).

Вариант 1: захватить таблицу по имени 'Облигации'

Посмотрите, как организовано DOM - имя «Облигации» является двоюродным братом таблицы, поэтому немного сложнее связать его с таблицей.Grossly Упрощенный Макет:

<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 ">

Таблица и название "Облигации", однако, разделяют бабушку и дедушку.Вы можете использовать регулярное выражение, чтобы найти связи заголовка - что-то вроде <h(?<hNum>[1-6]).*>.*Bonds.*</h\k<hNum>> - и затем найти следующую таблицу в скрипте, либо найдя следующий экземпляр <table.*>, либо воспользовавшись инструментом отображения DOM, который позволит вам путешествоватьдо бабушки и дедушки, а затем сузить до стола.Затем вы можете найти таблицу в ее великолепной HTML-форме и проанализировать ее оттуда.Этот подход, пожалуй, самый надежный, поскольку искомое имя можно изменить, чтобы найти любую из других таблиц.

Кроме того, вы также можете искать таблицу по имени класса, которое кажется уникальным., но не гарантируется, что это так и, таким образом, граничит с жестким кодированием.


Вариант 2: Индексирование

В подходе индексирования вы можете найти все <table.*>.*?</table>, проходя по циклуих и присвоение их массиву.Однако вам, вероятно, потребуется жестко указать, какой индекс таблицы вы хотите: если таблица облигаций является 5-й таблицей, подлежащей индексации, вам придется ссылаться на нее как table[5], что не идеально.Если это для простой и временной программы, или страница будет оставаться относительно статичной в течение длительного времени, этот подход может работать нормально, и он будет относительно простым.Однако, если макет страницы вообще меняется или ваша программа должна быть динамичной, возможно, стоит приложить усилия для создания более надежного подхода.

0 голосов
/ 05 июля 2019

Существует еще одна конечная точка, которую вы можете использовать, которую можно найти на вкладке сети при нажатии на страницу просмотра облигаций. Возвращенный 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)
0 голосов
/ 05 июля 2019

После выбора заголовка того контейнера, в котором находится нужная вкладка, все остальное легко.Вы также можете получить таблицу из тега сценария, используя только запросы, а затем выполнить обработку содержимого, используя json().Однако попробуйте следующий сценарий, чтобы получить табличное содержимое с использованием селена.

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']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...