<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chetan</title>
    <description>The latest articles on DEV Community by Chetan (@chetanam).</description>
    <link>https://dev.to/chetanam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F574513%2F00169428-1345-49d4-bfcd-26db432fd3dc.jpg</url>
      <title>DEV Community: Chetan</title>
      <link>https://dev.to/chetanam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chetanam"/>
    <language>en</language>
    <item>
      <title>🚀 Introducing ✨ Bose Framework - The Swiss Army Knife for Bot Developers 🤖</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Wed, 24 May 2023 16:40:50 +0000</pubDate>
      <link>https://dev.to/chetanam/introducing-bose-framework-the-swiss-army-knife-for-bot-developers-10k9</link>
      <guid>https://dev.to/chetanam/introducing-bose-framework-the-swiss-army-knife-for-bot-developers-10k9</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ffeatured-0bacb14445a1b4cf367c10cd01454000.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ffeatured-0bacb14445a1b4cf367c10cd01454000.jpg" alt="Featured"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bot Development is Tough. &lt;/p&gt;

&lt;p&gt;Bot Detectors like Cloudflare are ready to defend websites from our Bots. Configuring Selenium with ChromeOptions to specify the driver path, profile, user agent, and window size is Cumbersome and a nightmare in windows. Debugging Bot Crashes via logs is hard. How do you solve these pain points without sacrificing speed and handy development?&lt;/p&gt;

&lt;p&gt;Enter Bose. Bose is the first bot development framework in the Developer Community that is specifically designed to provide the best developer experience for bot developers. Powered by Selenium, it offers a range of features and functionalities to simplify the process of bot development. As far as our knowledge goes, Bose is the first bot development framework of its kind in the town.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Clone Starter Template&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/omkarcloud/bose-starter my-bose-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then change into that directory, install dependencies, and start the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd my-bose-project
python -m pip install -r requirements.txt
python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first run will take some time as it downloads the chrome driver executable, subsequent runs will be fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core features
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Adds Powerful Methods to make working with Selenium a lot easier.&lt;/li&gt;
&lt;li&gt;Follows best practices to avoid Bot Detection by Cloudflare and PerimeterX.&lt;/li&gt;
&lt;li&gt;Saves the HTML, Screenshot, and the run details for each task run to enable easy debugging.&lt;/li&gt;
&lt;li&gt;Utility components to write scraped data as JSON, CSV, and Excel files.&lt;/li&gt;
&lt;li&gt;Automatically downloads and initializes the correct Chrome driver.&lt;/li&gt;
&lt;li&gt;Fast and Developer friendly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Say you want to start scraping a website. If you were using bare Selenium, you would have to handle the imperative tasks of opening and closing the driver like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;

&lt;span class="n"&gt;driver_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;path/to/chromedriver&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executable_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;driver_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, with Bose Framework, you can take a declarative and structured approach. You only need to write the following code, and Bose driver will take care of creating the driver, passing it to the &lt;strong&gt;&lt;code&gt;run&lt;/code&gt;&lt;/strong&gt; method of the Task, and closing the driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseTask&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;In bare Selenium, if you want to configure options such as the profile, user agent, or window size, it requires writing a lot of code, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium.webdriver.chrome.options&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Options&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;

&lt;span class="n"&gt;driver_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;path/to/chromedriver.exe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;profile_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--user-data-dir=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;profile_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;user_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.37&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--user-agent=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;window_width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;
&lt;span class="n"&gt;window_height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;720&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--window-size=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;window_width&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;window_height&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executable_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;driver_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand, Bose Framework simplifies these complexities by encapsulating the browser configuration within the &lt;strong&gt;&lt;code&gt;BrowserConfig&lt;/code&gt;&lt;/strong&gt; property of the Task, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BrowserConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WindowSize&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseTask&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;browser_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BrowserConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UserAgent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_agent_106&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;WindowSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window_size_1280_720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exception handling
&lt;/h2&gt;

&lt;p&gt;Exceptions are common when using Selenium. In bare Selenium, if an exception occurs, the driver automatically closes, leaving you with only logs to debug.&lt;/p&gt;

&lt;p&gt;In Bose, when an exception occurs in a scraping task, the browser remains open instead of immediately closing. This allows you to see the live browser state at the moment the exception occurred, which greatly helps in debugging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ferror-prompt-83de79e560f129197afb9f831d388383.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ferror-prompt-83de79e560f129197afb9f831d388383.png" alt="error prompt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging
&lt;/h2&gt;

&lt;p&gt;Web scraping can often be fraught with errors, such as incorrect selectors or pages that fail to load. When debugging with raw Selenium, you may have to sift through logs to identify the issue. Fortunately, Bose makes it simple for you to debug by storing information about each run.&lt;/p&gt;

&lt;p&gt;After each run a directory is created in tasks which contains three files, which are listed below:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;task_info.json&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;It contains information about the task run such as duration for which the task run, the ip details of task, the user agent, window_size and profile which used to execute the task. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ftask-info-1ad8d89552138e2edc900434144dfbe0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ftask-info-1ad8d89552138e2edc900434144dfbe0.png" alt="task info"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;final.png&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the screenshot captured before driver was closed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ffinal-d2ca24d2717d17576eb8233ad0cd2b10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ffinal-d2ca24d2717d17576eb8233ad0cd2b10.png" alt="final"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;page.html&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the html source captured before driver was closed. Very useful to know in case your selectors failed to select elements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Fpage-cffce10976b4bf201b49a479c2340075.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Fpage-cffce10976b4bf201b49a479c2340075.png" alt="Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;error.log&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In case your task crashed due to exception we also store error.log which contains the error due to which the task crashed. This is very helful in debugging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ferror-log-9ebb09dca133b2d7df1ae6cfc67df909.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fbose%2Fassets%2Fimages%2Ferror-log-9ebb09dca133b2d7df1ae6cfc67df909.png" alt="error log"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Outputting Data
&lt;/h2&gt;

&lt;p&gt;After performing web scraping, we need to store the data in either JSON or CSV format. Typically, this process involves writing a significant amount of imperative code which looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;write_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;write_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fieldnames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# get the fieldnames from the first dictionary
&lt;/span&gt;        &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DictWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fieldnames&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fieldnames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeheader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# write the header row
&lt;/span&gt;        &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# write each row of data
&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u201c&lt;/span&gt;&lt;span class="s"&gt;The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.&lt;/span&gt;&lt;span class="se"&gt;\u201d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Albert Einstein&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u201c&lt;/span&gt;&lt;span class="s"&gt;It is our choices, Harry, that show what we truly are, far more than our abilities.&lt;/span&gt;&lt;span class="se"&gt;\u201d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;J.K. Rowling&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nf"&gt;write_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;write_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bose simplifies these complexities by encapsulating them in Output Module for reading and writing Data. &lt;/p&gt;

&lt;p&gt;To use Output Method, call the &lt;code&gt;write&lt;/code&gt; method for the type of file you want to save.&lt;/p&gt;

&lt;p&gt;All data will be saved in the &lt;code&gt;output/&lt;/code&gt; folder:&lt;/p&gt;

&lt;p&gt;See following Code for Reference&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u201c&lt;/span&gt;&lt;span class="s"&gt;The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.&lt;/span&gt;&lt;span class="se"&gt;\u201d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Albert Einstein&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u201c&lt;/span&gt;&lt;span class="s"&gt;It is our choices, Harry, that show what we truly are, far more than our abilities.&lt;/span&gt;&lt;span class="se"&gt;\u201d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;J.K. Rowling&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Undetected Driver
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ultrafunkamsterdam" rel="noopener noreferrer"&gt;Ultrafunkamsterdam&lt;/a&gt; created a &lt;a href="https://github.com/ultrafunkamsterdam/undetected-chromedriver" rel="noopener noreferrer"&gt;ChromeDriver&lt;/a&gt; that has excellent support for bypassing &lt;strong&gt;all major bot detection systems&lt;/strong&gt; such as Distil, Datadome, Cloudflare, and others. &lt;/p&gt;

&lt;p&gt;Bose recognized the importance of bypassing bot detections and provides in built support for &lt;a href="https://github.com/ultrafunkamsterdam" rel="noopener noreferrer"&gt;Ultrafunkamsterdam’s&lt;/a&gt; &lt;a href="https://github.com/ultrafunkamsterdam/undetected-chromedriver" rel="noopener noreferrer"&gt;Undetected Driver&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Using the Undetected Driver in Bose Framework is as simple as passing the &lt;strong&gt;&lt;code&gt;use_undetected_driver&lt;/code&gt;&lt;/strong&gt; option to the &lt;strong&gt;&lt;code&gt;BrowserConfig&lt;/code&gt;&lt;/strong&gt;, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BrowserConfig&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseTask&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;browser_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BrowserConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;use_undetected_driver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  LocalStorage
&lt;/h2&gt;

&lt;p&gt;Just like how modern browsers have a local storage module, Bose has also incorporated the same concept in its framework.&lt;/p&gt;

&lt;p&gt;You can import the LocalStorage object from Bose to persist data across browser runs, which is extremely useful when scraping large amounts of data.&lt;/p&gt;

&lt;p&gt;The data is stored in a file named &lt;code&gt;local_storage.json&lt;/code&gt; in the root directory of your project. Here's how you can use it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LocalStorage&lt;/span&gt;

&lt;span class="n"&gt;LocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LocalStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Boss Driver
&lt;/h2&gt;

&lt;p&gt;The driver you receive in the &lt;strong&gt;&lt;code&gt;run&lt;/code&gt;&lt;/strong&gt; method of the Task is an extended version of Selenium that adds powerful methods to make working with Selenium much easier. Some of the popular methods added to the Selenium driver by Bose Framework are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;METHOD&lt;/th&gt;
&lt;th&gt;DESCRIPTION&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;get_by_current_page_referrer(link, wait=None)&lt;/td&gt;
&lt;td&gt;simulate a visit that appears as if you arrived at the page by clicking a link. This approach creates a more natural and less detectable browsing behavior.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;js_click(element)&lt;/td&gt;
&lt;td&gt;enables you to click on an element using JavaScript, bypassing any interceptions(ElementClickInterceptedException) from pop-ups or alerts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;get_cookies_and_local_storage_dict()&lt;/td&gt;
&lt;td&gt;returns a dictionary containing "cookies" and "local_storage”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;add_cookies_and_local_storage_dict(self, site_data)&lt;/td&gt;
&lt;td&gt;adds both cookies and local storage data to the current web site&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;organic_get(link, wait=None)&lt;/td&gt;
&lt;td&gt;visits google and then visits the “link” making it less detectable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;local_storage&lt;/td&gt;
&lt;td&gt;returns an instance of the LocalStorage module for interacting with the browser's local storage in an easy to use manner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;save_screenshot(filename=None)&lt;/td&gt;
&lt;td&gt;save a screenshot of the current web page to a file in tasks/ directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;short_random_sleep() and long_random_sleep():&lt;/td&gt;
&lt;td&gt;sleep for a random amount of time, either between 2 and 4 seconds (short) or between 6 and 9 seconds (long)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;get_element_or_* [eg: get_element_or_none, get_element_or_none_by_selector, get_element_by_id, get_element_or_none_by_text_contains,]&lt;/td&gt;
&lt;td&gt;find web elements on the page based on different criteria. They return the web element if it exists, or None if it doesn't.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;is_in_page(target, wait=None, raise_exception=False)&lt;/td&gt;
&lt;td&gt;checks if the browser is in the specified page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Bose is an excellent framework that simplifies the boring parts of Selenium and web scraping.&lt;/p&gt;

