Использование Beautiful Soup для простого отслеживания цен на акции

#python #beautifulsoup

#python #beautifulsoup

Вопрос:

Я пытаюсь создать бот для отслеживания цен на акции, но на веб-сайте есть такой код:

         <div class="kurBox">
        <span class="text">ALIŞ(TL)</span>
        <span class="value up">7,8175</span>
    </div>
    <div class="kurBox">
        <span class="text">SATIŞ(TL)</span>
        <span class="value up">7,8240</span>
 

Мне нужно получить значение обеих этих строк после текстов. И когда значение теперь становится ниже начального значения сегодняшнего дня, класс меняется на значение down.

Вот часть кода, который я использую, код работает, делает почти все, что я хочу, но он не извлекает оба значения одновременно, и иногда значения смешиваются, когда один из их классов изменяется на значение down. Как я могу решить эту проблему?

 url = "http://bigpara.hurriyet.com.tr/doviz/dolar/"
response = requests.get(url)
soup = BeautifulSoup(response.text, "lxml-xml")
old_value = soup.find("span" ,attrs={"class":"value up"}).text
first_value = soup.find("span" ,attrs={"class":"value up"}).text
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
print(" ")
print("******************************************")
print("|", current_time, "|", "Doların ilk fiyatı: ", first_value, "|")
print("******************************************")
print(" ")
print(" ")


bakiye = round(float(100.0000), 4)
dolar = int(0)
hold = time.sleep(0)

while True:
 time.sleep(1)
 url = "http://bigpara.hurriyet.com.tr/doviz/dolar/"
 response = requests.get(url)
 soup = BeautifulSoup(response.text, "lxml-xml")
 new_value = soup.find("span" ,attrs={"class":"value up"}).text
 

Комментарии:

1. вероятно, вам нужно find_all вместо find — получить список со всеми элементами.

2. Число 0 (ноль) уже является целочисленным значением, и нет необходимости использовать int() dolar = 0 . Число 100.0000 уже является значением с плавающей запятой, и его не нужно использовать float() — и оно округляется до 4 мест, поэтому нет необходимости использовать round() bakiye = 100.0000 . И sleep(0) не имеет смысла.

3. @furas Idk это выдавало ошибку, поэтому я попытался указать их, и это сработало. Возможно, это нужно указать для остальной части кода. И find_all результат такой: AttributeError: ResultSet object has no attribute 'text'. You're probably treating a list of elements like a single element. Did you call find_all() when you meant to call find()? и если я удалю .text его, он напечатает всю строку <span class="value up">7,8288</span>, <span class="value up">7,8345</span>

4. как я уже говорил в предыдущем комментарии — find_all выдает СПИСОК со всеми элементами. И когда у вас есть list, вам нужно использовать for -loop для работы с каждым элементом отдельно и получения .text отдельного — ie. for item in list: print(item.text)

Ответ №1:

Вам нужно будет использовать .find_all() , как предложено. Чтобы справиться с изменением атрибута класса с value up , на value down , вы можете использовать регулярное выражение для получения элементов, содержащих класс value . Тогда это приведет к увяданию.

Не уверен, что именно вам нужен результат, но это должно заставить вас работать:

 import requests
from bs4 import BeautifulSoup
from datetime import datetime
import re


url = "http://bigpara.hurriyet.com.tr/doviz/dolar/"
response = requests.get(url)
soup = BeautifulSoup(response.text, "lxml-xml")

values_list = []
values = soup.find_all('span',{re.compile('value')})
for val in values:
    text = val.find_previous('span').text
    value = val.text
    values_list.append((text,value))
    
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
print(" ")
print("******************************************")
print("|", current_time, "|", "Doların ilk fiyatı: ", values_list[0][1], "|")
print("******************************************")
print(" ")
print(" ")

print ('Second value: ', values_list[1][1])
 

Вывод:

 ******************************************
| 11:14:46 | Doların ilk fiyatı:  7,8240 |
******************************************
 
 
Second value:  7,8279