class Finviz::TickersFetcher
Fetch the list of tickers basing on the provided uri or array of filters
Attributes
uri[R]
Public Class Methods
new(uri: nil, filters: [], **rest)
click to toggle source
# File lib/finviz/tickers_fetcher.rb, line 8 def initialize(uri: nil, filters: [], **rest) raise("You should provide either uri or filters") if uri.present? && filters.present? raise("Do not support option #{rest.keys}") unless rest.empty? normalize_uri(uri, filters) end
Public Instance Methods
call()
click to toggle source
# File lib/finviz/tickers_fetcher.rb, line 15 def call all_pages = first_page + remaining_pages all_pages .map { |p| p.html.css("table span[onclick]") } .flatten .map { |a| a.children.text.gsub(/[[:space:]]+/, "") } end
Private Instance Methods
base_path()
click to toggle source
# File lib/finviz/tickers_fetcher.rb, line 61 def base_path "/screener.ashx" end
base_uri()
click to toggle source
# File lib/finviz/tickers_fetcher.rb, line 57 def base_uri "finviz.com" end
finviz_view_type()
click to toggle source
Output only tickers to reduce pages count
# File lib/finviz/tickers_fetcher.rb, line 66 def finviz_view_type 411 end
first_page()
click to toggle source
# File lib/finviz/tickers_fetcher.rb, line 25 def first_page @first_page ||= Crawler.call(paths: uri) end
generate_further_pages(number)
click to toggle source
# File lib/finviz/tickers_fetcher.rb, line 76 def generate_further_pages(number) (1...number).map do |i| uri.dup.tap do |inner_uri| new_query_ar = URI.decode_www_form(inner_uri.query) << ["r", i * per_page + 1] inner_uri.query = URI.encode_www_form(new_query_ar) end end end
normalize_uri(uri, filters)
click to toggle source
# File lib/finviz/tickers_fetcher.rb, line 39 def normalize_uri(uri, filters) uri = URI(uri || base_uri) @uri = URI::HTTPS.build( host: base_uri, path: base_path, query: CGI.unescape(URI.encode_www_form(query(uri, filters))) ) end
per_page()
click to toggle source
In tickers view we can get 1k of tickers per request. It is hardcoded be finviz
# File lib/finviz/tickers_fetcher.rb, line 72 def per_page 1_000 end
query(uri, filters)
click to toggle source
# File lib/finviz/tickers_fetcher.rb, line 49 def query(uri, filters) CGI.parse(uri.query || "").tap do |params| params["f"] = filters.join(",") if filters&.any? params["v"] = finviz_view_type params.delete("r") # remove offset if it was provided end end
remaining_pages()
click to toggle source
# File lib/finviz/tickers_fetcher.rb, line 29 def remaining_pages return @remaining_pages if @remaining_pages max_page = first_page.first.html.css("a.screener-pages").map { |a| a.children.text.to_i }.max return @remaining_pages = [] unless max_page paths = generate_further_pages(max_page) @remaining_pages = Crawler.call(paths: paths) end