&lt;p&gt;Wish you best of Luck and Happy Bot Development with Bose Framework!&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;p&gt;To learn about Bose Bot Development Framework in detail, read the Bose docs at &lt;a href="https://www.omkar.cloud/bose/" rel="noopener noreferrer"&gt;https://www.omkar.cloud/bose/&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  If Bose Framework helped in Bot Development, please take a moment to &lt;a href="https://github.com/omkarcloud/bose" rel="noopener noreferrer"&gt;star the repository&lt;/a&gt;. Your act of starring will help developers in discovering our Repository and contribute towards helping fellow developers in Bot Development. Dhanyawad 🙏! Vande Mataram!
&lt;/h3&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>selenium</category>
      <category>bot</category>
    </item>
    <item>
      <title>Youtube Collabration?</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Tue, 23 May 2023 08:40:43 +0000</pubDate>
      <link>https://dev.to/chetanam/youtube-collabration-fki</link>
      <guid>https://dev.to/chetanam/youtube-collabration-fki</guid>
      <description>&lt;p&gt;Are you interested in youtube Collaboration?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>🌈Omkar DevTools: A Swiss Army knife for Ninja Developers🚀</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Mon, 22 May 2023 18:27:55 +0000</pubDate>
      <link>https://dev.to/chetanam/omkar-devtools-a-swiss-army-knife-for-developers-40na</link>
      <guid>https://dev.to/chetanam/omkar-devtools-a-swiss-army-knife-for-developers-40na</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZELwBMHl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xm1iegnb4x9rc4ap7es.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZELwBMHl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xm1iegnb4x9rc4ap7es.jpg" alt="Image description" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe you just know &lt;a href="https://github.com/microsoft/PowerToys#about"&gt;PowerToys&lt;/a&gt;. It's a set of utilities for power users to tune and streamline their Windows experience for greater productivity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.omkar.cloud/devtools/"&gt;DevTools&lt;/a&gt; is more or less the same thing, but for developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Before Omkar DevTools, you must be using a lot of online tools on different sites.&lt;/p&gt;

&lt;p&gt;Every time you need to remember the url of the tool, or open Notion to find my notes about the tools and I wasted a lot of times.&lt;/p&gt;

&lt;p&gt;Not any more with Omkar DevTools you can access a number of tools in one Dashboard. &lt;/p&gt;

&lt;p&gt;At the moment there a lot of tools available inside Omkar DevTools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON to YAML&lt;/li&gt;
&lt;li&gt;YAML to JSON&lt;/li&gt;
&lt;li&gt;Base64 Encoder&lt;/li&gt;
&lt;li&gt;UUID Generator&lt;/li&gt;
&lt;li&gt;Secret Key Generator&lt;/li&gt;
&lt;li&gt;Hash Generator&lt;/li&gt;
&lt;li&gt;Lorem Ipsum Generator&lt;/li&gt;
&lt;li&gt;JWT Decoder&lt;/li&gt;
&lt;li&gt;Number Base Converter&lt;/li&gt;
&lt;li&gt;HTML Encoder and Decoder&lt;/li&gt;
&lt;li&gt;URL Encoder and Decoder&lt;/li&gt;
&lt;li&gt;GZIP Compressor/Decompressor&lt;/li&gt;
&lt;li&gt;Color Blindness Simulator&lt;/li&gt;
&lt;li&gt;File Hash Generator&lt;/li&gt;
&lt;li&gt;Base64 File Encoder&lt;/li&gt;
&lt;li&gt;Case Convertor&lt;/li&gt;
&lt;li&gt;Text Counter&lt;/li&gt;
&lt;li&gt;Json Duplicate Remover&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to use DevTools
&lt;/h2&gt;

&lt;p&gt;You can easily use Omkar Tools by visiting &lt;a href="https://www.omkar.cloud/devtools/"&gt;https://www.omkar.cloud/devtools/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xiPokBf5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fs7skbylaqg8fk793ys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xiPokBf5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fs7skbylaqg8fk793ys.png" alt="Dashboard" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Try Omkar Devtools at &lt;a href="https://www.omkar.cloud/devtools/"&gt;https://www.omkar.cloud/devtools/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am curious to hear your thoughts in the Comments about Omkar DevTools.&lt;/p&gt;

&lt;p&gt;Dhanyawad 🙏&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🌈 A One Person Startup Tech Stack for Ninja Developers - Next.js, Django, Kubernetes, and GCP 🚀</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Mon, 22 May 2023 16:17:30 +0000</pubDate>
      <link>https://dev.to/chetanam/a-one-person-startup-tech-stack-nextjs-django-kubernetes-and-gcp-k62</link>
      <guid>https://dev.to/chetanam/a-one-person-startup-tech-stack-nextjs-django-kubernetes-and-gcp-k62</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P2KUkH56--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnnfxk6vc1eadfaj8e6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P2KUkH56--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnnfxk6vc1eadfaj8e6d.png" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, I will share the tech stack I used to build my startup, Omkar. My startup consists of several components, including Frontend, Backend, Blog. &lt;/p&gt;

&lt;p&gt;By learning about my tech stack, you can gain insights that will assist you in selecting the tech stack for your startup.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Application Omkar Cloud
&lt;/h2&gt;

&lt;p&gt;My Application Omkar Cloud is a full stack website with a Blog, developed using technologies like Django, Next.js, and Kubernetes&lt;/p&gt;

&lt;p&gt;It is a People Search Engine that you can use, for example, to find people working in a company or CEOs of companies in an industry. Think of it as an advanced version of LinkedIn Search.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GDYxjjEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/or1mhlt45wcxcozszrpb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GDYxjjEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/or1mhlt45wcxcozszrpb.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack of Omkar Cloud
&lt;/h2&gt;

&lt;p&gt;The Most Important Technologies in my Tech Stack are Kubernetes, GCP, Elastic UI, Next.js, GitHub Actions, and Django. &lt;/p&gt;

&lt;p&gt;Here is a breakdown of my Tech Stack&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend**
&lt;/h3&gt;

&lt;p&gt;For the Frontend I have used Elastic UI, React and Next.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elastic UI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have used many Component Libraries in the past, such as Bootstrap and Material UI. However, based on my experience, I have found the Component Library of Elastic UI to be particularly impressive. Elastic UI is really beautiful Component Library.&lt;/p&gt;

&lt;p&gt;Therefore, I have chosen Elastic UI as my UI framework&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Also, I had learnt two frameworks to create websites which are Svelte and React. &lt;/p&gt;

&lt;p&gt;I wanted to use Svelte as it is much more concise than React. However, since the Elastic UI Library was not available for Svelte, I had no choice but to choose React as the only option available to me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next.js is a framework built on top of React. &lt;/p&gt;

&lt;p&gt;I think of Next.js as a framework for a framework 😂.&lt;/p&gt;

&lt;p&gt;Next.js simplifies the usage of React and provides additional features. Therefore, instead of using the bare create-react-app setup, I opted to use Next.js as it makes working with React much easier&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;p&gt;For the Backend I used Django powered by SQLite Database&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Django&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have learned various backend frameworks such as Express.js and Nest.js, but Django stood out as my favorite. &lt;/p&gt;

&lt;p&gt;When working with Django, I found that I could accomplish tasks with significantly fewer lines of code compared to Nest.js or Express.js. &lt;/p&gt;

&lt;p&gt;Django's conciseness is similar to Sanskrit Language, in Sanskrit you can convey your thoughts in very fewer words compared to English or Hindi Language. &lt;/p&gt;

&lt;p&gt;Hence, I chose Django for its conciseness and simplicity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQLite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the database, I had the option of using either SQLite or PostgreSQL. I opted for SQLite due to several reasons.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most Importantly for me as an Indian is that it is SQLite is cheaper than PostgreSQL since in SQLite there is no need to purchase a separate server.&lt;/li&gt;
&lt;li&gt;It allows developers to start developing faster since PostgreSQL requires spinning up a server, whereas SQLite is file-based&lt;/li&gt;
&lt;li&gt;It is easier to view table contents using SQLite Browser application in SQLite compared to PostgreSQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although, it can be argued that PostgreSQL is more Scalable but for a Start Up, SQLite does the Job Perfectly. Also, in future you can always migrate to PostgreSQL if necessary. &lt;/p&gt;

&lt;h3&gt;
  
  
  Blog
&lt;/h3&gt;

&lt;p&gt;To create the blog for my website, I utilized the tailwind-nextjs-starter-blog developed by Timothy Lin. It is a beautiful blogging platform built on Next.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;p&gt;For deployment, I used Kubernetes, GitHub Actions, and Google Cloud Platform (GCP).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wanted to host the frontend, backend, and blog on a single domain, namely '&lt;strong&gt;&lt;a href="http://www.omkar.cloud/"&gt;www.omkar.cloud&lt;/a&gt;&lt;/strong&gt;' &lt;strong&gt;at different paths&lt;/strong&gt;. Additionally, I needed to store the SQLite database file in storage.&lt;/p&gt;

