{"id":18234632,"url":"https://github.com/ronin-rb/ronin-web","last_synced_at":"2025-10-03T17:42:44.124Z","repository":{"id":795715,"uuid":"494612","full_name":"ronin-rb/ronin-web","owner":"ronin-rb","description":"ronin-web is a collection of useful web helper methods and commands.","archived":false,"fork":false,"pushed_at":"2025-02-15T06:49:23.000Z","size":1149,"stargazers_count":42,"open_issues_count":7,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-06-14T07:44:13.718Z","etag":null,"topics":["cli","crawler","hacktoberfest","helpers","html","proxy-server","ronin-rb","ruby","server","spider","web","xml"],"latest_commit_sha":null,"homepage":"https://ronin-rb.dev","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ronin-rb.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"COPYING.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"open_collective":"ronin-rb","patreon":"roninrb"}},"created_at":"2010-01-30T02:36:33.000Z","updated_at":"2025-02-15T06:46:13.000Z","dependencies_parsed_at":"2024-01-15T09:05:03.995Z","dependency_job_id":"abc72997-02ba-4710-bee1-cc5840d900c8","html_url":"https://github.com/ronin-rb/ronin-web","commit_stats":{"total_commits":1157,"total_committers":4,"mean_commits":289.25,"dds":"0.0034572169403630504","last_synced_commit":"77d1782ad0e180e4bdb110288544e5fa28228213"},"previous_names":["ronin-ruby/ronin-web"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/ronin-rb/ronin-web","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ronin-rb","download_url":"https://codeload.github.com/ronin-rb/ronin-web/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-web/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261038883,"owners_count":23100969,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","crawler","hacktoberfest","helpers","html","proxy-server","ronin-rb","ruby","server","spider","web","xml"],"created_at":"2024-11-04T23:04:31.041Z","updated_at":"2025-10-03T17:42:44.049Z","avatar_url":"https://github.com/ronin-rb.png","language":"Ruby","funding_links":["https://opencollective.com/ronin-rb","https://patreon.com/roninrb"],"categories":[],"sub_categories":[],"readme":"# ronin-web\n\n[![CI](https://github.com/ronin-rb/ronin-web/actions/workflows/ruby.yml/badge.svg)](https://github.com/ronin-rb/ronin-web/actions/workflows/ruby.yml)\n[![Code Climate](https://codeclimate.com/github/ronin-rb/ronin-web.svg)](https://codeclimate.com/github/ronin-rb/ronin-web)\n[![Gem Version](https://badge.fury.io/rb/ronin-web.svg)](https://badge.fury.io/rb/ronin-web)\n\n* [Source](https://github.com/ronin-rb/ronin-web)\n* [Issues](https://github.com/ronin-rb/ronin-web/issues)\n* [Documentation](https://ronin-rb.dev/docs/ronin-web/frames)\n* [Discord](https://discord.gg/6WAb3PsVX9) |\n  [Mastodon](https://infosec.exchange/@ronin_rb)\n\n## Description\n\nronin-web is a Ruby library that provides common web security commands and\nadditional libraries.\n\nronin-web is part of the [ronin-rb] project, a [Ruby] toolkit for security\nresearch and development.\n\n## Features\n\n* HTML/XML parsing/building (using [Nokogiri][nokogiri]).\n  * Also provides additional extensions to [Nokogiri][nokogiri] using\n    [nokogiri-ext].\n* Supports diffing HTML/XML documents using [nokogiri-diff].\n* Supports random `User-Agent` generation using [ronin-web-user_agents].\n* Provides an easy to use [Sinatra][sinatra] based web server using\n  [ronin-web-server].\n* Provides an easy to use web spider using [ronin-web-spider].\n* Provides a CLI for common web related tasks.\n* Has 98% documentation coverage.\n* Has 89% test coverage.\n\n## Synopsis\n\n```\nUsage: ronin-web [options] [COMMAND [ARGS...]]\n\nOptions:\n    -h, --help                       Print help information\n\nArguments:\n    [COMMAND]                        The command name to run\n    [ARGS ...]                       Additional arguments for the command\n\nCommands:\n    completion\n    diff\n    help\n    html\n    irb\n    new\n    reverse-proxy\n    screenshot\n    server\n    session-cookie\n    spider\n    user-agent\n    vulns\n    wordlist\n    xml\n```\n\nOpen the `ronin-web` Ruby REPL:\n\n```shell\n$ ronin-web irb\n```\n\nDiff two HTML files:\n\n```shell\n$ ronin-web diff index1.html index2.html\n+\n\n+ \u003cdiv\u003ehax\u003c/div\u003e\n```\n\nDiff two URLs:\n\n```shell\n$ ronin-web diff http://example.com/index.html http://example.com/index2.html\n```\n\nPerform an XPath query on an HTML file:\n\n```shell\n$ ronin-web html --xpath //meta index.html\n\u003cmeta charset=\"utf-8\"\u003e\n\u003cmeta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\"\u003e\n\u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n```\n\nPerform an XPath query on a URL:\n\n```shell\n$ ronin-web html --xpath //meta https://example.com/\n\u003cmeta charset=\"utf-8\"\u003e\n\u003cmeta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\"\u003e\n\u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n```\n\nDump all links from a web page:\n\n```shell\n$ ronin-web html --links https://www.google.com/\nhttps://www.google.com/imghp?hl=en\u0026tab=wi\nhttps://maps.google.com/maps?hl=en\u0026tab=wl\nhttps://play.google.com/?hl=en\u0026tab=w8\nhttps://www.youtube.com/?tab=w1\nhttps://news.google.com/?tab=wn\nhttps://mail.google.com/mail/?tab=wm\nhttps://drive.google.com/?tab=wo\nhttps://www.google.com/intl/en/about/products?tab=wh\nhttp://www.google.com/history/optout?hl=en\n/preferences?hl=en\nhttps://accounts.google.com/ServiceLogin?hl=en\u0026passive=true\u0026continue=https://www.google.com/\u0026ec=GAZAAQ\n/advanced_search?hl=en\u0026authuser=0\nhttps://www.google.com/url?q=https://blog.google/products/search/google-search-new-fact-checking-misinformation/\u0026source=hpp\u0026id=19034203\u0026ct=3\u0026usg=AOvVaw3UxG35a-5UX1Rl8M_VwPbd\u0026sa=X\u0026ved=0ahUKEwjM4Iq--JD-AhVtGTQIHXMBBaYQ8IcBCAU\n/intl/en/ads/\n/services/\n/intl/en/about.html\n/intl/en/policies/privacy/\n/intl/en/policies/terms/\n```\n\nSpiders a host and print all visited URLs:\n\n```shell\n$ ronin-web spider --host www.ruby-lang.org\nhttp://www.ruby-lang.org/\nhttp://www.ruby-lang.org/en/\nhttp://www.ruby-lang.org/en/downloads/\nhttp://www.ruby-lang.org/en/documentation/\nhttp://www.ruby-lang.org/en/libraries/\nhttp://www.ruby-lang.org/en/community/\nhttps://www.ruby-lang.org/en/news/\nhttps://www.ruby-lang.org/en/security/\nhttps://www.ruby-lang.org/en/about/\n...\n```\n\nSpiders the domain and sub-domains and print every visited URL:\n\n```shell\n$ ronin-web spider --domain ruby-lang.org\nhttp://ruby-lang.org/\nhttps://www.ruby-lang.org/\nhttps://www.ruby-lang.org/en/\nhttps://www.ruby-lang.org/en/downloads/\nhttps://www.ruby-lang.org/en/documentation/\nhttps://www.ruby-lang.org/en/libraries/\nhttps://www.ruby-lang.org/en/community/\nhttps://www.ruby-lang.org/en/news/\nhttps://www.ruby-lang.org/en/security/\nhttps://www.ruby-lang.org/en/about/\n...\n```\n\nSpiders a specific web-site and print every visited URL:\n\n```shell\n$ ronin-web spider --site https://www.ruby-lang.org/\nhttps://www.ruby-lang.org/\nhttps://www.ruby-lang.org/en/\nhttps://www.ruby-lang.org/en/downloads/\nhttps://www.ruby-lang.org/en/documentation/\nhttps://www.ruby-lang.org/en/libraries/\nhttps://www.ruby-lang.org/en/community/\nhttps://www.ruby-lang.org/en/news/\nhttps://www.ruby-lang.org/en/security/\nhttps://www.ruby-lang.org/en/about/\n...\n```\n\nSpider a host and print the response statuses:\n\n```shell\n200 http://www.ruby-lang.org/\n200 http://www.ruby-lang.org/en/\n200 http://www.ruby-lang.org/en/downloads/\n200 http://www.ruby-lang.org/en/documentation/\n200 http://www.ruby-lang.org/en/libraries/\n200 http://www.ruby-lang.org/en/community/\n200 http://www.ruby-lang.org/en/news/\n200 http://www.ruby-lang.org/en/security/\n200 http://www.ruby-lang.org/en/about/\n...\n```\n\nSpider a host and print the response status and headers:\n\n```shell\nronin-web spider --print-headers --host www.ruby-lang.org\n200 http://www.ruby-lang.org/\n    Connection: close\n    Content-Length: 887\n    Server: Cowboy\n    Strict-Transport-Security: max-age=31536000\n    Content-Type: text/html\n    Etag: W/\"496ac7fab29a6094e490da28025c5857\"\n    X-Frame-Options: SAMEORIGIN\n    Via: 1.1 vegur, 1.1 varnish\n    Accept-Ranges: bytes\n    Date: Tue, 04 Apr 2023 19:42:51 GMT\n    Age: 155\n    X-Served-By: cache-pdx12330-PDX\n    X-Cache: HIT\n    X-Cache-Hits: 1\n    X-Timer: S1680637372.808609,VS0,VE1\n    Vary: Accept-Encoding\n...\n```\n\nStart a debug web server on http://localhost:8000/:\n\n```shell\n$ ronin-web server\n[2023-04-04 12:26:59] INFO  WEBrick 1.7.0\n[2023-04-04 12:26:59] INFO  ruby 3.1.3 (2022-11-24) [x86_64-linux]\n== Sinatra (v3.0.4) has taken the stage on 8000 for development with backup from WEBrick\n[2023-04-04 12:26:59] INFO  WEBrick::HTTPServer#start: pid=8966 port=8000\n```\n\nStart a debug web server on a different address and port:\n\n```shell\n$ ronin-web server --host 0.0.0.0 --port 1337\n```\n\nHost the files in a directory on http://localhost:8000/:\n\n```shell\n$ ronin-web server --root .\n```\n\nMount a specific file at a specific HTTP path:\n\n```shell\n$ ronin-web server --dir /dir/index.html:./index.html\n```\n\nMount a specific directory at a specific HTTP path:\n\n```shell\n$ ronin-web server --dir /dir:.\n```\n\nAdd a redirect to the web server:\n\n```shell\n$ ronin-web server --redirect /redirect:https://example.com/\n```\n\nStart a HTTP reverse proxy that rewrites HTTP responses on http://localhost:8080:\n\n```shell\n$ ronin-web reverse-proxy --rewrite-response Example:Hax\n```\n\nTest the reverse proxy:\n\n```shell\n$ curl -H \"Host: example.com\" http://localhost:8080/\n```\n\nGenerate a new Ruby script for parsing HTML/XML:\n\n```shell\n$ ronin-web new nokogiri parse.rb\n\terb\tnokogiri.rb.erb\tparse.rb\n\tchmod\tparse.rb\n```\n\nGenerate a new web spider script:\n\n```shell\n$ ronin-web new spider --host=www.example.com spider.rb\n\terb\tspider.rb.erb\tspider.rb\n\tchmod\tspider.rb\n```\n\nGenerate a new web server script:\n\n```shell\n$ ronin-web new server server.rb\n\terb\tserver.rb.erb\tserver.rb\n\tchmod\tserver.rb\n```\n\nGenerate a new web app:\n\n```shell\n$ ronin-web new app myapp\n\tmkdir\tmyapp\n\tmkdir\tmyapp/lib\n\tmkdir\tmyapp/views\n\tmkdir\tmyapp/public\n\terb\t.ruby-version.erb\tmyapp/.ruby-version\n\tcp\tGemfile\tmyapp\n\terb\tapp.rb.erb\tmyapp/app.rb\n\tcp\tconfig.ru\tmyapp\n```\n\nOpen the Ronin Web Ruby REPL:\n\n```\n$ ronin-web irb\n                                                                   , Jµ     ▓▓█▓\n                                                  J▌      ▐▓██▌ ████ ██    ▐███D\n                                      ╓▄▓▓█████▌  ██µ     ████ ▄███ÖJ██▌   ███▌\n        ,╓µ▄▄▄▄▄▄▄▄µ;,            ,▄▓██████████  ▐███    ▐███▀ ███▌ ████µ ▄███\n¬∞MÆ▓███████████████████████▓M  ▄██████▀▀╙████▌  ████▌   ████ ▄███ J█████ ███▌\n           `█████▀▀▀▀▀███████  -████▀└    ████  ▐█████n ▄███O ███▌ ██████████\n           ▓████L       ████▀  ▓████     ▓███Ö  ███████ ███▌ ▓███ ▐█████████▀\n          ▄████▀  ,╓▄▄▄█████  J████Ü    ,███▌  ▄███████████ J███▀ ████ █████\n         J█████████████████─  ████▌     ████   ████`██████▌ ████ ▐███Ü ▐███Ü\n         ███████████▀▀▀╙└    ▐████     J███▌  ▓███▌ ²█████ J███Ü ███▌   ▀█▌\n        ▓██████████▌         ████▌     ████  ;████   ▀███▀ ███▌ J▀▀▀-    █\n       ▄█████▀ ▀█████µ      ▐████  ,▄▓████▀  ████▀    ███ J███           `\n      J█████-    ╙▀███▄     ████████████▀╙  J█▀▀▀      █U  ▀█▌\n      ████▀         ▀███   ▄████████▀▀                 ╨    █\n     ▓██▀             ²▀█▄ █▀▀▀╙└\n    ▄██╜                 ╙W\n   J█▀\n   ▌└\n  ┘\n\nirb(ronin-web)\u003e\n```\n\n## Examples\n\n### HTML\n\nParse an HTML string:\n\n```ruby\ndoc = html_parse(\"\u003chtml\u003e\\n  \u003cbody\u003e\\n    \u003cp\u003eHello world\u003c/p\u003e\\n  \u003c/body\u003e\\n\u003c/html\u003e\\n\")\n# =\u003e\n# #(Document:0x6ab8 {\n#   name = \"document\",\n#   children = [\n#     #(DTD:0x6be4 { name = \"html\" }),\n#     #(Element:0x6cd4 {\n#       name = \"html\",\n#       children = [\n#         #(Text \"\\n  \"),\n#         #(Element:0x6e64 {\n#           name = \"body\",\n#           children = [\n#             #(Text \"\\n    \"),\n#             #(Element:0x6ff4 { name = \"p\", children = [ #(Text \"Hello world\")] }),\n#             #(Text \"\\n  \")]\n#           }),\n#         #(Text \"\\n\")]\n#       })]\n#   })\n```\n\nParse a HTML file:\n\n```ruby\ndoc = html_open(\"index.html\")\n# =\u003e #\u003cNokogiri::HTML::Document:...\u003e\n```\n\nSearching an HTML document using [XPath] or CSS-path:\n\n```ruby\nnodes = doc.search('//div/p')\nnodes = doc.search('div p.class')\n# =\u003e [#\u003cNokogiri::HTML::Element:...\u003e, ...]\n\nnode = doc.at('#id')\n# =\u003e #\u003cNokogiri::HTML::Element:...\u003e\n```\n\nBuild a HTML document:\n\n```ruby\ndoc = html_build do\n  html {\n    head {\n      script(type: 'text/javascript', src: 'redirect.js')\n    }\n  }\nend\n\nputs doc.to_html\n# \u003c!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"\u003e\n# \u003chtml\u003e\u003chead\u003e\u003cscript src=\"redirect.js\" type=\"text/javascript\"\u003e\u003c/script\u003e\u003c/head\u003e\u003c/html\u003e\n```\n\n### XML\n\nParse an XML response body:\n\n```ruby\nxml_parse(\"\u003c?xml version=\\\"1.0\\\"?\u003e\\n\u003cusers\u003e\\n  \u003cuser\u003e\\n    \u003cname\u003eadmin\u003c/name\u003e\\n    \u003cpassword\u003e0mni\u003c/password\u003e\\n  \u003cuser\u003e\\n\u003c/users\u003e\\n\")\n# =\u003e\n# #(Document:0xdebc {\n#   name = \"document\",\n#   children = [\n#     #(Element:0xdfe8 {\n#       name = \"users\",\n#       children = [\n#         #(Text \"\\n  \"),\n#         #(Element:0xe178 {\n#           name = \"user\",\n#           children = [\n#             #(Text \"\\n    \"),\n#             #(Element:0xe308 { name = \"name\", children = [ #(Text \"admin\")] }),\n#             #(Text \"\\n    \"),\n#             #(Element:0xe538 { name = \"password\", children = [ #(Text \"0mni\")] }),\n#             #(Text \"\\n  \"),\n#             #(Element:0xe768 { name = \"user\", children = [ #(Text \"\\n\")] }),\n#             #(Text \"\\n\")]\n#           })]\n#       })]\n#   })\n```\n\nParse a XML file:\n\n```ruby\ndoc = html_open(\"data.xml\")\n# =\u003e #\u003cNokogiri:XML:::Document:...\u003e\n```\n\nSearching an XML document using [XPath]:\n\n```ruby\nusers = doc.search('//user')\n# =\u003e [#\u003cNokogiri::XML::Element:...\u003e, ...]\n\nadmin = doc.at('//user[@name=\"admin\"]')\n# =\u003e #\u003cNokogiri::XML::Element:...\u003e\n```\n\nBuild a XML document:\n\n```ruby\ndoc = xml_build do\n  playlist {\n    mp3 {\n      file { text('02 THE WAIT.mp3') }\n      artist { text('Evil Nine') }\n      track { text('The Wait feat David Autokratz') }\n      duration { text('1000000000') }\n    }\n  }\nend\n\nputs doc.to_xml\n# \u003c?xml version=\"1.0\"?\u003e\n# \u003cplaylist\u003e\n#   \u003cmp3\u003e\n#     \u003cfile\u003e02 THE WAIT.mp3\u003c/file\u003e\n#     \u003cartist\u003eEvil Nine\u003c/artist\u003e\n#     \u003ctrack\u003eThe Wait feat David Autokratz\u003c/track\u003e\n#     \u003cduration\u003e1000000000\u003c/duration\u003e\n#   \u003c/mp3\u003e\n# \u003c/playlist\u003e\n```\n\n### Web Requests\n\nGets a URL and follows any redirects:\n\n```ruby\nget 'https://example.com/'\n# =\u003e #\u003cNet::HTTPResponse:...\u003e\n```\n\nGets a URL and parses the HTML response:\n\n```ruby\nget_html 'https://example.com/'\n# =\u003e #\u003cNokogiri::HTML::Document:...\u003e\n```\n\nGets a URL and parses the XML response:\n\n```ruby\nget_xml 'https://example.com/sitemap.xml'\n# =\u003e #\u003cNokogiri::XML::Document:...\u003e\n```\n\nGets a URL and parses the JSON response:\n\n```ruby\nget_json 'https://example.com/api/endpoint.json'\n# =\u003e {...}\n```\n\nPOSTs to a URL and follows any redirects:\n\n```ruby\npost 'https://example.com/form', form_data: {'foo' =\u003e 'bar'}\n# =\u003e #\u003cNet::HTTPResponse:...\u003e\n```\n\nPOSTs to a URL and parses the HTML response:\n\n```ruby\npost_html 'https://example.com/form', form_data: {'foo' =\u003e 'bar'}\n# =\u003e #\u003cNokogiri::HTML::Document:...\u003e\n```\n\nPOSTs to a URL and parses the XML response:\n\n```ruby\npost_xml 'https://example.com/form', form_data: {'foo' =\u003e 'bar'}\n# =\u003e #\u003cNokogiri::XML::Document:...\u003e\n```\n\nPOSTs to a URL and parses the JSON response:\n\n```ruby\npost_json 'https://example.com/api/endpoint.json', json: {foo: 'bar'}\n# =\u003e {...}\n```\n\n### User Agents\n\nGet a random `User-Agent` string:\n\n```ruby\nuser_agent = UserAgents.random\n# =\u003e \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.230 Safari/537.36\"\n```\n\nFor more examples, see [ronin-web-user_agents][ronin-web-user_agents-examples].\n\n[ronin-web-user_agents-examples]: https://github.com/ronin-rb/ronin-web-user_agents#examples\n\n### Session Cookie\n\nParse a Django JSON session cookie:\n\n```ruby\nSessionCookie.parse('sessionid=eyJmb28iOiJiYXIifQ:1pQcTx:UufiSnuPIjNs7zOAJS0UpqnyvRt7KET7BVes0I8LYbA')\n# =\u003e\n# #\u003cRonin::Web::SessionCookie::Django:0x00007f29bb9c6b70\n#  @hmac=\n#   \"R\\xE7\\xE2J{\\x8F\\\"3l\\xEF3\\x80%-\\x14\\xA6\\xA9\\xF2\\xBD\\e{(D\\xFB\\x05W\\xAC\\xD0\\x8F\\va\\xB0\",\n#  @params={\"foo\"=\u003e\"bar\"},\n#  @salt=1676070425\u003e\n```\n\nFor more examples, see [ronin-web-session_cookie][ronin-web-session_cookie-examples].\n\n[ronin-web-session_cookie-examples]: https://github.com/ronin-rb/ronin-web-session_cookie#examples\n\n### Spider\n\nSpider a website and print out visited URLs:\n\n```ruby\nSpider.site('http://www.rubyinside.com/') do |spider|\n  spider.every_url { |url| puts url }\nend\n```\n\nFor more examples, see [ronin-web-spider][ronin-web-spider-examples].\n\n[ronin-web-spider-examples]: https://github.com/ronin-rb/ronin-web-spider#examples\n\n### Browser\n\nOpen a visible web browser and intercept all requests:\n\n```ruby\nbrowser = Ronin::Web::Browser.new(visible: true)\nbrowser.every_request do |request|\n  puts \"\u003e #{request.method} #{request.url}\"\nend\n\nbrowser.go_to(\"https://twitter.com/login\")\n```\n\nFor more examples, see [ronin-web-browser][ronin-web-browser-examples].\n\n[ronin-web-browser-examples]: https://github.com/ronin-rb/ronin-web-browser#examples\n\n## Requirements\n\n* [Ruby] \u003e= 3.0.0\n* [nokogiri] ~\u003e 1.4\n* [nokogiri-diff] ~\u003e 0.2\n* [robots] ~\u003e 0.10\n* [open_namespace] ~\u003e 0.4\n* [wordlist] ~\u003e 1.0, \u003e= 1.0.1\n* [ronin-support] ~\u003e 1.1\n* [ronin-support-web] ~\u003e 0.1\n* [ronin-web-browser] ~\u003e 0.1\n* [ronin-web-server] ~\u003e 0.1\n* [ronin-web-spider] ~\u003e 0.2\n* [ronin-web-user_agents] ~\u003e 0.1\n* [ronin-web-session_cookie] ~\u003e 0.1\n* [ronin-core] ~\u003e 0.2\n* [ronin-vulns] ~\u003e 0.2\n\n## Install\n\n```shell\n$ gem install ronin-web\n```\n\n## Development\n\n1. [Fork It!](https://github.com/ronin-rb/ronin-web/fork)\n2. Clone It!\n3. `cd ronin-web`\n4. `./scripts/setup`\n5. `git checkout -b my_feature`\n6. Code It!\n7. `bundle exec rake spec`\n8. `git push origin my_feature`\n\n## License\n\nronin-web - A collection of useful web helper methods and commands.\n\nCopyright (c) 2006-2025 Hal Brodigan (postmodern.mod3 at gmail.com)\n\nronin-web is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nronin-web is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with ronin-web.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n\n[ronin-rb]: https://ronin-rb.dev\n[Ruby]: https://www.ruby-lang.org\n\n[nokogiri]: https://nokogiri.org/\n[nokogiri-diff]: https://github.com/postmodern/nokogiri-diff#readme\n[open_namespace]: https://github.com/postmodern/open_namespace#readme\n[ronin-support]: https://github.com/ronin-rb/ronin-support#readme\n[ronin-support-web]: https://github.com/ronin-rb/ronin-support-web#readme\n[ronin-core]: https://github.com/ronin-rb/ronin-core#readme\n[ronin-web-browser]: https://github.com/ronin-rb/ronin-web-browser#readme\n[ronin-web-server]: https://github.com/ronin-rb/ronin-web-server#readme\n[ronin-web-spider]: https://github.com/ronin-rb/ronin-web-spider#readme\n[ronin-web-user_agents]: https://github.com/ronin-rb/ronin-web-user_agents#readme\n[ronin]: https://github.com/ronin-rb/ronin#readme\n[sinatra]: https://sinatrarb.com/\n\n[XPath]: https://developer.mozilla.org/en-US/docs/Web/XPath\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronin-rb%2Fronin-web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fronin-rb%2Fronin-web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronin-rb%2Fronin-web/lists"}