Resumo : neste tutorial, você aprenderá como usar o módulo de threading Python para desenvolver um programa multithread.
Estendendo a classe Thread
Desenvolveremos um programa multithread que extrai os preços das ações do site do Yahoo Finance .
Para fazer isso, usaremos dois pacotes de terceiros:
requests
– para obter o conteúdo de uma página da web.lxml
– para selecionar um elemento específico de um documento HTML.
Primeiro, instale os módulos requests
e lxml
usando o comando pip :
pip install request lxml
Linguagem de código: Python ( python )
A seguir, defina uma nova classe chamada Stock
que herda da Thread
classe do threading
módulo. Colocaremos a classe Stock no stock.py
módulo:
import threading
class Stock(threading.Thread):
pass
Linguagem de código: Python ( python )
Em seguida, implemente o
método que aceita um símbolo e inicializa a __init__()
url
variável de instância com base no símbolo:
import threading
import requests
from lxml import html
class Stock(threading.Thread):
def __init__(self, symbol: str) -> None:
super().__init__()
self.symbol = symbol
self.url = f'https://finance.yahoo.com/quote/{symbol}'
self.price = None
Linguagem de código: Python ( python )
Por exemplo, se você passar o símbolo GOOG
para o __init__()
método, a URL será:
https://finance.yahoo.com/quote/GOOG
Linguagem de código: Python ( python )
Depois disso, substitua o run()
método da Thread
classe. O run()
método obtém o conteúdo de self.url
e obtém o preço da ação:
class Stock(threading.Thread):
def __init__(self, symbol: str) -> None:
super().__init__()
self.symbol = symbol
self.url = f'https://finance.yahoo.com/quote/{symbol}'
self.price = None
def run(self):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}
response = requests.get(self.url, headers=headers)
if response.status_code == 200:
# parse the HTML
tree = html.fromstring(response.text)
# get the price in text
price_text = tree.xpath(
'//*[@id="quote-header-info"]/div[3]/div[1]/div[1]/fin-streamer[1]/text()')
if price_text:
try:
self.price = float(price_text[0].replace(',', ''))
except ValueError:
self.price = None
def __str__(self):
return f'{self.symbol}\t{self.price}'
Linguagem de código: Python ( python )
Como funciona.
Faça uma solicitação ao URL usando o requests.get()
método:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}
response = requests.get(self.url, headers=headers)
Linguagem de código: Python ( python )
Observe que sem cabeçalhos válidos, o Yahoo retornará 404 em vez de 200.
Se a solicitação for bem-sucedida, o código de status HTTP será 200. Nesse caso, obtemos o conteúdo HTML da resposta e o passamos para a fromstring()
função do html
módulo do lxml
pacote:
if response.status_code == 200:
tree = html.fromstring(response.text)
Linguagem de código: Python ( python )
Cada elemento de uma página da web pode ser selecionado usando algo chamado XPath.
Para obter o XPath de um elemento usando o Google Chrome, inspecione a página, clique com o botão direito no elemento, selecione copiar e Copiar XPath.
O XPath do preço das ações no momento da redação deste tutorial é o seguinte:
//*[@id="quote-header-info"]/div[3]/div[1]/div[1]/fin-streamer[1]
Linguagem de código: Python ( python )
Para obter o texto do elemento, anexe no text()
final do XPath:
//*[@id="quote-header-info"]/div[3]/div[1]/div[1]/fin-streamer[1]/text()
Linguagem de código: Python ( python )
Observe que se o Yahoo alterar a estrutura da página, você precisará alterar o XPath de acordo. Caso contrário, o programa não funcionará conforme esperado:
price_text = tree.xpath('//*[@id="quote-header-info"]/div[3]/div[1]/div[1]/fin-streamer[1]/text()')
Linguagem de código: Python ( python )
Depois de obter o preço como texto, removemos a vírgula e o convertemos em um número:
if price_text:
try:
self.price = float(price_text[0].replace(',', ''))
except ValueError:
self.price = None
Linguagem de código: Python ( python )
Por fim, adicione o
método que retorna a representação em string do objeto Stock:__str__()
import threading
import requests
from lxml import html
class Stock(threading.Thread):
def __init__(self, symbol: str) -> None:
super().__init__()
self.symbol = symbol
self.url = f'https://finance.yahoo.com/quote/{symbol}'
self.price = None
def run(self):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}
response = requests.get(self.url, headers=headers)
if response.status_code == 200:
# parse the HTML
tree = html.fromstring(response.text)
# get the price in text
price_text = tree.xpath(
'//*[@id="quote-header-info"]/div[3]/div[1]/div[1]/fin-streamer[1]/text()')
if price_text:
try:
self.price = float(price_text[0].replace(',', ''))
except ValueError:
self.price = None
def __str__(self):
return f'{self.symbol}\t{self.price}'
Linguagem de código: Python ( python )
Usando a classe Estoque
O main.py
módulo a seguir usa a Stock
classe do stock.py
módulo:
from stock import Stock
symbols = ['MSFT', 'GOOGL', 'AAPL', 'META']
threads = []
for symbol in symbols:
t = Stock(symbol)
threads.append(t)
t.start()
for t in threads:
t.join()
print(t)
Linguagem de código: Python ( python )
Saída:
MSFT 253.67
GOOGL 2280.41
AAPL 145.86
META 163.27
Linguagem de código: Python ( python )
Como funciona.
Primeiro, importe a Stock
classe do stock.py
módulo:
from stock import Stock
Linguagem de código: Python ( python )
Segundo, inicialize uma lista de símbolos:
symbols = ['MSFT', 'GOOGL', 'AAPL', 'META']
Linguagem de código: Python ( python )
Terceiro, crie um thread para cada símbolo, inicie-o e anexe o thread à lista de threads:
threads = []
for symbol in symbols:
t = Stock(symbol)
threads.append(t)
t.start()
Linguagem de código: Python ( python )
Por fim, aguarde a conclusão de todos os threads da lista de threads e imprima o preço das ações:
for t in threads:
t.join()
print(t)
Linguagem de código: Python ( python )
Resumo
- Defina uma classe que herde da
threading.Thread
classe e substitua orun()
método.