&lt;p&gt;Kubernetes provided a convenient method for orchestrating these needs. So, I used Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To automate the deployment process, I utilized GitHub Actions. With this setup, I could easily deploy a new version of my application by simply pushing the code to the master branch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GCP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I chose GCP as the platform to run my entire Kubernetes stack. Google products have a reputation for quality, and GCP proved to be reliable and suitable for my needs. It costs me 2900 INR or $35 per month to run my full Stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Tools
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Google Analytics.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used Google Analytics to track my website as It was the analytics software I was most familiar with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;G Suite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For creating a professional email address like &lt;strong&gt;&lt;code&gt;info@omkar.cloud&lt;/code&gt;&lt;/strong&gt;, I utilized G Suite. I opted for G Suite due to my familiarity with the Gmail interface and my resistance to change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Search Console&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;I utilized Google Search Console to monitor the search ranking of my website, omkar.cloud, on Google.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NameCheap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used &lt;strong&gt;NameCheap&lt;/strong&gt; for buying domain name of omkar.cloud. I was satisfied with Name Cheap’s  services. &lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;In short, I used the following technologies in my tech stack for &lt;strong&gt;&lt;a href="http://www.omkar.cloud/"&gt;omkar.cloud&lt;/a&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Frontend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elastic UI&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Next.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Backend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Django&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Blog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tailwind-nextjs-starter-blog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes&lt;/li&gt;
&lt;li&gt;GitHub Actions&lt;/li&gt;
&lt;li&gt;Google Cloud Platform (GCP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other Tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Analytics&lt;/li&gt;
&lt;li&gt;G Suite&lt;/li&gt;
&lt;li&gt;Google Search Console&lt;/li&gt;
&lt;li&gt;NameCheap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, I am very satisfied with the tech stack of &lt;strong&gt;&lt;a href="http://www.omkar.cloud/"&gt;omkar.cloud&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If you are creating a startup and considering the tech stack to use, based on my experience, I can confidently say that if you base your tech stack on mine, you will have a solid technological foundation for your startup. &lt;/p&gt;

&lt;p&gt;I am curious to hear if you have any questions regarding the tech stack, so please feel free to ask in the comments. &lt;/p&gt;

&lt;p&gt;Dhanyawad 🙏&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>startup</category>
      <category>python</category>
    </item>
    <item>
      <title>🔥💥🚀 10 Missing Selenium Methods for Ninja Developers!😱💥🔥</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Mon, 22 May 2023 11:41:12 +0000</pubDate>
      <link>https://dev.to/chetanam/10-missing-selenium-methods-4ic0</link>
      <guid>https://dev.to/chetanam/10-missing-selenium-methods-4ic0</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu92r24g8ww9tlhao100d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu92r24g8ww9tlhao100d.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Based on my experience, I have created multiple utilities to simplify Selenium for bot developers. First, let me describe these utilities to you, and then I will explain how to use them effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods
&lt;/h2&gt;

&lt;p&gt;1) &lt;code&gt;get_by_current_page_referrer(link, wait=None)&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;An alternative to &lt;code&gt;driver.get&lt;/code&gt; is the &lt;code&gt;get_by_current_page_referrer(link, wait=None)&lt;/code&gt; utility. When using &lt;code&gt;driver.get&lt;/code&gt;, the &lt;code&gt;document.referrer&lt;/code&gt; property remains empty, indicating that you directly entered the page URL in the search bar, which can raise suspicion for bot detection systems.&lt;/p&gt;

&lt;p&gt;By employing &lt;code&gt;get_by_current_page_referrer(link, wait=None)&lt;/code&gt;, you can simulate a visit that appears as if you arrived at the page by clicking a link. This approach creates a more natural and less detectable browsing behavior.&lt;/p&gt;

&lt;p&gt;In general, when navigating to an internal page of a website, it is recommended to replace &lt;code&gt;driver.get&lt;/code&gt; with &lt;code&gt;get_by_current_page_referrer&lt;/code&gt;. Additionally, you have the option to specify the amount of time to wait before navigating, using the optional &lt;code&gt;wait&lt;/code&gt; parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_by_current_page_referrer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) &lt;code&gt;js_click(element)&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;While clicking elements with Selenium, elements can be intercepted by pop-ups, alerts, or other elements, leading to the raising of an &lt;strong&gt;&lt;code&gt;ElementClickInterceptedException&lt;/code&gt;&lt;/strong&gt; error.&lt;/p&gt;

&lt;p&gt;To handle such situations, you can utilize the &lt;strong&gt;&lt;code&gt;js_click&lt;/code&gt;&lt;/strong&gt; method. This method enables you to click on an element using JavaScript, bypassing any interceptions from pop-ups or alerts. &lt;/p&gt;

&lt;p&gt;By employing the &lt;strong&gt;&lt;code&gt;js_click&lt;/code&gt;&lt;/strong&gt; method, you can ensure that the click operation is executed smoothly without being intercepted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_element_or_none_by_selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.button&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;js_click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) &lt;code&gt;get_cookies_and_local_storage_dict()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;This method returns a dictionary containing two keys, "cookies" and "local_storage", each of which contains a dictionary of the cookies and local storage. You can use them to persist session by storing them in a JSON file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;site_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_cookies_and_local_storage_dict&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4)  &lt;code&gt;add_cookies_and_local_storage_dict(self, site_data)&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;This method adds both cookies and local storage data to the current web site.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;site_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cookies&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cookie1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cookie2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;local_storage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;John&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_cookies_and_local_storage_dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) &lt;code&gt;organic_get link, wait=None)&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;This method follows a two-step process: it first loads the Google homepage and then navigates to the specified link. This approach closely resembles the way people typically visit websites, resulting in more humane behavior and reduces chances of bot being detected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;organic_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6) &lt;code&gt;local_storage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This property returns an instance of the &lt;code&gt;LocalStorage&lt;/code&gt; class from the &lt;code&gt;bose.drivers.local_storage&lt;/code&gt; module. This class is used for interacting with the browser's local storage in an easy to use manner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;local_storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;local_storage&lt;/span&gt;

&lt;span class="c1"&gt;# Set an item in the Browser's Local Storage
&lt;/span&gt;&lt;span class="n"&gt;local_storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;johndoe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Retrieve an item from the Browser's Local Storage
&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;local_storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7) &lt;code&gt;save_screenshot(filename=None)&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Use this method  to save a screenshot of the current web page to a file in &lt;code&gt;tasks/&lt;/code&gt; directory. The filename of the screenshot is generated based on the current date and time, unless a custom filename is provided.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save_screenshot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8) &lt;code&gt;short_random_sleep()&lt;/code&gt; and &lt;code&gt;long_random_sleep()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;These methods sleep for a random amount of time, either between 2 and 4 seconds (short) or between 6 and 9 seconds (long). You can use them like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;short_random_sleep&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;long_random_sleep&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9) &lt;code&gt;get_element_or_none(xpath, wait=None)&lt;/code&gt;, &lt;code&gt;get_element_or_none_by_selector(selector, wait=None)&lt;/code&gt;, &lt;code&gt;get_element_by_id(id, wait=None)&lt;/code&gt;, &lt;code&gt;get_element_or_none_by_text_contains(text, wait=None)&lt;/code&gt;, &lt;code&gt;get_element_or_none_by_text(text, wait=None)&lt;/code&gt;, &lt;code&gt;get_element_or_none_by_name(selector, wait=None)&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;These methods find web elements on the page based on different criteria. They return the web element if it exists, or &lt;code&gt;None&lt;/code&gt; if it doesn't. You can also pass number of seconds to wait for element to appear. You can use them like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# find an element by xpath
&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_element_or_none&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;//div[@class=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;example&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# find an element by CSS selector
&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_element_or_none_by_selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.example-class&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# find an element by ID
&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_element_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;example-id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# find an element by text
&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_element_or_none_by_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Example text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# find an element by partial text
&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_element_or_none_by_text_contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Example&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# find an element with attribute name = "email"
&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_element_or_none_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;10) &lt;code&gt;is_in_page(target, wait=None, raise_exception=False)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This method checks if the browser is in the specified page. It will keep checking the URL for a specified amount of time (if wait is provided) and return False if the target is not found. If raise_exception is True, it will raise an exception if the page is not found.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;is_in_page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_in_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;raise_exception&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to use these utilities?
&lt;/h2&gt;

&lt;p&gt;The easiest way to use these utilities is to utilize the Bose Framework, which is the first framework designed to simplify Bot Development for Developers. &lt;/p&gt;

&lt;p&gt;Bose Framework automatically incorporates these utility methods into the Selenium Driver. You can learn how to use the Bose Framework by following the tutorial at &lt;strong&gt;&lt;a href="https://www.omkar.cloud/bose/docs/tutorial/" rel="noopener noreferrer"&gt;https://www.omkar.cloud/bose/docs/tutorial/&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🚀 🤖💻🔍 How to scrape g2 using Python, Selenium and Bose Framework 🅶2️⃣🐍🖥️</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Sun, 21 May 2023 15:07:45 +0000</pubDate>
      <link>https://dev.to/chetanam/how-to-scrape-g2-using-python-selenium-and-bose-framework-4h99</link>
      <guid>https://dev.to/chetanam/how-to-scrape-g2-using-python-selenium-and-bose-framework-4h99</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XrXwJVka--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vd2ccxhrfnk9qf72xqq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XrXwJVka--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vd2ccxhrfnk9qf72xqq8.png" alt="g2" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, you will learn how to scrape g2.com using Bose Framework.&lt;/p&gt;

&lt;p&gt;Also, Scraping g2.com is an excellent way to do competitor analysis.&lt;/p&gt;

&lt;p&gt;Bose Framework, is a Selenium based Bot Development Framework that provides a comprehensive set of tools and functionalities specifically aimed at making the Bot Development Process easy for Developers. &lt;/p&gt;

&lt;p&gt;To make it easy to scrape g2.com, I have prepared a script that you can use to scrape g2 effectively. This article will walk you through the steps of utilizing the script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Clone Starter Template
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/omkarcloud/g2-scraper
cd g2-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install dependencies
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;extract_product_links.py&lt;/code&gt; specify your &lt;code&gt;Task.product_url&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run Project
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script will start running and output progress updates to the console. When the scraper is complete, it will generate a JSON file named &lt;code&gt;pending.json&lt;/code&gt; in the &lt;code&gt;output&lt;/code&gt; directory. The JSON file will contain the product links.&lt;/p&gt;

&lt;p&gt;Once the bot is detected by Cloudflare, the script will recognize it and prompt you to press the "Enter" key in the console once you have successfully solved the Cloudflare captcha.&lt;/p&gt;

&lt;p&gt;Additionaly, you don't have to configure the Selenium driver as it will automatically download the appropriate driver based on your Chrome browser version.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;main.py&lt;/code&gt; change &lt;code&gt;task&lt;/code&gt; variable to &lt;code&gt;src.extract_product_links&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Rerun Project
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The products will be extracted and stored in the output/finished.csv and output/finished.json file after scraping.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>tutorial</category>
      <category>webscrapingtools</category>
    </item>
    <item>
      <title>🤔🌐🗺️ How to scrape google maps using Python, Selenium and Bose Framework 🐍🔍🌍</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Sun, 21 May 2023 12:23:48 +0000</pubDate>
      <link>https://dev.to/chetanam/how-to-scrape-google-maps-using-python-selenium-and-bose-framework-20g</link>
      <guid>https://dev.to/chetanam/how-to-scrape-google-maps-using-python-selenium-and-bose-framework-20g</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi65y3g6m9b2z60xcll0o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi65y3g6m9b2z60xcll0o.png" alt="Result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today's digital era, businesses are constantly seeking innovative ways to generate leads and gain a competitive edge. One incredibly powerful tool that has become indispensable for lead generation is Google Maps.&lt;/p&gt;

