Как выделить результаты при помощи soup.find () в Beautifulsoup4 для Python 3.6? - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь получить цену символа тикера с веб-сайта, и в инструменте проверки цена акции выглядит так, как будто она определяется по следующей строке:

<meta itemprop="price" content="274.9">

и мой кодв Python выглядит так:

import urllib.request
from bs4 import BeautifulSoup

quote_page = 'https://www.bloomberg.com/quote/SPY:US'
page = urllib.request.urlopen(quote_page)
soup = BeautifulSoup(page.read(), 'html.parser')
price_box = soup.find('meta', {"itemprop" : "price"})
print(price_box)

Но в терминале он печатает весь мета-контент, который содержит слово "цена" в начале.Как PriceChange, PriceCurrency и т. Д. Я просто хочу результаты "цена".Также он будет отображаться так:

<meta content="274.9" itemprop="price"> <meta content="1.3" itemprop="priceChange"> <meta content="0.475146" itemprop="priceChangePercent"> <meta content="2018-06-04T20:15:05.000Z" itemprop="quoteTime"> <meta content="USD" itemprop="priceCurrency"> </meta></meta></meta></meta></meta>

Как отобразить только номер?

1 Ответ

0 голосов
/ 05 июня 2018

Во-первых, на самом деле это не поиск нескольких значений;тот факт, что другие теги meta имеют itemprop s, начинающиеся с price, является простым совпадением.find вызов всегда находит только один тег.И даже если вы используете find_all, он выдаст вам список этого тега.Проблема в том, что это вложенный тег, который включает в себя все остальные внутри него.


Если вы посмотрите на HTML, это не то, что на самом деле там.Все теги являются самозакрывающимися, независимыми дочерними элементами "schema-org-financial-quote" div itemscope, не вложенными друг в друга.

Кажется, проблема в том, что этот HTML-код недействителен, и html.parser догадывается об этом не так, как ваш браузер.

Насколько я могу судить по взгляду на спецификации, тег meta в body, который обеспечивает itemprop для itemscope не должен быть закрыт.Но на странице есть самозакрывающиеся теги meta.

Очевидный способ, которым человек мог бы прочитать это, состоит в том, чтобы просто игнорировать закрытие и рассматривать их как независимых братьев и сестер, какими они кажутся.И это то, что делают по крайней мере Chrome и Firefox.(Интересно, что, по крайней мере, в Chrome, самозакрывающиеся теги meta в head обрабатываются иначе, чем самозакрывающиеся теги itemprop meta в body, что подразумевает, что он может сознательно обходить ошибкистраницы, подобные этой.)

Но html.parser делает что-то другое, и вместо этого вкладывает каждую из них в предыдущую.

Если я прав, что HTML на самом деле неверен, это не такТехнически это ошибка.Но, вероятно, было бы лучше справиться с этим лучше.Начиная с Python 2.7 / 3.2, html.parser считается «снисходительным, как браузер», и он не делает то, что здесь делают браузеры.Таким образом, вы можете найти ошибку в этом и подать одну, если ее не существует .(Однако, даже если это исправить, скажем, в Python 3.7.1 или 3.8, это не поможет, если кто-то запустит ваш код в 3.6.4.)


Если вы можете использовать lxml или html5lib вместо html.parser, который решает вашу проблему - оба они выполняют синтаксический анализ этих тегов так же, как это делает Chrome, что, по-видимому, вам и нужно.


Однако… делайте…вам на самом деле нужно это решить?Если вы просто хотите content тега price, он уже работает:

>>> price_box = soup.find('meta', {"itemprop" : "price"})
>>> print(price_box['content'])
274.9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...