Compare commits

...

16 Commits

Author SHA1 Message Date
90353f1251 Update 'README.md' 2023-06-15 11:00:55 -07:00
148f59664e update license 2023-03-16 12:52:44 -07:00
6225cf7fd0 Delete setup.cfg 2021-12-04 19:24:14 -08:00
3a6b6d26d5 Include requirements 2021-12-04 19:15:35 -08:00
b8fd0276df Update branch info 2021-12-04 19:00:34 -08:00
5f23f1c04c Reformat code and bump version 2021-12-04 18:53:48 -08:00
14be2b99c5 Update README
Fix installation instructions, and miscellaneous cleanup
2021-12-04 18:50:58 -08:00
1bd1ced732 Use f-strings 2021-12-04 18:46:49 -08:00
9f1bd098bc Use newer user agent 2021-12-04 18:45:45 -08:00
43a0a9408e Work with new Yahoo! Finance site
Closes Issue #3
2021-12-04 18:45:04 -08:00
204a91b1f6
Add space to README
Oops
2021-05-26 19:51:30 -07:00
879ac760d0
Mention ETFs and mutual funds in readme
Mention ETFs and mutual funds (and refer to #2)
2021-05-26 19:50:48 -07:00
8b202c4fb2
Remove copyright notice 2021-05-26 13:42:53 -07:00
0d12a89e58
Update setup.py 2021-05-26 13:41:49 -07:00
518692c69f
Merge pull request #2 from ausmal/master
Fix issue with historical quotes for mutual funds
2021-05-26 13:38:23 -07:00
Austin Maliszewski
6225cecf45 Fix issue with historical quotes for mutual funds
Mutual funds do not have volume information, so int parse was failing.
Also fixed warning about 'is' comparison with literal.
2021-05-26 10:39:53 -05:00
6 changed files with 55 additions and 63 deletions

View File

@ -1,3 +1,6 @@
# Branches
All PRs should be made against the `devel` branch.
# `black`
Be sure to run

View File

@ -1,14 +1,22 @@
`stockquotes` is a simple Python module for collecting stock quotes and
historical data from Yahoo! Finance. It's perfect for developers who can't
afford the (often high) prices charged by many stock data APIs.
`stockquotes` is a Python module for collecting stock, ETF, and mutual fund
quotes and historical data from Yahoo! Finance.
# Branches
* `devel`: current development version
* `stable`: latest stable release
All PRs should be made against devel.
# Requirements
* Python 3.5+
* Python 3.6+
* Beautiful Soup 4
# Installation
pip3 install stockquotes
pip3 install git+https://git.kj7rrv.com/kj7rrv/stockquotes@stable
Do not install from PyPI; the PyPI package is no longer updated.
# Usage
First, import the `stockquotes` module.
@ -48,13 +56,13 @@ for recent IPOs. Also, a known but unexplained bug causes it to only give two
days of data for some stocks.
# Exceptions
`stockquotes.StockDoesNotExistError` is raised when the stock does not exist.
`stockquotes.StockDoesNotExistError` is raised when the stock does not (appear
to) exist.
`stockquotes.NetworkError` is raised when a connection to Yahoo! Finance
cannot be established.
# License
Copyright (c) 2019 ScoopGracie. All rights reversed.
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
beautifulsoup4

View File

@ -1,4 +0,0 @@
[egg_info]
tag_build =
tag_date = 0

View File

@ -4,7 +4,7 @@ with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="stockquotes",
version="2.0.1",
version="2.0.4",
description="A simple module for retreiving stock data",
long_description=long_description,
long_description_content_type="text/markdown",
@ -13,5 +13,6 @@ setuptools.setup(
"Programming Language :: Python :: 3",
"Operating System :: OS Independent",
],
python_requires=">=3.5",
python_requires=">=3.6",
install_requires="beautifulsoup4",
)

View File

@ -1,28 +1,18 @@
#!/usr/bin/env python3
# stockquotes - Python module to pull stock quotes from Yahoo! Finance
# Copyright 2020 ScoopGracie. All rights reversed.
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
# Copyright 2020-2023 Samuel Sloniker
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
# THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
from bs4 import BeautifulSoup as bs
import requests
@ -41,14 +31,14 @@ class Stock:
def __init__(self, ticker):
try:
r = requests.get(
"https://finance.yahoo.com/quote/{}/history".format(ticker),
f"https://finance.yahoo.com/quote/{ticker}/history",
headers={
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3941.4 Safari/537.36"
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0"
},
)
except:
raise NetworkError()
if r.status_code is 302:
if r.status_code == 302:
raise StockDoesNotExistError(ticker)
try:
soup = bs(r.text, features="lxml")
@ -70,39 +60,32 @@ class Stock:
"adjusted_close": float(
row[5].span.string.replace(",", "")
),
"volume": int(row[6].span.string.replace(",", "")),
"volume": int(row[6].span.string.replace(",", ""))
if row[6].string != "-"
else None,
}
except:
continue
self.historical.append(parsed)
top_data = soup.find(id="quote-header-info")
try:
self.current_price = float(
top_data.findAll("span")[11].string.replace(",", "")
)
raw_change = top_data.findAll("span")[12].string
except IndexError:
self.current_price = float(
top_data.findAll("span")[3].string.replace(",", "")
)
raw_change = top_data.findAll("span")[4].string
except ValueError:
self.current_price = float(
top_data.findAll("span")[9].string.replace(",", "")
)
raw_change = top_data.findAll("span")[10].string
self.increase_dollars = float(
raw_change.split(" ")[0].replace(",", "")
)
self.increase_percent = float(
raw_change.split(" ")[1]
.replace(",", "")
.replace("(", "")
.replace(")", "")
.replace("%", "")
price_selector = f'fin-streamer[data-field="regularMarketPrice"][data-symbol="{self.symbol}"]'
price_element = soup.select_one(price_selector)
self.current_price = float(price_element.text)
change_selector = f'fin-streamer[data-field="regularMarketChange"][data-symbol="{self.symbol}"]'
change_element = soup.select_one(change_selector)
self.increase_dollars = float(change_element.text)
change_percent_selector = f'fin-streamer[data-field="regularMarketChangePercent"][data-symbol="{self.symbol}"]'
change_percent_element = soup.select_one(change_percent_selector)
change_percent_text = "".join(
[
char
for char in change_percent_element.text
if char in "-.0123456789"
]
)
self.increase_percent = float(change_percent_text)
except AttributeError as error:
raise StockDoesNotExistError(ticker) from error