&lt;p&gt;With its vast database of businesses and geolocation information, scraping Google Maps can provide valuable insights and opportunities for various industries. It allows businesses to extract information such as business names, contact details, addresses, customer reviews, and more. This data can serve as a goldmine for web developers and marketers in their quest for B2B leads.&lt;/p&gt;

&lt;p&gt;To Scrape Google Maps we will use Bose Framework, a Selenium based Bot Development Framework that provides a comprehensive set of tools and functionalities specifically aimed at making the Bot Development Process easy for Developers. &lt;/p&gt;

&lt;p&gt;Let's dive into the fascinating world of lead generation and explore how web developers can leverage the Bose Framework and Google Maps scraping to discover B2B leads.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to scrape google maps
&lt;/h2&gt;

&lt;p&gt;I have written a Python script that allows you to scrape information from Google Maps, including business names, addresses, phone numbers, websites, ratings, and reviews. The script can be configured to search for specific queries and can scrape either the first page of results or all pages of results.&lt;/p&gt;

&lt;p&gt;Let's get started with Installation&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Clone Starter Template
```bash
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;git clone &lt;a href="https://github.com/omkarcloud/google-maps-scraper" rel="noopener noreferrer"&gt;https://github.com/omkarcloud/google-maps-scraper&lt;/a&gt;&lt;br&gt;
cd google-maps-scraper&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2. Install dependencies
```bash


