#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