Class: Webpipe::BrowserSession
- Inherits:
-
Object
- Object
- Webpipe::BrowserSession
- Defined in:
- lib/webpipe/browser.rb
Overview
Handle to a persistent headless Chromium session on the server.
Server-side facts: sessions expire after 30 minutes idle; at most 2
concurrent running sessions per user. Always close when done.
Constant Summary collapse
- TERMINAL_STATUSES =
%w[stopped error expired].freeze
Instance Attribute Summary collapse
-
#expires_at ⇒ Object
readonly
Returns the value of attribute expires_at.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#session_name ⇒ Object
readonly
Returns the value of attribute session_name.
-
#status ⇒ Object
readonly
Returns the value of attribute status.
-
#url ⇒ Object
readonly
Returns the value of attribute url.
Instance Method Summary collapse
-
#action(type, **params) ⇒ Object
Run a raw browser action.
- #check(selector) ⇒ Object
- #clear_cookies ⇒ Object
- #click(selector, wait_after: nil) ⇒ Object
-
#close ⇒ Object
Stop the session and release server resources.
-
#evaluate(expression) ⇒ Object
Evaluate a JavaScript expression in the page (value in payload's "result").
- #fill(selector, value) ⇒ Object
- #get_cookies ⇒ Object
- #hover(selector) ⇒ Object
-
#initialize(http, id:, status:, url: nil, session_name: nil, expires_at: nil) ⇒ BrowserSession
constructor
A new instance of BrowserSession.
-
#navigate(url, formats: nil, scroll_to_bottom: nil, max_scrolls: nil, scroll_wait: nil, scroll_step: nil) ⇒ Object
Navigate to a new URL (with anti-bot handling) and scrape it.
- #press(key, selector: nil, wait_after: nil) ⇒ Object
-
#refresh ⇒ Object
Fetch the latest session state from the server.
-
#save_session ⇒ Object
Persist cookies/storage under this session's
session_name. -
#scrape(formats: nil, scroll_to_bottom: nil, max_scrolls: nil, scroll_wait: nil, scroll_step: nil) ⇒ Object
Scrape the current page without navigating (faster than
navigate). -
#screenshot(full_page: false) ⇒ Object
Take a screenshot.
- #scroll(direction: "down", amount: nil) ⇒ Object
- #select(selector, value) ⇒ Object
- #set_cookies(cookies) ⇒ Object
- #wait(ms = 1000) ⇒ Object
- #wait_for(selector, timeout: nil) ⇒ Object
-
#wait_until_running(timeout: 60, poll_interval: 1) ⇒ Object
Block until the session is ready to accept commands.
Constructor Details
#initialize(http, id:, status:, url: nil, session_name: nil, expires_at: nil) ⇒ BrowserSession
Returns a new instance of BrowserSession.
34 35 36 37 38 39 40 41 |
# File 'lib/webpipe/browser.rb', line 34 def initialize(http, id:, status:, url: nil, session_name: nil, expires_at: nil) @http = http @id = id @status = status @url = url @session_name = session_name @expires_at = expires_at end |
Instance Attribute Details
#expires_at ⇒ Object (readonly)
Returns the value of attribute expires_at.
30 31 32 |
# File 'lib/webpipe/browser.rb', line 30 def expires_at @expires_at end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
30 31 32 |
# File 'lib/webpipe/browser.rb', line 30 def id @id end |
#session_name ⇒ Object (readonly)
Returns the value of attribute session_name.
30 31 32 |
# File 'lib/webpipe/browser.rb', line 30 def session_name @session_name end |
#status ⇒ Object (readonly)
Returns the value of attribute status.
30 31 32 |
# File 'lib/webpipe/browser.rb', line 30 def status @status end |
#url ⇒ Object (readonly)
Returns the value of attribute url.
30 31 32 |
# File 'lib/webpipe/browser.rb', line 30 def url @url end |
Instance Method Details
#action(type, **params) ⇒ Object
Run a raw browser action. Returns the raw API payload Hash.
86 87 88 |
# File 'lib/webpipe/browser.rb', line 86 def action(type, **params) @http.post("#{base}/action", { type: type }.merge(params)) end |
#check(selector) ⇒ Object
108 |
# File 'lib/webpipe/browser.rb', line 108 def check(selector) = action("check", selector:) |
#clear_cookies ⇒ Object
116 |
# File 'lib/webpipe/browser.rb', line 116 def = @http.post("#{base}/cookies", { op: "clear" }) |
#click(selector, wait_after: nil) ⇒ Object
90 |
# File 'lib/webpipe/browser.rb', line 90 def click(selector, wait_after: nil) = action("click", **drop_nil(selector:, wait_after:)) |
#close ⇒ Object
Stop the session and release server resources.
67 68 69 70 71 |
# File 'lib/webpipe/browser.rb', line 67 def close @http.delete(base) @status = "stopped" nil end |
#evaluate(expression) ⇒ Object
Evaluate a JavaScript expression in the page (value in payload's "result").
106 |
# File 'lib/webpipe/browser.rb', line 106 def evaluate(expression) = action("evaluate", expression:) |
#fill(selector, value) ⇒ Object
91 |
# File 'lib/webpipe/browser.rb', line 91 def fill(selector, value) = action("fill", selector:, value:) |
#get_cookies ⇒ Object
110 111 112 113 |
# File 'lib/webpipe/browser.rb', line 110 def data = @http.get("#{base}/cookies") data["cookies"] || data["data"] || [] end |
#hover(selector) ⇒ Object
107 |
# File 'lib/webpipe/browser.rb', line 107 def hover(selector) = action("hover", selector:) |
#navigate(url, formats: nil, scroll_to_bottom: nil, max_scrolls: nil, scroll_wait: nil, scroll_step: nil) ⇒ Object
Navigate to a new URL (with anti-bot handling) and scrape it.
74 75 76 77 |
# File 'lib/webpipe/browser.rb', line 74 def navigate(url, formats: nil, scroll_to_bottom: nil, max_scrolls: nil, scroll_wait: nil, scroll_step: nil) body = { url: url }.merge(scrape_body(formats:, scroll_to_bottom:, max_scrolls:, scroll_wait:, scroll_step:)) Document.from_hash(@http.post("#{base}/navigate", body)["data"]) end |
#press(key, selector: nil, wait_after: nil) ⇒ Object
94 95 96 |
# File 'lib/webpipe/browser.rb', line 94 def press(key, selector: nil, wait_after: nil) action("press", **drop_nil(key:, selector:, wait_after:)) end |
#refresh ⇒ Object
Fetch the latest session state from the server.
44 45 46 47 48 49 50 51 |
# File 'lib/webpipe/browser.rb', line 44 def refresh info = @http.get(base) @status = info["status"] @url = info["url"] @session_name = info["session_name"] @expires_at = info["expires_at"] self end |
#save_session ⇒ Object
Persist cookies/storage under this session's session_name.
119 |
# File 'lib/webpipe/browser.rb', line 119 def save_session = @http.post("#{base}/save_session") |
#scrape(formats: nil, scroll_to_bottom: nil, max_scrolls: nil, scroll_wait: nil, scroll_step: nil) ⇒ Object
Scrape the current page without navigating (faster than navigate).
80 81 82 83 |
# File 'lib/webpipe/browser.rb', line 80 def scrape(formats: nil, scroll_to_bottom: nil, max_scrolls: nil, scroll_wait: nil, scroll_step: nil) body = scrape_body(formats:, scroll_to_bottom:, max_scrolls:, scroll_wait:, scroll_step:) Document.from_hash(@http.post("#{base}/scrape", body)["data"]) end |
#screenshot(full_page: false) ⇒ Object
Take a screenshot. The API returns a base64 PNG inside the payload.
103 |
# File 'lib/webpipe/browser.rb', line 103 def screenshot(full_page: false) = action("screenshot", full_page:) |
#scroll(direction: "down", amount: nil) ⇒ Object
98 |
# File 'lib/webpipe/browser.rb', line 98 def scroll(direction: "down", amount: nil) = action("scroll", **drop_nil(direction:, amount:)) |
#select(selector, value) ⇒ Object
92 |
# File 'lib/webpipe/browser.rb', line 92 def select(selector, value) = action("select", selector:, value:) |
#set_cookies(cookies) ⇒ Object
115 |
# File 'lib/webpipe/browser.rb', line 115 def () = @http.post("#{base}/cookies", { op: "set", cookies: }) |
#wait(ms = 1000) ⇒ Object
99 |
# File 'lib/webpipe/browser.rb', line 99 def wait(ms = 1000) = action("wait", ms:) |
#wait_for(selector, timeout: nil) ⇒ Object
100 |
# File 'lib/webpipe/browser.rb', line 100 def wait_for(selector, timeout: nil) = action("wait_for", **drop_nil(selector:, timeout:)) |
#wait_until_running(timeout: 60, poll_interval: 1) ⇒ Object
Block until the session is ready to accept commands.
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/webpipe/browser.rb', line 54 def wait_until_running(timeout: 60, poll_interval: 1) deadline = Time.now + timeout loop do refresh return self if @status == "running" raise Error, "Browser session #{@id} entered terminal status '#{@status}'" if TERMINAL_STATUSES.include?(@status) raise PollTimeoutError, "Browser session #{@id} not running after #{timeout}s" if Time.now >= deadline sleep poll_interval end end |