python -m pip install -r requirements.txt


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Run Project
```bash
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;python main.py&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
The script will start running and output progress updates to the console. When the scraper is complete, it will generate a CSV file named `finished.csv` in the `output` directory. The CSV file will contain the business name, address, phone number, website, rating, and review for each result.

Additionaly, you don't have to configure the Selenium driver as it will automatically download the appropriate driver based on your Chrome browser version.

## Configuration

- To specify the Google search queries to be used in the scraper, open the `src/scraper.py` file in your preferred text editor and update the `Task.queries` list with your desired queries.

- To specify whether to scrape the first page of Google Maps results or all pages of results, open the `src/scraper.py` file and set the `Task.GET_FIRST_PAGE` variable to `True` or `False` as appropriate.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>bot</category>
      <category>webscrapingtools</category>
    </item>
    <item>
      <title>⭐🤖🔑 9 Ninja Tips to prevent Bot from getting Detected like Grey Ninja 🕵️‍♂️🔍🛡️</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Sat, 20 May 2023 16:33:14 +0000</pubDate>
      <link>https://dev.to/chetanam/9-ninja-tips-to-prevent-bot-from-getting-detected-like-grey-ninja-koc</link>
      <guid>https://dev.to/chetanam/9-ninja-tips-to-prevent-bot-from-getting-detected-like-grey-ninja-koc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine this: You've writing a Selenium script to automate a website, only to be blocked by detection services like Cloudflare and PerimeterX.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j9ydEBY8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnski81ul69rup8548ng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j9ydEBY8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnski81ul69rup8548ng.png" alt="Cloudflare Bot Caught" width="800" height="662"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this Article, I will share 9 Brilliant Tips to prevent Cloudflare and PerimeterX from detecting your Bots.&lt;/p&gt;

&lt;p&gt;Within this article, I will also introduce you to Bose Framework, a framework that I created using my bot development skills to help bot developers in creating unstoppable Bots. Think of it like Swiss Army Knife for Bot Development.&lt;/p&gt;

&lt;p&gt;I have concentrated all my Knowledge of Bot Development into a Single Easy to use Framework for the benefit of all Bot Developers. &lt;/p&gt;

&lt;p&gt;Now, Let us learn the Tips to avoid bot detection from Cloudflare and PerimeterX like a Real Ninja.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. User-Agent and Window Size Rotation
&lt;/h3&gt;

&lt;p&gt;Bot Detection systems analyze the user agent and window size to identify bots. &lt;/p&gt;

&lt;p&gt;For instance, making an abnormal number of requests (e.g., 1000 page visits) using a single user agent increases the chances of being flagged as a bot.&lt;/p&gt;

&lt;p&gt;Also, using made up user agents that are not in usage also increases the chances of being flagged as a bot.&lt;/p&gt;

&lt;p&gt;So, it is best to use commonly used User Agents like Chrome 104 and Chrome 106 on a random basis.&lt;/p&gt;

&lt;p&gt;In Bose Framework, the following code snippet demonstrates how to achieve random rotation of user agents and window sizes with each run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;bose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseTask&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;browser_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BrowserConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UserAgent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RANDOM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;WindowSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RANDOM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, if you are utilizing the Bose Framework instead of plain Selenium, the user agent will be automatically rotated on each run by default.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Change your IPs
&lt;/h3&gt;

&lt;p&gt;To evade detection, changing your IP address is another crucial aspect. Websites often track IP addresses to identify and block suspicious activity.&lt;/p&gt;

&lt;p&gt;If you have been detected by services like Cloudflare or PerimeterX, you will need to change your IP address to continue automation.&lt;/p&gt;

&lt;p&gt;There are both free and paid methods to change your IP address:&lt;/p&gt;

&lt;h4&gt;
  
  
  Free Methods
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Enable and disable airplane mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this method, you can utilize the connection between your PC and a mobile hotspot to access the internet via a SIM card and then enable and disable airplane mode on your mobile device to get a new IP address. &lt;/p&gt;

&lt;p&gt;This method is quite fast and usually takes 10 seconds to acquire a new IP.&lt;/p&gt;

&lt;p&gt;Here's how you can enable and disable airplane mode to change your IP address:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Connect your PC to a mobile hotspot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On your mobile device, turn airplane mode on and off&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, Turn the Hotspot On Again.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;On and Off WIFI Router&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For devices connected to a Wi-Fi network, turning off the router and then turning it back on will change the IP address. Although It is slow methods as Wifi Router will take 2-3 minutes to start. &lt;/p&gt;

&lt;h4&gt;
  
  
  Paid Method
&lt;/h4&gt;

&lt;p&gt;Paid services like Oxylab and IPRoyal provide a pool of residential IP addresses. However, they can be quite expensive, with prices averaging around $15 per GB for residential IPs. If you opt for this method and are scraping large amounts of data, consider disabling the loading of CSS and images to reduce costs.&lt;/p&gt;




&lt;p&gt;In general, the free method of using airplane mode works well for most use cases. It is not only free but also faster than using a proxy&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Humane Page Flow
&lt;/h3&gt;

&lt;p&gt;To avoid suspicion, replicate organic user behavior by engaging with the website as a human would. In general you should follow these recomendation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access pages via search engines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of directly visiting a page, navigate to it through a search engine like Google. This emulates how users typically discover websites by searching on a search engine. The Bose Framework provides a special method called organic_get in the Selenium driver, which achieves this behavior. You can use it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;organic_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Navigate using internal links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Browsers can detect the page you came from by checking the &lt;code&gt;document.referrer&lt;/code&gt; property. When visiting multiple pages within a site, utilize the get_by_current_page_referrer method from the Bose driver. This JavaScript-based method simulates internal navigation by clicking a link, making it appear more natural:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_by_current_page_referrer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Use Random Waits and Slow the Bot
&lt;/h3&gt;

&lt;p&gt;Adding random wait times  and slowing bot between actions helps mimic human interaction patterns and evade bot detection. &lt;/p&gt;

&lt;p&gt;The Bose Framework offers &lt;code&gt;short_random_sleep()&lt;/code&gt; and &lt;code&gt;long_random_sleep()&lt;/code&gt; methods that pause the bot for a random duration.&lt;/p&gt;

&lt;p&gt;Here is how you can use them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;short_random_sleep&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;long_random_sleep&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Use Captcha Solving Services
&lt;/h3&gt;

&lt;p&gt;Services like Cloudflare may present CAPTCHA challenges. To overcome this obstacle, you can use CAPTCHA solving services like &lt;strong&gt;2captcha&lt;/strong&gt;, which solves the CAPTCHA challenges.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Use Ultrafunkamsterdam’s ChromeDriver
&lt;/h3&gt;

&lt;p&gt;Ultrafunkamsterdam's ChromeDriver, developed by Leon from the Netherlands, is an exceptional tool that enhances the stealth of Selenium Driver . It applies patches making it harder for detection services like Cloudflare and PerimeterX to detect the Bot.&lt;/p&gt;

&lt;p&gt;The Bose Framework seamlessly integrates with Ultrafunkamsterdam’s ChromeDriver. To use it, specify &lt;code&gt;use_undetected_driver=True&lt;/code&gt; in the &lt;code&gt;browser_config&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseTask&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;browser_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BrowserConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;use_undetected_driver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Do not use a Headless Browser
&lt;/h3&gt;

&lt;p&gt;Avoid using headless browsers, as bot detection systems like PerimeterX can detect them by checking for specific APIs. &lt;/p&gt;

&lt;p&gt;For example, the following code in JavaScript determines whether the browser is headless. In the case of headless Chrome, the test will log "Headless Chrome"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permissions&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notifications&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;permissionStatus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permission&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;denied&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nx"&gt;permissionStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prompt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Headless Chrome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Not Headless Chrome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Maintain Consistency in User Agent, Window Size, and IP Address
&lt;/h3&gt;

&lt;p&gt;If you are maintaining sessions by using a profile in Selenium, then make sure that the User Agent and Window Size remains same for the Profile. &lt;/p&gt;

&lt;p&gt;Sudden and frequent changes in these parameters like one time you are using Chrome 106 and then Chrome 98 and then Chrome 102 can raise red flags and lead to detection.&lt;/p&gt;

&lt;p&gt;In the Bose Framework, if you specify a profile in a task, it will automatically retain the same user agent and window size on each run using that profile. Here's an example of how to specify a profile in the Boss Task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseTask&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# The User Agent and Window Size will remain same on each run with profile 1.
&lt;/span&gt;    &lt;span class="n"&gt;browser_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BrowserConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, When using a proxy, it is equally important to maintain consistency in the IP address location. Avoid abrupt changes from one country to another, such as switching from Bharat (India) to Russia and then to Israel. &lt;/p&gt;

&lt;h3&gt;
  
  
  9. Use Bose Framework
&lt;/h3&gt;

&lt;p&gt;Whenever you are developing any Selenium Script, you should definetly use Bose Framework.&lt;/p&gt;

&lt;p&gt;Just like a Thunder Stone evolves Pikachu into Raichu in the Pokémon world, the Bose Framework transforms a normal bot developer into a mega bot developer.&lt;/p&gt;

&lt;p&gt;Read the Bose Framework Tutorial at &lt;a href="https://www.omkar.cloud/bose/docs/tutorial/"&gt;https://www.omkar.cloud/bose/docs/tutorial/&lt;/a&gt; to create powerful bots.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>tutorial</category>
      <category>webscrapingtools</category>
    </item>
    <item>
      <title>💻🎯 Ninja Kubernetes Cheat Sheet for Ninja Developers 📜</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Thu, 18 May 2023 13:58:35 +0000</pubDate>
      <link>https://dev.to/chetanam/must-book-mark-kubernetes-cheat-sheet-1o3a</link>
      <guid>https://dev.to/chetanam/must-book-mark-kubernetes-cheat-sheet-1o3a</guid>
      <description>&lt;h2&gt;
  
  
  A small request
&lt;/h2&gt;

&lt;p&gt;I'm trying to reach 1K GitHub stars for "&lt;a href="https://github.com/omkarcloud/bose"&gt;Bose&lt;/a&gt;" - an open source bot development framework I just launched for easily creating advanced selenium based bots.&lt;br&gt;
Can you help us out by starring the GitHub repository? It would help us a lot! Thank you! &lt;a href="https://github.com/omkarcloud/bose"&gt;https://github.com/omkarcloud/bose&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Popular
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Ger logs of Pods in a Deployment. This is the recommended way to fetch logs, as the deployment name remains the same even if pods change upon creation.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# View the latest logs from the end. This can be useful when there are a large number of logs generated by a pod.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;

&lt;span class="c1"&gt;# Access a Pod within a Deployment using an interactive bash shell. This is the recommended method as the deployment name remains the same, unlike the pods that change upon creation.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="k"&gt;exec&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;bash&lt;/span&gt;

&lt;span class="c1"&gt;# Access a Pod within a Deployment using an interactive shell. Use this if the previous method fails, as the pod does not support bash.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="k"&gt;exec&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;sh&lt;/span&gt;

&lt;span class="c1"&gt;# Apply a folder or file containing Kubernetes manifests.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="nb"&gt;apply&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# Delete a folder or file containing Kubernetes manifests.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# Delete a deployment.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;deployment&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# Forcefully delete a deployment without waiting for graceful termination.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;deployment&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;grace&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;period&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt;

&lt;span class="c1"&gt;# Display the logs of a specific pod.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# Stream and display the logs of a specific pod.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;follow&lt;/span&gt;

&lt;span class="c1"&gt;# Delete all jobs.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="sb"&gt;`kubectl get jobs -o custom-columns=:.name`&lt;/span&gt;

&lt;span class="c1"&gt;# Delete pods based on a selector.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;pods&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pods
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all pods in the current namespace.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;pods&lt;/span&gt;

&lt;span class="c1"&gt;# Get detailed information about a pod.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;pod&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# Create a new pod.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;pod&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a pod.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;pod&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;pod&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Nodes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all nodes in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;nodes&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a node.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new node
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a node
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Services
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all services in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a service.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new service.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a service.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deployments
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all deployments in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;deployments&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a deployment.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;deployment&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new deployment.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;deployment&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a deployment.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;deployment&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deployment&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ReplicaSets
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all replica sets in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;replicasets&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a replica set.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;replicaset&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;replicaset&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new replica set.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;replicaset&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;replicaset&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a replica set.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;replicaset&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;replicaset&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  StatefulSets
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all stateful sets in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;statefulsets&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a stateful set.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;statefulset&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;statefulset&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new stateful set.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;statefulset&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;statefulset&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a stateful set.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;statefulset&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;statefulset&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Jobs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all jobs in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a job.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# Create a new job.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a job.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CronJobs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all cron jobs in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;cronjobs&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a cron job.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;cronjob&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;cronjob&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new cron job.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;cronjob&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;cronjob&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a cron job.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;cronjob&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;cronjob&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ConfigMaps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all config maps in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;configmaps&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a config map.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;configmap&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;configmap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new config map.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;configmap&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;configmap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a config map.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;configmap&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;configmap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Secrets
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all secrets in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a secret.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new secret.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a secret.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ingresses
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all ingresses in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;ingresses&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about an ingress.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;ingress&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ingress&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# Create a new ingress.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;ingress&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ingress&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete an ingress.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;ingress&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ingress&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  PersistentVolumes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all persistent volumes in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;pv&lt;/span&gt; 

&lt;span class="c1"&gt;# Get detailed information about a persistent volume.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;pv&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;persistentvolume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new persistent volume.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;pv&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;persistentvolume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a persistent volume.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;pv&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;persistentvolume&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  PersistentVolumesClaims
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# List all persistent volumes in the cluster.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;pvc&lt;/span&gt;

&lt;span class="c1"&gt;# Get detailed information about a persistent volume.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;pvc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;persistentvolumesclaim&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Create a new persistent volume.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;pvc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;persistentvolumesclaim&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

&lt;span class="c1"&gt;# Delete a persistent volume.
&lt;/span&gt;&lt;span class="n"&gt;kubectl&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;pvc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;persistentvolumesclaim&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Also, this article is licensed under MIT, so you are free to use it as you wish.&lt;/p&gt;

&lt;p&gt;If you are a YouTuber, I encourage you to create a video of this article on your channel. By doing so, you can potentially help thousands of developers solve their deployment problems and earn great amounts of punya. Additionally, you can send me your Video URL and I will feature your video at the top of the article, boosting its views.&lt;/p&gt;




&lt;p&gt;Some of my brilliant Creations, that you don’t want to miss out are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Bose Framework: An Open Source Framework that is Swiss Army Knife for Selenium. Read the docs at &lt;a href="https://www.omkar.cloud/bose/"&gt;https://www.omkar.cloud/bose/&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Free Tools: Simplify your daily tasks with the Free Omkar Tools, an all-in-one dashboard that offers a range of free utilities. Whether it's formatting JSON, comparing text, or testing RegExp, these tools have got you covered. Say goodbye to unreliable websites and use it at &lt;a href="https://www.omkar.cloud/tools/"&gt;https://www.omkar.cloud/tools/&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Omkar Cloud: My Samurai Lead Generation Software allows you to access over 200M+ LinkedIn leads, enabling you to win clients. It's like Sales Navigator with superpowers. You can use it at &lt;a href="https://www.omkar.cloud/"&gt;https://www.omkar.cloud/&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Omkar Cloud Datasets: Enhance your analysis with meticulously scraped datasets from Stack Overflow, G2, and many more reputable sources. These fresh datasets are readily available for your data analysis at &lt;a href="https://www.omkar.cloud/datasets/"&gt;https://www.omkar.cloud/datasets/&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kubernetes Consultation: Take your DevOps practices to the next level with our team of Ninja Developers. Through our Kubernetes Consultation service, we can help you turbocharge your DevOps processes and enable you to move at the speed of light. Whatsapp us for a consultation at &lt;a href="https://www.omkar.cloud/l/whatsapp"&gt;https://www.omkar.cloud/l/whatsapp&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>kubernetes</category>
      <category>tutorial</category>
      <category>docker</category>
      <category>devops</category>
    </item>
    <item>
      <title>🌍🚀🎯 From Localhost to Cloud ☁️: Next.js, Django, SSL 🔒, GitHub Actions 🚀, DNS| Ultimate Website Deployment Tutorial🌟🔥✨</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Wed, 17 May 2023 16:59:19 +0000</pubDate>
      <link>https://dev.to/chetanam/from-localhost-to-cloud-nextjs-django-ssl-github-actions-dns-ultimate-website-deployment-tutorial-34hp</link>
      <guid>https://dev.to/chetanam/from-localhost-to-cloud-nextjs-django-ssl-github-actions-dns-ultimate-website-deployment-tutorial-34hp</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Ffeatured-image.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Ffeatured-image.jpg" alt="featured-image.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A small request
&lt;/h2&gt;

&lt;p&gt;I'm trying to reach 1K GitHub stars for "&lt;a href="https://github.com/omkarcloud/bose" rel="noopener noreferrer"&gt;Bose&lt;/a&gt;" - an open source bot development framework I just launched for easily creating advanced selenium based bots.&lt;br&gt;
Can you help us out by starring the GitHub repository? It would help us a lot! Thank you! &lt;a href="https://github.com/omkarcloud/bose" rel="noopener noreferrer"&gt;https://github.com/omkarcloud/bose&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Picture this: 📸 You have developed a stunning website, and now it's time to make it accessible to the world. But the deployment process seems daunting, right? 😰&lt;/p&gt;

&lt;p&gt;Fear not, because Kubernetes is here to save the day. 🦸‍♂️ With its powerful features and intelligent container management, Kubernetes takes the complexity out of website deployment.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will demystify Kubernetes and guide you through the process of deploying your website effortlessly. Get ready to unlock the magic of Kubernetes and witness your website thrive in realms of the Cloud. ✨🌐&lt;/p&gt;

&lt;h2&gt;
  
  
  What we will do
&lt;/h2&gt;

&lt;p&gt;We will guide you through the process of deploying your website from running locally on your localhost to the Cloud.&lt;/p&gt;

&lt;p&gt;The website will be a full stack website with frontend and backend with a SQLite database served over SSL. &lt;/p&gt;

&lt;p&gt;We will also make a CI Pipeline to deploy code on commit to master Branch.&lt;/p&gt;

&lt;p&gt;To accomplish this, we will perform the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dockerize the Next.js frontend and Django backend.&lt;/li&gt;
&lt;li&gt;Write Kubernetes manifests for frontend and backend servers, including a Persistent Volume for the Django SQLite database and obtaining an SSL certificate using Cert Manager.&lt;/li&gt;
&lt;li&gt;Create a Kubernetes cluster in GCP.&lt;/li&gt;
&lt;li&gt;Configure the domain's DNS.&lt;/li&gt;
&lt;li&gt;Write GitHub Actions YAML for building and deploying applications to GCP.&lt;/li&gt;
&lt;li&gt;Push code to GitHub for deployment. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial involves several technologies, and if you encounter any unfamiliar concepts, don't worry. As you progress through the tutorial, you will gain a better understanding of each technology and its role in the deployment process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To successfully complete this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GCP Account&lt;/li&gt;
&lt;li&gt;A Domain Name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you haven't purchased a domain name yet, I recommend using Namecheap as I have personally used them and had a good experience.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I highly recommend to read through the tutorial 2-3 times before proceeding with the deployment on your own.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Dockerization
&lt;/h2&gt;

&lt;p&gt;For this tutorial, a repository has been created consisting of two folders: &lt;code&gt;frontend&lt;/code&gt; and &lt;code&gt;backend&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;frontend&lt;/code&gt; folder contains the code for the Next.js-based application, while the &lt;code&gt;backend&lt;/code&gt; folder contains the code for the Django-based application.&lt;/p&gt;

&lt;p&gt;To begin, you will need to clone the starter code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

git clone https://github.com/omkarcloud/kubernetes-website-deployment-tutorial-starter


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open the project in Visual Studio Code by running:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

code kubernetes-website-deployment-tutorial-starter/


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Dockerizing Frontend
&lt;/h3&gt;

&lt;p&gt;To Dockerize the frontend code built with Next.js, create a Dockerfile in the frontend folder with the following contents:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;frontend/Dockerfile&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:16-alpine&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; node_modules/ .next/&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--legacy-peer-deps&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "run", "start"]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Additionally, create a .dockerignore file in the frontend folder with the same contents as .gitignore by running following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;cp &lt;/span&gt;frontend/.gitignore frontend/.dockerignore


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Dockerizing Backend
&lt;/h3&gt;

&lt;p&gt;Now, let's Dockerize the Django-based backend code by creating a &lt;code&gt;Dockerfile&lt;/code&gt; in the &lt;code&gt;backend&lt;/code&gt; folder with the following contents:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;backend/Dockerfile&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.9&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PYTHONBUFFERED 1&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;app
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /app&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; gunicorn --workers 3 -b 0.0.0.0:8000 config.wsgi&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, create a .dockerignore file in the backend folder with the same contents as .gitignore by running following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

cp backend/.gitignore backend/.dockerignore


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Creating PVC for Backend
&lt;/h2&gt;

&lt;p&gt;To ensure persistence of our SQLite database file used in the Django application, let's create a Persistent Volume Claim (PVC) by creating &lt;code&gt;pvc.yaml&lt;/code&gt; file at &lt;code&gt;k8s/volumes/&lt;/code&gt; with the following contents, which provisions 4GB of storage in GCP:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;k8s/volumes/pvc.yaml&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PersistentVolumeClaim&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;csi-pvc&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;accessModes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ReadWriteOnce&lt;/span&gt;
  &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;4Gi&lt;/span&gt;
  &lt;span class="na"&gt;storageClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;standard-rwo&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Creating Service for Backend and Frontend
&lt;/h2&gt;

&lt;p&gt;To make the backend and frontend pods accessible within the cluster, create the following manifest files:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Backend Deployment (&lt;code&gt;k8s/app/backend-depl.yaml&lt;/code&gt;):
```yaml
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;apiVersion: apps/v1&lt;br&gt;
kind: Deployment&lt;br&gt;
metadata:&lt;br&gt;
  name: backend-depl&lt;br&gt;
