#python #html #beautifulsoup
#python #HTML #beautifulsoup
Вопрос:
Я пытаюсь использовать ограничения фондового рынка webscrape, используя приведенный ниже код. Сначала я традиционно пытался получить список market cap values
использования bs4. Когда я print(x.find('span',{'class': 'Trsdu(0.3s)'}).text)
делал это, я получал AttributeError: 'NoneType' object has no attribute 'text'
ошибку.
for x in marketCapArray:
print(x.find('span',{'class': 'Trsdu(0.3s)'}).text)
Я не знал, как устранить указанную выше ошибку, специфичную для моего кода. Поэтому я выбрал альтернативу, используя регулярное выражение, чтобы просто извлечь требуемые значения, и попробовал это ниже.
Основной код
import bs4
import re
import requests
from bs4 import BeautifulSoup
from urllib.request import urlopen
def pickTopGainers():
url = 'https://in.finance.yahoo.com/gainers?offset=0amp;count=100'
page = urlopen(url)
soup = bs4.BeautifulSoup(page,"html.parser")
marketCapArray = soup.find_all('td', {'class': 'Va(m) Ta(end) Pstart(20px) Pend(10px) W(120px) Fz(s)',
'aria-label': 'Market cap'})
print(str(marketCapArray))
xi = re.findall("........</span>", str(marketCapArray)) # regex-use-1
pi = re.sub("(</span>|....>N/A|>|")","", str(xi))
print(pi)
pickTopGainers()
Результаты
Это то, что print(str(marketCapArray)
будет выводиться. (вставлена только некоторая часть)
[<td aria-label="Market cap" class="Va(m) Ta(end) Pstart(20px) Pend(10px) W(120px) Fz(s)" colspan="" data-reactid="93"><span class="Trsdu(0.3s)" data-reactid="94">159.404M</span></td>,
<td aria-label="Market cap" class="Va(m) Ta(end) Pstart(20px) Pend(10px) W(120px) Fz(s)" colspan="" data-reactid="119"><span class="Trsdu(0.3s)" data-reactid="120">533.97M</span></td>,
<td aria-label="Market cap" class="Va(m) Ta(end) Pstart(20px) Pend(10px) W(120px) Fz(s)" colspan="" data-reactid="145"><span data-reactid="146">N/A</span></td>,
<td aria-label="Market cap" class="Va(m) Ta(end) Pstart(20px) Pend(10px) W(120px) Fz(s)" colspan="" data-reactid="171"><span class="Trsdu(0.3s)" data-reactid="172">2.952B</span></td>,
<td aria-label="Market cap" class="Va(m) Ta(end) Pstart(20px) Pend(10px) W(120px) Fz(s)" colspan="" data-reactid="197"><span class="Trsdu(0.3s)" data-reactid="198">9.223B</span></td>,
<td aria-label="Market cap" class="Va(m) Ta(end) Pstart(20px) Pend(10px) W(120px) Fz(s)" colspan="" data-reactid="223"><span data-reactid="224">N/A</span></td>]
Это результат print(pi)
. Также конечный результат.
['159.404M', '533.97M', '', '2.952B', '9.223B', '']
Вопрос
Как я могу избежать использования замены регулярных выражений (re.sub) в приведенном выше Main Code
для достижения заданного конечного результата pi
? или предложите мне правильный подход для этого. Я чувствую, что мое регулярное выражение неприятно.
Ответ №1:
Вы можете перебирать строку за строкой внутри <table>
, где хранится вся информация. Например:
import requests
from bs4 import BeautifulSoup
url = 'https://in.finance.yahoo.com/gainers?offset=0amp;count=100'
soup = BeautifulSoup(requests.get(url).content, 'html.parser')
fmt_string = '{:<15} {:<60} {:<10} {:<10} {:<10} {:<10} {:<10} {:<10} {:<10}'
print(fmt_string.format('Symbol', 'Name', 'Price(int)', 'Change', '% change', 'Volume', 'AvgVol(3M)', 'Market Cap', 'PE ratio'))
for row in soup.select('table:has(a[href*="/quote/"]) > tbody > tr'):
cells = [td.get_text(strip=True) for td in row.select('td')]
print(fmt_string.format(*cells[:-1]))
С принтами:
Symbol Name Price(int) Change % change Volume AvgVol(3M) Market Cap PE ratio
CCCL.NS Consolidated Construction Consortium Limited 0.2000 0.0500 33.33% 57,902 290,154 159.404M N/A
KSERASERA.NS KSS Limited 0.2500 0.0500 25.00% 1.607M 2.601M 533.97M N/A
BONLON.BO BONLON INDUSTRIES LIMITED 21.60 3.60 20.00% 16,000 N/A N/A N/A
MENONBE.NS Menon Bearings Limited 52.80 8.80 20.00% 2.334M 65,713 2.952B 25.05
RPOWER.NS Reliance Power Limited 3.3000 0.5500 20.00% 127.814M 18.439M 9.223B N/A
11DPD.BO Nippon India Mutual Fund 0.0600 0.0100 20.00% 190 N/A N/A N/A
ABFRLPP-E1.NS Aditya Birla Rs.5 ppd up 105.65 17.60 19.99% 1.238M N/A N/A N/A
500110.BO Chennai Petroleum Corporation Limited 64.55 -0.15 -0.23% 42,765 61,584 9.612B N/A
ABFRLPP.BO Aditya Birla Fashion and Retai 106.05 17.65 19.97% 387,703 N/A N/A N/A
RADIOCITY.NS Music Broadcast Limited 21.35 3.55 19.94% 12.657M 1.013M 7.38B 124.13
RADIOCITY.BO Music Broadcast Limited 21.35 3.55 19.94% 898,070 90,236 7.38B 124.13
MENONBE.BO Menon Bearings Limited 52.65 8.75 19.93% 137,065 8,648 2.951B 24.98
MTNL.BO Mahanagar Telephone Nigam Limited 10.72 1.78 19.91% 1.142M 156,275 6.754B N/A
...and so on.
Комментарии:
1. Спасибо, это выглядит намного лучше для работы. Однако возможно ли извлечь значения этой таблицы, напечатанные отдельно. Как и каждая строка в качестве словаря, чтобы я мог облегчить некоторые артематики на нем.
2. @Thinker-101 Вы можете сделать, например
print( cells[7] )
, для печати только рыночной капитализации. Вы можете сохранить его внутри списка, например, и т.д..