2017-02-20 14 views
1

Я недавно начал узнавать больше о Python и о том, как разбирать сайты с помощью BeautifulSoup.Получить конкретные значения из BeautifulSoup Parsing

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я, кажется, застрял.

HTML код (после того, как принято суп):

<div class="mod-3-piece-app__visual-container__chart"> 
    <div class="mod-ui-chart--dynamic" data-chart-config='{"chartData":{"periods":[{"year":2013,"period":null,"periodicity":"A","icon":null},{"year":2014,"period":null,"periodicity":"A","icon":null},{"year":2015,"period":null,"periodicity":"A","icon":null},{"year":2016,"period":null,"periodicity":"A","icon":null},{"year":2017,"period":null,"periodicity":"A","icon":null},{"year":2018,"period":null,"periodicity":"A","icon":null}],"forecastRange":{"from":3.5,"to":5.5},"actualValues":[5.6785,6.45,9.22,8.31,null,null],"consensusData":[{"y":5.6307,"toolTipData":{"low":5.5742,"high":5.7142,"analysts":34,"restatement":null}},{"y":6.3434,"toolTipData":{"low":6.25,"high":6.5714,"analysts":35,"restatement":null}},{"y":9.1265,"toolTipData":{"low":9.02,"high":9.28,"analysts":40,"restatement":null}},{"y":8.2734,"toolTipData":{"low":8.17,"high":8.335,"analysts":40,"restatement":null}},{"y":8.9304,"toolTipData":{"low":8.53,"high":9.63,"analysts":41,"restatement":null}},{"y":10.1252,"toolTipData":{"low":8.63,"high":11.61,"analysts":42,"restatement":null}}]}}'> 
     <noscript> 
      <div class="mod-ui-chart--static"> 
       <div class="mod-ui-chart--sprited" style="width:410px; height:135px; background:url('/data/Charts/EquityForecast?issueID=36276&amp;height=135&amp;width=410') 0px -270px no-repeat;"> 
       </div> 
      </div> 
     </noscript> 
    </div> 
</div> 

Мой код:

from bs4 import BeautifulSoup 
import urllib.request 


data = [] 
List = ['AAPL'] 

# Iterates Through List 
for i in List : 
    # The webpage which we wish to Parse 
    soup = BeautifulSoup(urllib.request.urlopen('https://markets.ft.com/data/equities/tearsheet/forecasts?s=AAPL:NSQ').read(), 'lxml') 

    # Gathering the data 
    Values = soup.find_all("div", {"class":"mod-3-piece-app__visual-container__chart"})[4] 
    print(Values) 

    # Getting desired values from data 

То, что я хочу, чтобы достичь является значения после {"y" ....,, следовательно, числа 5.6307,6.3434,9.1265, 8.2734, 8.9304 and 10.1252, но я не могу для жизнь меня выясняет, как. Я пробовал Values.get_text, а также Values.text, но это просто пуст (вероятно, потому, что весь код находится внутри списка или что-то подобное).

Если бы я мог просто получить данные после «toolTipData», это было бы хорошо.

Есть ли кто-нибудь, что ум помогает мне?

Если я пропустил что-либо, пожалуйста, предоставьте отзыв, чтобы я мог сделать лучший вопрос в будущем.

Спасибо

ответ

1

Вскоре, вы хотите получить некоторую информацию, которая находится внутри атрибута тега.

Все, что я должен был сделать:

  1. открыть источник веб-страницы, чтобы понять, где находится ваш информация
  2. использование find_all ищет правильный атрибут класса mod-ui-chart--dynamic
  3. для каждого элемента, расположенного с помощью find_all, извлечение содержимого атрибута с использованием .get()
  4. поиск внутри строки содержимого атрибута для выражения 'actualValues'
  5. , если найдено 'actualValues', затем загрузите json и перейдите по его значениям.

Пробуйте следующий фрагмент кода. Я прокомментировал это, чтобы вы могли понять, что он делает.

Код:

from bs4 import BeautifulSoup 
import urllib.request 
import json 

data = [] 
List = ['AAPL'] 

# Iterates Through List 
for i in List: 
    # The webpage which we wish to Parse 
    soup = BeautifulSoup(urllib.request.urlopen('https://markets.ft.com/data/equities/tearsheet/forecasts?s=AAPL:NSQ').read(), 'lxml') 

    # Gathering the data 
    elemList = soup.find_all('div', {'class':'mod-ui-chart--dynamic'}) 

    #we will get the attribute info of each `data-chart-config` tag, inside each `div` with `class=mod-ui-chart--dynamic` 
    for elem in elemList: 

     elemID = elem.get('class') 
     elemName = elem.get('data-chart-config') 

     #if there's no value in elemName, pass... 
     if elemName is None: 
      pass 

     #if the term 'actualValues' exists in elemName 
     elif 'actualValues' in elemName: 
      #print('Extracting actualValues from:\n') 
      #print("Attribute id = %s" % elemID) 
      #print() 
      #print("Attribute name = %s" % elemName) 
      #print() 

      #reading `data-chart-config` attribute as a json 
      data = json.loads(elemName) 

      #print(json.dumps(data, indent=4, sort_keys=True)) 
      #print(data['chartData']['actualValues']) 

      #fetching desired info 
      val1 = data['chartData']['actualValues'][0] 
      val2 = data['chartData']['actualValues'][1] 
      val3 = data['chartData']['actualValues'][2] 
      val4 = data['chartData']['actualValues'][3] 

      #printing desired values 
      print(val1, val2, val3, val4) 

      print('-'*15) 

Выход:

1.9 1.42 1.67 3.36 
--------------- 
5.6785 6.45 9.22 8.31 
--------------- 
50557000000 42358000000 46852000000 78351000000 
--------------- 
170910000000 182795000000 233715000000 215639000000 
--------------- 

p.s.1: если вы хотите, вы можете раскомментировать print() функции внутри elif loop, чтобы разобраться в программе.

p.s.2: если вы хотите, вы можете изменить 'actualValues' на val1 = data['chartData']['actualValues'][0] к 'consensusData'

+0

Спасибо, это работает отлично 1 случай активов (только AAPL), но как только я пытаюсь включить другие активы (IBM, например) val1- val4 получает перегруженное. Я постараюсь сделать все возможное, чтобы найти способ разбить этот словарь на список, а затем просто добавить к нему для каждого прогона. –