spec:&lt;br&gt;
  replicas: 1&lt;br&gt;
  selector:&lt;br&gt;
    matchLabels:&lt;br&gt;
      app: backend&lt;br&gt;
  template:&lt;br&gt;
    metadata:&lt;br&gt;
      labels:&lt;br&gt;
        app: backend&lt;br&gt;
    spec:&lt;br&gt;
      volumes:&lt;br&gt;
        - name: app-data&lt;br&gt;
          persistentVolumeClaim:&lt;br&gt;
            claimName: csi-pvc&lt;br&gt;
      containers:&lt;br&gt;
        - name: backend&lt;br&gt;
          image: placeholder/backend:1.0.5&lt;br&gt;
          volumeMounts:&lt;br&gt;
            - mountPath: /app-data&lt;/p&gt;
&lt;h2&gt;
  
  
                name: app-data
&lt;/h2&gt;

&lt;p&gt;apiVersion: v1&lt;br&gt;
kind: Service&lt;br&gt;
metadata:&lt;br&gt;
  name: backend-srv&lt;br&gt;
spec:&lt;br&gt;
  selector:&lt;br&gt;
    app: backend&lt;br&gt;
  ports:&lt;br&gt;
    - name: backend&lt;br&gt;
      protocol: TCP&lt;br&gt;
      port: 8000&lt;br&gt;
      targetPort: 8000&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
2.  Frontend Deployment (`k8s/app/frontend-depl.yaml`):
```yaml


apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: frontend
          resources:
            requests:
              ephemeral-storage: "800Mi"
            limits:
              ephemeral-storage: "800Mi"
          image: placeholder/frontend:1.0.4
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-srv
spec:
  selector:
    app: frontend
  ports:
    - name: frontend
      protocol: TCP
      port: 3000
      targetPort: 3000


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Creating Load Balancer
&lt;/h2&gt;

&lt;p&gt;To expose our pods via services, we need to create an Ingress resource. Create a file named &lt;code&gt;ingress.yaml&lt;/code&gt; in &lt;code&gt;k8s/app/&lt;/code&gt; with the following contents, replacing "&lt;a href="http://www.your-domain.com" rel="noopener noreferrer"&gt;www.your-domain.com&lt;/a&gt;" with your domain name:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;k8s/app/ingress.yaml&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ingress-service&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kubernetes.io/ingress.class&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="na"&gt;cert-manager.io/issuer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;letsencrypt-prod"&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/proxy-body-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;80m&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/proxy-connect-timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;30"&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/proxy-send-timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;600"&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/proxy-read-timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;600"&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;www.your-domain.com"&lt;/span&gt;
      &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/backend&lt;/span&gt;
            &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prefix&lt;/span&gt;
            &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backend-srv&lt;/span&gt;
                &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8000&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
            &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prefix&lt;/span&gt;
            &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;frontend-srv&lt;/span&gt;
                &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;

  &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;www.your-domain.com"&lt;/span&gt;
      &lt;span class="na"&gt;secretName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ssl-certificate&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Getting SSL Certificate
&lt;/h2&gt;

&lt;p&gt;To obtain an SSL certificate for your domain, you can create a YAML file named &lt;code&gt;certificates.yaml&lt;/code&gt; in the &lt;code&gt;k8s/certificates&lt;/code&gt; directory. &lt;/p&gt;

&lt;p&gt;Replace &lt;code&gt;www.your-domain.com&lt;/code&gt; with your actual domain name and optionally replace &lt;code&gt;youremail@gmail.com&lt;/code&gt; with your email address to receive SSL-related emails from Let's Encrypt (Our SSL Provider).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;k8s/certificates/certificates.yaml&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cert-manager.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Issuer&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;letsencrypt-prod&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;acme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://acme-v02.api.letsencrypt.org/directory&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;youremail@gmail.com&lt;/span&gt;
    &lt;span class="na"&gt;privateKeySecretRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;letsencrypt-prod&lt;/span&gt;
    &lt;span class="na"&gt;solvers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;http01&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
        &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;dnsNames&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;www.your-domain.com"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Create Github Actions
&lt;/h2&gt;

&lt;p&gt;To automate the deployment process of your application on each commit to the master branch, you can utilize GitHub Actions. &lt;/p&gt;

&lt;p&gt;The following workflow defines the necessary steps to authenticate with Google Cloud Platform (GCP), build Docker images, push them to Google Container Registry, and deploy the application to Google Kubernetes Engine (GKE) cluster. &lt;/p&gt;

&lt;p&gt;Please note that the deployment includes deleting the previous backend deployment, which will result in temporary downtime of 4 to 5 minutes whenever you deploy code by pushing to Github.&lt;/p&gt;

&lt;p&gt;We also utilize various Google Cloud Platform (GCP) environment variables for the deployment, which we will store securely in the secrets of our GitHub repository later.&lt;/p&gt;

&lt;p&gt;To use this workflow create a file called &lt;code&gt;deploy.yaml&lt;/code&gt; in the &lt;code&gt;.github/workflows&lt;/code&gt; directory. Here is the content for the &lt;code&gt;deploy.yaml&lt;/code&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.github/workflows/deploy.yaml&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Deploy to GKE&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;

&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;PROJECT_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GKE_PROJECT }}&lt;/span&gt;
  &lt;span class="na"&gt;GKE_CLUSTER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-application-cluster&lt;/span&gt;
  &lt;span class="na"&gt;GKE_PROJECT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GKE_PROJECT }}&lt;/span&gt;
  &lt;span class="na"&gt;GKE_CLUSTER_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-application-cluster&lt;/span&gt;
  &lt;span class="na"&gt;GKE_ZONE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asia-south1-a&lt;/span&gt;
  &lt;span class="na"&gt;GKE_EMAIL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GKE_EMAIL }}&lt;/span&gt;
  &lt;span class="na"&gt;GKE_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GKE_KEY }}&lt;/span&gt;
  &lt;span class="na"&gt;GITHUB_SHA&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.sha }}&lt;/span&gt;
  &lt;span class="na"&gt;ACTIONS_ALLOW_UNSECURE_COMMANDS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
  &lt;span class="na"&gt;USE_GKE_GCLOUD_AUTH_PLUGIN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;True"&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;setup-build-publish-deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup, Build, Publish, and Deploy&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;read'&lt;/span&gt;
      &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;write'&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set Images as enviroment variables&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "FRONTEND=$(echo "gcr.io/""$GKE_PROJECT""/frontend:""$GITHUB_SHA")" &amp;gt;&amp;gt; $GITHUB_ENV&lt;/span&gt;
          &lt;span class="s"&gt;echo "BACKEND=$(echo "gcr.io/""$GKE_PROJECT""/backend:""$GITHUB_SHA")" &amp;gt;&amp;gt; $GITHUB_ENV&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;update images&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;FRONTEND_ESCAPE=$(printf '%s\n' "$FRONTEND" | sed -e 's/[\/&amp;amp;]/\\&amp;amp;/g')&lt;/span&gt;
          &lt;span class="s"&gt;sed -i -e 's/placeholder\/frontend:1.0.4/'"$FRONTEND_ESCAPE"'/g' frontend-depl.yaml&lt;/span&gt;
          &lt;span class="s"&gt;cat frontend-depl.yaml&lt;/span&gt;
          &lt;span class="s"&gt;BACKEND_ESCAPE=$(printf '%s\n' "$BACKEND" | sed -e 's/[\/&amp;amp;]/\\&amp;amp;/g')&lt;/span&gt;
          &lt;span class="s"&gt;sed -i -e 's/placeholder\/backend:1.0.5/'"$BACKEND_ESCAPE"'/g' backend-depl.yaml&lt;/span&gt;
          &lt;span class="s"&gt;cat backend-depl.yaml&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;k8s/app&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;auth'&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;google-github-actions/auth@v1'&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;credentials_json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secrets.GCP_CREDENTIALS&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Cloud SDK&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;google-github-actions/setup-gcloud@v1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Gke&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;gcloud components install gke-gcloud-auth-plugin&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Cluster Login&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;gcloud container clusters get-credentials $GKE_CLUSTER_NAME --zone $GKE_ZONE --project $GKE_PROJECT&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure Docker&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gcloud --quiet auth configure-docker&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker build --tag "$FRONTEND" .&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;frontend&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker build --tag "$BACKEND" .&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backend&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Push Images&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;docker push "$FRONTEND"&lt;/span&gt;
          &lt;span class="s"&gt;docker push "$BACKEND"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;kubectl delete deployment backend-depl || true&lt;/span&gt;
          &lt;span class="s"&gt;kubectl apply --recursive -f k8s/&lt;/span&gt;
          &lt;span class="s"&gt;deploy=$(kubectl get deploy -o name) &amp;amp;&amp;amp;  for i in $deploy; do kubectl rollout status $i -w --timeout=30s; done || true&lt;/span&gt;
          &lt;span class="s"&gt;kubectl get pods&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  GCP Setup
&lt;/h2&gt;

&lt;p&gt;Now, we will set up the GCP Cluster.&lt;br&gt;
I will tell you when there you need to change some variables. Please only modify the variables I tell you and keep the other variables untouched, such as the cluster name and zone etc.&lt;/p&gt;

&lt;p&gt;As they are hardcoded and will be used multiple times in the commands of this Tutorial. Once you have become familiar with the tutorial, feel free to rename them according to your preference.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enable the following APIs for your Project to create a GKE cluster:
```bash
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Artifact Registry: &lt;a href="https://console.cloud.google.com/marketplace/product/google/artifactregistry.googleapis.com" rel="noopener noreferrer"&gt;https://console.cloud.google.com/marketplace/product/google/artifactregistry.googleapis.com&lt;/a&gt;&lt;br&gt;
Kubernetes Engine: &lt;a href="https://console.cloud.google.com/marketplace/product/google/container.googleapis.com" rel="noopener noreferrer"&gt;https://console.cloud.google.com/marketplace/product/google/container.googleapis.com&lt;/a&gt;&lt;br&gt;
Compute Engine: &lt;a href="https://console.cloud.google.com/marketplace/product/google-cloud-platform/compute-engine" rel="noopener noreferrer"&gt;https://console.cloud.google.com/marketplace/product/google-cloud-platform/compute-engine&lt;/a&gt;&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
![api-gcp.png](https://www.omkar.cloud/blog/static/blog/from-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes/api-gcp.png)

2. In the sidebar, click on the "Kubernetes Engine" button.

![gke.png](https://www.omkar.cloud/blog/static/blog/from-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes/gke.png)

3. Click on the "Create" button to create a new cluster. Configure the "Standard Mode" Cluster, as it is more cost-effective.

![choose.png](https://www.omkar.cloud/blog/static/blog/from-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes/choose.png)

4. Provide the following details for the cluster:

```bash


Cluster Name: my-application-cluster
Location Type: zonal
Zone: asia-south1-a


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fconfigure.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fconfigure.png" alt="configure.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the sidebar, select "default-pool" and change the number of nodes to 1 instead of 3 to save costs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fpool.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fpool.png" alt="pool.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the sidebar, select "Nodes" and use the following settings to save costs:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

Machine Type: e2-small 
Boot Disk Size: 20 GB 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fnodes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fnodes.png" alt="nodes.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The estimated cost should be around $90. If this is your first cluster in GCP, the cost will be charged around $27 after 1 Month discounting $73 discount for the first cluster.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click the "Create" button, and the cluster will be created in approximately 5-6 minutes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the GCP Shell by clicking the shell icon in the top-right corner.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fshell.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fshell.png" alt="shell.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authenticate in your cluster by running the following command. Replace "clear-world-31478" with your GCP project name.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

gcloud container clusters get-credentials my-application-cluster &lt;span class="nt"&gt;--zone&lt;/span&gt; asia-south1-a &lt;span class="nt"&gt;--project&lt;/span&gt; clear-world-31478


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Create an IP address by running the following command:
```bash
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;gcloud compute addresses create my-application-cluster-ip --region asia-south1&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
11. Note the created IP address by running the command:

```bash


gcloud compute addresses describe my-application-cluster-ip --region asia-south1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;In your Domain Name Service (DNS) provider, such as Namecheap, add the following records. Replace "31.91.11.253" with the IP address obtained in the previous step.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

A @ 31.91.11.253
A www 31.91.11.253


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ensure that the TTL (Time to Live) is set to the lowest possible value, such as 1 minute, to allow for fast DNS propagation. &lt;/p&gt;

&lt;p&gt;If you are using Namecheap, select the 1-minute TTL option, which will take 1 minute to propogate DNS Changes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Execute the following commands to install &lt;code&gt;ingress-nginx&lt;/code&gt; and &lt;code&gt;cert-manager&lt;/code&gt; which are needed do load balancing get the SSL certificate. In the following commands, replace 31.91.11.253 with the IP address you created earlier.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm upgrade &lt;span class="nt"&gt;--install&lt;/span&gt; ingress-nginx-chart ingress-nginx/ingress-nginx &lt;span class="nt"&gt;--set&lt;/span&gt; controller.service.loadBalancerIP&lt;span class="o"&gt;=&lt;/span&gt;31.91.11.253 &lt;span class="nt"&gt;--set&lt;/span&gt; controller.service.externalTrafficPolicy&lt;span class="o"&gt;=&lt;/span&gt;Local

helm repo add jetstack https://charts.jetstack.io
helm repo update
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.crds.yaml
helm &lt;span class="nb"&gt;install &lt;/span&gt;cert-manager jetstack/cert-manager &lt;span class="nt"&gt;--namespace&lt;/span&gt; cert-manager &lt;span class="nt"&gt;--create-namespace&lt;/span&gt; &lt;span class="nt"&gt;--version&lt;/span&gt; v1.8.0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Github Setup
&lt;/h2&gt;

&lt;p&gt;This is the final step where we will configure GitHub Secrets for our deployment workflow and push the code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a Github Repository &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a service account JSON file by visiting &lt;a href="https://console.cloud.google.com/iam-admin/serviceaccounts" rel="noopener noreferrer"&gt;https://console.cloud.google.com/iam-admin/serviceaccounts&lt;/a&gt;. The service account will have full access to all resources (Owner) in Google Cloud (GCP). Keep the JSON file secure, as it will be required for deploying to Google Kubernetes Engine (GKE). Save the file as account.json.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.omkar.cloud%2Fblog%2Fstatic%2Fblog%2Ffrom-localhost-to-cloud-next-js-django-ssl-github-actions-dns-configuration-the-ultimate-website-deployment-tutorial-with-kubernetes%2Fsa.png" alt="sa.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create Github secrets which are used in Workflow by going to your Repository GitHub Settings &amp;gt; Secrets &amp;gt; Actions and creating three secrets with the following names and values:
```
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;GKE_PROJECT="clear-world-31478"&lt;br&gt;
GKE_EMAIL="&lt;a href="mailto:owner-709@project.iam.gserviceaccount.com"&gt;owner-709@project.iam.gserviceaccount.com&lt;/a&gt;"&lt;br&gt;
GKE_KEY="JodHRWCzov...L3D3dy5n"&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Here,
  - `GKE_PROJECT` is your project name.
  - `GKE_EMAIL` is email located in the `account.json` file.
  - `GKE_KEY` is your service account encoded as base64. You can obtain it by running `cat account.json | base64`.

4. Now, push the code to the repository. Once pushed, the site will be ready 4-5 minutes after the GitHub Action is completed. It takes 4-5 minutes as it will obtain SSL certificates etc.

You can view status of your actions by visiting Action Tabs of your Github Repository.

After Action is Completed, you can access the website at your domain.

## Delete the Resources

Remember to delete the GCP resources to avoid incurring charges. Follow these steps to delete the GCP resources:

1. Delete the created IP address by running the following command. In this command, replace "clear-world-31478" with your GCP project name.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gcloud compute addresses delete my-application-cluster-ip --region asia-south1 --project clear-world-31478&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
2. Use the GKE Dashboard to delete the cluster using the graphical user interface.



## FAQ

**Q: How can I connect PostgreSQL to Django in Kubernetes?**

A: If you are just starting out, I highly recommend using SQLite to save both money and development time. However, if you prefer to use PostgreSQL, you can follow the tutorial at https://cloud.google.com/python/django/kubernetes-engine.


**Q: Where is the final Code?**

A: You can find the final code at https://github.com/omkarcloud/kubernetes-website-deployment-tutorial-finished.


## Final Words

Congratulations on successfully deploying your website! You have accomplished website deployment with SSL, DNS, GitHub Actions, etc.

If you have any questions, feel free to ask them in the comments.

--- 

Also, this article is licensed under MIT, so you are free to use it as you wish.

If you are a YouTuber, I encourage you to create a video of this article on your channel. By doing so, you can potentially help thousands of developers solve their deployment problems and earn great amounts of punya. Additionally, you can send me your Video URL and I will feature your video at the top of the article, boosting its views.

---
Did you enjoy this article or need an experienced Kubernetes Developer for a remote contract-based role? Feel free to contact me.

[WhatsApp](https://www.omkar.cloud/l/whatsapp)

&amp;lt;!--  
Some of my brilliant Creations, that you don’t want to miss out are: 

1.  Bose Framework: An Open Source Framework that is Swiss Army Knife for Selenium. Read the docs at https://www.omkar.cloud/bose/ 

2.  Free Tools: Simplify your daily tasks with the Free Omkar Tools, an all-in-one dashboard that offers a range of free utilities. Whether it's formatting JSON, comparing text, or testing RegExp, these tools have got you covered. Say goodbye to unreliable websites and use it at https://www.omkar.cloud/tools/.

3.  Omkar Cloud: My Samurai Lead Generation Software allows you to access over 200M+ LinkedIn leads, enabling you to win clients. It's like Sales Navigator with superpowers. You can use it at https://www.omkar.cloud/.

4.  Omkar Cloud Datasets: Enhance your analysis with meticulously scraped datasets from Stack Overflow, G2, and many more reputable sources. These fresh datasets are readily available for your data analysis at https://www.omkar.cloud/datasets/.

5.  Kubernetes Consultation: Take your DevOps practices to the next level with our team of Ninja Developers. Through our Kubernetes Consultation service, we can help you turbocharge your DevOps processes and enable you to move at the speed of light. Whatsapp us for a consultation at .

--&amp;gt;

Dhanyawad 🙏! Vande Mataram!


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>kubernetes</category>
      <category>tutorial</category>
      <category>docker</category>
      <category>devops</category>
    </item>
    <item>
      <title>How To Get Land Web Development Clients! 💰💰💰</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Sat, 22 Apr 2023 17:27:21 +0000</pubDate>
      <link>https://dev.to/chetanam/how-to-get-land-web-development-clients-he1</link>
      <guid>https://dev.to/chetanam/how-to-get-land-web-development-clients-he1</guid>
      <description>&lt;h2&gt;
  
  
  🎯 Overview
&lt;/h2&gt;

&lt;p&gt;You are here as you want to find clients for your web development agency.&lt;/p&gt;

&lt;p&gt;We have collected some of the best performing strategies to help you land clients for your web development firm.&lt;/p&gt;

&lt;p&gt;Let's not beat around the bush, and let me to share with you two great strategies to get clients for your web development agency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Suggest Interesting Ideas for their Business
&lt;/h2&gt;

&lt;p&gt;One of the surest to way get a conversation started with a prospect is to get interested in them and talk concretely in terms specifically how you could help them grow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's an example of how can be done&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Target the People most likely to need Web Development Services, we recommend targeting decision makers with verified emails at companies with size range of 11 to 100 in industries like Consumer Goods and Consumer Electronics as these people will be in more need of Web Development Service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can easily find people who fit this criteria using omkar cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZEB8YFCq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.omkar.cloud/blog/static/blog/how-to-get-clients-for-your-web-development-agencies/Suggest_Interesting_Ideas_for_Their_Business.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZEB8YFCq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.omkar.cloud/blog/static/blog/how-to-get-clients-for-your-web-development-agencies/Suggest_Interesting_Ideas_for_Their_Business.png" alt="Suggest Interesting Ideas for Their Business.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now you should visit each prospect's exisiting website and send a personalized email thats demonstrates effective steps to make their website better. Following is an excellent example that you can use as a basis for your email
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Subject: Ideas for {{company_name}}

Hi {{first_name}},
Congrats on having a huge following on Facebook. However when I checked your website [Website URL] it does not match the quality of work you guys are doing.

I identified a few areas where quick wins could be achieved:

1. Adding a feature for customers to get notified when products are back in stock.
2. Adding a blog to enhance your SEO efforts.
3. Implementing a contact form for customers to easily reach out with questions.

I have helped [Similar Company] and they saw a significant boost in revenue from it this year.

Are these ideas you've been considering?

Best,
[Your Name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The thing that will really boost response rates is following up with prospect. So Follow with the prospect say 2 Days later in case they didn’t respond. Following is an excellent email template that you can use
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Hey {{first_name}}, I know that you are a busy person. So just wanted to follow up so that this doesn't get lost
Thanks,
[Your Name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reaching Out to Prospects Hiring a Web Developer
&lt;/h2&gt;

&lt;p&gt;If a company which has posted a job vacancy for web development role then their are high chances to convert them into a Customer.&lt;/p&gt;

&lt;p&gt;While some companies want to hire in-house, others are open to discussing the option of working with a web development agency, especially if you can demonstrate that you are a great choice for them.&lt;/p&gt;

&lt;p&gt;Also in case they are adamant about hiring in-house still you can still offer to provide them with a skilled web developer from your agency on a monthly contract basis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's an example of how it can be done:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Target the People who are hiring for Web Development Role, we recommend targeting decision makers with verified emails at companies with size range of 11 to 100 who are hiring for Web Developer, Web Designer, Frontend Developer Role.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can easily find people who fit this criteria using omkar cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bak1nSqD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.omkar.cloud/blog/static/blog/how-to-get-clients-for-your-web-development-agencies/Reaching_Out_to_Prospects_Hiring_a_Web_Developer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bak1nSqD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.omkar.cloud/blog/static/blog/how-to-get-clients-for-your-web-development-agencies/Reaching_Out_to_Prospects_Hiring_a_Web_Developer.png" alt="Reaching Out to Prospects Hiring a Web Developer.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now send a personalized email. Following is an excellent email template that you can use
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Subject: Hiring [Job Title] at [Company Name]?

Hi [Name],
Saw that you’re hiring [Job Title] at [Company Name].

I wanted to see if you’d be interested in our Web Development as a Service offering. You only pay for results you get.

Something you might be interested in?

Best,
[Your Name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;As a best practice send a followup email to increase your response rates. Following is an excellent email template that you can use
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hey {{first_name}}, I know that you are a busy person. So just wanted to follow up so that this doesn't get lost
Thanks,
[Your Name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;That's all there is to getting clients for your web development agencies, these were 2 battle tested strategies you can use and see results for yourself.&lt;/p&gt;

&lt;p&gt;Understand that Knowledge learned but not applied does not bear fruit. So head over to &lt;a href="https://www.omkar.cloud/"&gt;omkar.cloud&lt;/a&gt;, discover your leads, and start shooting emails :)&lt;/p&gt;

&lt;p&gt;Wish you best of luck!&lt;/p&gt;

&lt;p&gt;Dhanyawad 🙏&lt;/p&gt;




&lt;p&gt;Some of my brilliant Creations, that you don’t want to miss out are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Bose Framework: An Open Source Framework that is Swiss Army Knife for Selenium. Read the docs at &lt;a href="https://www.omkar.cloud/bose/"&gt;https://www.omkar.cloud/bose/&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Free Tools: Simplify your daily tasks with the Free Omkar Tools, an all-in-one dashboard that offers a range of free utilities. Whether it's formatting JSON, comparing text, or testing RegExp, these tools have got you covered. Say goodbye to unreliable websites and use it at &lt;a href="https://www.omkar.cloud/tools/"&gt;https://www.omkar.cloud/tools/&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Omkar Cloud: My Samurai Lead Generation Software allows you to access over 200M+ LinkedIn leads, enabling you to win clients. It's like Sales Navigator with superpowers. You can use it at &lt;a href="https://www.omkar.cloud/"&gt;https://www.omkar.cloud/&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Omkar Cloud Datasets: Enhance your analysis with meticulously scraped datasets from Stack Overflow, G2, and many more reputable sources. These fresh datasets are readily available for your data analysis at &lt;a href="https://www.omkar.cloud/datasets/"&gt;https://www.omkar.cloud/datasets/&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kubernetes Consultation: Take your DevOps practices to the next level with our team of Ninja Developers. Through our Kubernetes Consultation service, we can help you turbocharge your DevOps processes and enable you to move at the speed of light. Whatsapp us for a consultation at &lt;a href="https://www.omkar.cloud/l/whatsapp"&gt;https://www.omkar.cloud/l/whatsapp&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>tutorial</category>
      <category>react</category>
      <category>python</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How To Get Clients For Web Development Agencies</title>
      <dc:creator>Chetan</dc:creator>
      <pubDate>Sat, 22 Apr 2023 13:58:24 +0000</pubDate>
      <link>https://dev.to/chetanam/how-to-get-clients-for-web-development-agencies-117c</link>
      <guid>https://dev.to/chetanam/how-to-get-clients-for-web-development-agencies-117c</guid>
      <description>&lt;h2&gt;
  
  
  🎯 Overview
&lt;/h2&gt;

&lt;p&gt;You are here because you want to find clients for your web development agency.&lt;/p&gt;

&lt;p&gt;We have collected some of the best performing strategies to help you land clients for your web development firm.&lt;/p&gt;

&lt;p&gt;Let's not beat around the bush, and let me to share with you two great strategies to get clients for your web development agency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Suggest Interesting Ideas for their Business
&lt;/h2&gt;

&lt;p&gt;One of the surest to way get a conversation started with a prospect is to get interested in them and talk concretely in terms specifically how you could help them grow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's an example of how can be done&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Target the People most likely to need Web Development Services, we recommend targeting decision makers with verified emails at companies with size range of 11 to 100 in industries like Consumer Goods and Consumer Electronics as these people will be in more need of Web Development Service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can easily find people who fit this criteria using omkar cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZEB8YFCq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.omkar.cloud/blog/static/blog/how-to-get-clients-for-your-web-development-agencies/Suggest_Interesting_Ideas_for_Their_Business.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZEB8YFCq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.omkar.cloud/blog/static/blog/how-to-get-clients-for-your-web-development-agencies/Suggest_Interesting_Ideas_for_Their_Business.png" alt="Suggest Interesting Ideas for Their Business.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now you should visit each prospect's exisiting website and send a personalized email thats demonstrates effective steps to make their website better. Following is an excellent example that you can use as a basis for your email
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Subject: Ideas for {{company_name}}

Hi {{first_name}},
Congrats on having a huge following on Facebook. However when I checked your website [Website URL] it does not match the quality of work you guys are doing.

I identified a few areas where quick wins could be achieved:

1. Adding a feature for customers to get notified when products are back in stock.
2. Adding a blog to enhance your SEO efforts.
3. Implementing a contact form for customers to easily reach out with questions.

I have helped [Similar Company] and they saw a significant boost in revenue from it this year.

Are these ideas you've been considering?

Best,
[Your Name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The thing that will really boost response rates is following up with prospect. So Follow with the prospect say 2 Days later in case they didn’t respond. Following is an excellent email template that you can use
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Hey {{first_name}}, I know that you are a busy person. So just wanted to follow up so that this doesn't get lost
Thanks,
[Your Name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reaching Out to Prospects Hiring a Web Developer
&lt;/h2&gt;

&lt;p&gt;If a company which has posted a job vacancy for web development role then their are high chances to convert them into a Customer.&lt;/p&gt;

&lt;p&gt;While some companies want to hire in-house, others are open to discussing the option of working with a web development agency, especially if you can demonstrate that you are a great choice for them.&lt;/p&gt;

&lt;p&gt;Also in case they are adamant about hiring in-house still you can still offer to provide them with a skilled web developer from your agency on a monthly contract basis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's an example of how it can be done:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Target the People who are hiring for Web Development Role, we recommend targeting decision makers with verified emails at companies with size range of 11 to 100 who are hiring for Web Developer, Web Designer, Frontend Developer Role.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can easily find people who fit this criteria using omkar cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bak1nSqD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.omkar.cloud/blog/static/blog/how-to-get-clients-for-your-web-development-agencies/Reaching_Out_to_Prospects_Hiring_a_Web_Developer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bak1nSqD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.omkar.cloud/blog/static/blog/how-to-get-clients-for-your-web-development-agencies/Reaching_Out_to_Prospects_Hiring_a_Web_Developer.png" alt="Reaching Out to Prospects Hiring a Web Developer.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now send a personalized email. Following is an excellent email template that you can use
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Subject: Hiring [Job Title] at [Company Name]?

Hi [Name],
Saw that you’re hiring [Job Title] at [Company Name].

I wanted to see if you’d be interested in our Web Development as a Service offering. You only pay for results you get.

Something you might be interested in?

Best,
[Your Name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;As a best practice send a followup email to increase your response rates. Following is an excellent email template that you can use
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hey {{first_name}}, I know that you are a busy person. So just wanted to follow up so that this doesn't get lost
Thanks,
[Your Name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;That's all there is to getting clients for your web development agencies, these were 2 battle tested strategies you can use and see results for yourself.&lt;/p&gt;

&lt;p&gt;Understand that Knowledge learned but not applied does not bear fruit. So head over to &lt;a href="https://www.omkar.cloud/"&gt;omkar.cloud&lt;/a&gt;, discover your leads, and start shooting emails :)&lt;/p&gt;

&lt;p&gt;Wish you best of luck!&lt;/p&gt;

&lt;p&gt;Dhanyawad 🙏&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
