{"id":738,"date":"2024-10-09T16:02:01","date_gmt":"2024-10-09T14:02:01","guid":{"rendered":"https:\/\/www.syntera.ch\/blog\/?p=738"},"modified":"2024-10-09T16:02:02","modified_gmt":"2024-10-09T14:02:02","slug":"scrape-dynamic-apis-like-a-pro-with-selenium","status":"publish","type":"post","link":"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/","title":{"rendered":"Scrape Dynamic APIs Like a Pro with Selenium"},"content":{"rendered":"<div class=\"wp-block-post-author has-medium-font-size\"><div class=\"wp-block-post-author__avatar\"><img alt='' src='https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=48&#038;d=mm&#038;r=g' srcset='https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&#038;d=mm&#038;r=g 2x' class='avatar avatar-48 photo' height='48' width='48' \/><\/div><div class=\"wp-block-post-author__content\"><p class=\"wp-block-post-author__byline\">LEAD DATA ENGINEERING<\/p><p class=\"wp-block-post-author__name\">Kail Kuhn Schlicht<\/p><\/div><\/div>\n\n\n<p class=\"wp-block-paragraph\">At Syntera, we\u2019re passionate about blending creativity with technology, especially when it comes to automation and data extraction. In this blog post, I\u2019ll show you how to <strong>scrape data from dynamic APIs like a pro<\/strong>, using <strong>Selenium<\/strong> with <strong>Firefox<\/strong>, a simple <strong>Django Ninja<\/strong> API, and a basic <strong>web page<\/strong>. You\u2019ll learn how to automate interactions on a web page, capture data from an API, and save it in a structured format\u2014all without manually parsing messy HTML.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Use Case: Fetching Mountain Passes Data from a Local API<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine you have a web application that provides information about Swiss mountain passes. The app features a button labeled <strong>&#8220;Load Passes&#8221;<\/strong>, which triggers an AJAX request to a <code>\/api\/mountain-passes<\/code> endpoint to fetch the data. Your task is to:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Automate interaction with the web page<\/strong> to click the &#8220;Load Passes&#8221; button.<\/li>\n\n\n\n<li><strong>Capture the returned data<\/strong> from the dynamic API request.<\/li>\n\n\n\n<li><strong>Save the data<\/strong> in a structured format (JSON).<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">This post will guide you through setting up <strong>Django Ninja<\/strong> as a lightweight API for serving the mountain pass data, creating a <strong>sample web page<\/strong>, and then automating the data extraction process with <strong>Selenium<\/strong>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 1: Setting Up the Django Ninja API<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">First, let\u2019s create a simple API using <strong>Django Ninja<\/strong>. Django Ninja is a powerful, fast, and modern web framework that makes it easy to build APIs with minimal code. For this use case, we\u2019ll set up a simple endpoint to return mountain pass information.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can refer to the <a href=\"https:\/\/github.com\/kksyntera\/selenium-blog\/\">GitHub repository<\/a> for the complete code setup for the <strong>Django Ninja<\/strong> API, including the models and endpoints. Here\u2019s a quick overview:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Create a Django project and app<\/strong> named <code>mountains<\/code>.<\/li>\n\n\n\n<li><strong>Set up Django Ninja<\/strong> in the app and define an API endpoint <code>\/api\/mountain-passes<\/code> that returns a list of mountain passes.<\/li>\n\n\n\n<li><strong>Run the Django server locally<\/strong> on <code>http:\/\/127.0.0.1:8000<\/code>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Now, the <strong>Django Ninja<\/strong> API will serve the mountain pass data in JSON format when the <code>\/api\/mountain-passes<\/code> endpoint is accessed.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 2: Creating a Sample Web Page with a &#8220;Load Passes&#8221; Button<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">We need a simple web page that contains a button to trigger the AJAX request to our API. Here\u2019s the HTML code for the sample web page:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Mountain Passes&lt;\/title&gt;\n    &lt;script src=\"https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/3.5.1\/jquery.min.js\"&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;Swiss Mountain Passes&lt;\/h1&gt;\n    &lt;button id=\"load-passes\"&gt;Load Mountain Passes&lt;\/button&gt;\n    &lt;ul id=\"passes-list\"&gt;&lt;\/ul&gt;\n\n    &lt;script&gt;\n        $('#load-passes').on('click', function() {\n            $.ajax({\n                url: '\/api\/mountain-passes',\n                method: 'GET',\n                success: function(data) {\n                    $('#passes-list').empty();\n                    data.forEach(function(pass) {\n                        $('#passes-list').append('&lt;li&gt;' + pass.name + ' - ' + pass.elevation_meters + ' meters (' + pass.location + ')&lt;\/li&gt;');\n                    });\n                },\n                error: function(error) {\n                    console.log(\"Error fetching data:\", error);\n                }\n            });\n        });\n    &lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Explanation of the Sample Web Page:<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>HTML Structure<\/strong>: The page contains a title, a button with the ID <code>load-passes<\/code>, and an unordered list to display the mountain pass data.<\/li>\n\n\n\n<li><strong>AJAX Request<\/strong>: When the button is clicked, a jQuery AJAX request is made to the <code>\/api\/mountain-passes<\/code> endpoint. If the request is successful, the data is displayed in the list. In case of an error, it\u2019s logged to the console.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">To serve this web page, place the file in the <code>static<\/code> directory of your Django project and configure your Django settings to serve static files.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 3: Setting Up Selenium with Firefox<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Now, let\u2019s set up Selenium to automate the interaction with our local web page. We\u2019ll use <strong>Firefox<\/strong> with <strong>GeckoDriver<\/strong>, and the <strong>dotenv<\/strong> library will help us load environment variables for configuration.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>Installing Dependencies<\/strong><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Make sure you have <strong>Selenium<\/strong>, <strong>dotenv<\/strong>, and <strong>GeckoDriver<\/strong> installed. Here\u2019s how to get started (I&#8217;m doing it on a Mac):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install selenium python-dotenv<br>brew install geckodriver<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 4: Writing the Selenium Script<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">We\u2019ll write a Selenium script to automate the following tasks:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Navigate to the web page<\/strong>: <code>http:\/\/127.0.0.1:8000\/mountain-passes\/<\/code><\/li>\n\n\n\n<li><strong>Find the &#8220;Load Passes&#8221; button<\/strong> and click it to trigger the AJAX request.<\/li>\n\n\n\n<li><strong>Capture the data<\/strong> returned from the <code>\/api\/mountain-passes<\/code> endpoint.<\/li>\n\n\n\n<li><strong>Print and save the data<\/strong> in JSON format.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s the complete script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nimport time\nimport json\nfrom dotenv import load_dotenv\nfrom selenium import webdriver\nfrom selenium.webdriver.firefox.service import Service as FirefoxService\nfrom selenium.webdriver.common.by import By\nfrom selenium.webdriver.support.ui import WebDriverWait\nfrom selenium.webdriver.support import expected_conditions as EC\n\n# Load environment variables from the .env file\nload_dotenv()\n\n# Access the paths from the environment variables\nGECKO_DRIVER_PATH = os.getenv('GECKO_DRIVER_PATH')\n\n# Set up Firefox WebDriver\nservice = FirefoxService(GECKO_DRIVER_PATH)\ndriver = webdriver.Firefox(service=service)\n\n# Navigate to the web page\nprint(\"Navigating to the web page...\")\ndriver.get(\"http:\/\/127.0.0.1:8000\/mountain-passes\/\")\n\n# Find the load button and click it\ntry:\n    load_button = WebDriverWait(driver, 10).until(\n        EC.element_to_be_clickable((By.ID, \"load-passes\"))\n    )\n    print(\"Load button is visible and clickable.\")\n\n    # Scroll to the button using JavaScript\n    driver.execute_script(\"arguments&#91;0].scrollIntoView();\", load_button)\n    print(\"Scrolled to the load button.\")\n\n    # Click the button using JavaScript\n    driver.execute_script(\"arguments&#91;0].click();\", load_button)\n    print(\"Load button clicked via JavaScript.\")\nexcept Exception as e:\n    print(f\"Error finding or clicking the button: {e}\")\n\n# Add a sleep to allow the AJAX request to complete\ntime.sleep(5)\n\n# Execute JavaScript to capture the mountain passes data directly from the page\nmountain_passes_data = driver.execute_script(\"\"\"\n    return fetch('\/api\/mountain-passes')\n        .then(response =&gt; response.json())\n        .then(data =&gt; data);\n\"\"\")\n\n# Close the browser\ndriver.quit()\n\n# Print the captured data as JSON\nprint(\"Mountain Passes Data (JSON Format):\")\nprint(json.dumps(mountain_passes_data, indent=4))\n\n# Save the data to a JSON file\nwith open('mountain_passes_data.json', 'w') as json_file:\n    json.dump(mountain_passes_data, json_file, indent=4)\n\nprint(\"Mountain passes data has been saved to 'mountain_passes_data.json'.\")<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Step 5: Why This Approach?<\/strong> <strong>The Advantages of Scraping Dynamic APIs Over Traditional HTML Scraping<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Scraping dynamic APIs is often more effective than parsing static HTML, especially for modern websites where content is loaded asynchronously. Here\u2019s why:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Clean Data Extraction<\/strong>: APIs return structured data (e.g., JSON) directly, eliminating the need for parsing complex HTML.<\/li>\n\n\n\n<li><strong>Handling Dynamic Content<\/strong>: This approach easily captures data from web pages that load content with JavaScript.<\/li>\n\n\n\n<li><strong>Reduced Risk of Breakage<\/strong>: API endpoints are usually more stable than the website\u2019s HTML structure.<\/li>\n\n\n\n<li><strong>Automating User Actions<\/strong>: Selenium enables automating interactions such as button clicks, which isn\u2019t possible with traditional scraping.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I\u2019ve demonstrated how to <strong>scrape data from a dynamic API<\/strong> using <strong>Selenium<\/strong>, <strong>Django Ninja<\/strong>, and a basic <strong>sample web page<\/strong>. This method streamlines the data extraction process by leveraging API endpoints instead of parsing static HTML, making it ideal for modern web applications.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Explore the <a href=\"https:\/\/github.com\/kksyntera\/selenium-blog\/\">GitHub repository<\/a> for the complete code setup, and feel free to reach out with questions or ideas for future projects!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>At Syntera, we\u2019re passionate about blending creativity with technology, especially when it comes to automation and data extraction. In this blog post, I\u2019ll show you how to scrape data from dynamic APIs like a pro, using Selenium with Firefox, a simple Django Ninja API, and a basic web page. You\u2019ll learn how to automate interactions [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":748,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-738","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-allgemein"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Scrape Dynamic APIs Like a Pro with Selenium - Syntera<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Scrape Dynamic APIs Like a Pro with Selenium - Syntera\" \/>\n<meta property=\"og:description\" content=\"At Syntera, we\u2019re passionate about blending creativity with technology, especially when it comes to automation and data extraction. In this blog post, I\u2019ll show you how to scrape data from dynamic APIs like a pro, using Selenium with Firefox, a simple Django Ninja API, and a basic web page. You\u2019ll learn how to automate interactions [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/\" \/>\n<meta property=\"og:site_name\" content=\"Syntera\" \/>\n<meta property=\"article:published_time\" content=\"2024-10-09T14:02:01+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-09T14:02:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.syntera.ch\/blog\/wp-content\/uploads\/2024\/10\/banner-selenium.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"750\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Kail Kuhn Schlicht\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kail Kuhn Schlicht\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/\",\"url\":\"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/\",\"name\":\"Scrape Dynamic APIs Like a Pro with Selenium - Syntera\",\"isPartOf\":{\"@id\":\"https:\/\/www.syntera.ch\/blog\/#website\"},\"datePublished\":\"2024-10-09T14:02:01+00:00\",\"dateModified\":\"2024-10-09T14:02:02+00:00\",\"author\":{\"@id\":\"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/8048dfb9e4b2f044222a4baa11ee3e68\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.syntera.ch\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Scrape Dynamic APIs Like a Pro with Selenium\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/#website\",\"url\":\"https:\/\/www.syntera.ch\/blog\/\",\"name\":\"Syntera\",\"description\":\"translating data into business value.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.syntera.ch\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/8048dfb9e4b2f044222a4baa11ee3e68\",\"name\":\"Kail Kuhn Schlicht\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&d=mm&r=g\",\"caption\":\"Kail Kuhn Schlicht\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/kail-kuhn-schlicht-603584a3\/\"],\"url\":\"https:\/\/www.syntera.ch\/blog\/author\/kail\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Scrape Dynamic APIs Like a Pro with Selenium - Syntera","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/","og_locale":"en_US","og_type":"article","og_title":"Scrape Dynamic APIs Like a Pro with Selenium - Syntera","og_description":"At Syntera, we\u2019re passionate about blending creativity with technology, especially when it comes to automation and data extraction. In this blog post, I\u2019ll show you how to scrape data from dynamic APIs like a pro, using Selenium with Firefox, a simple Django Ninja API, and a basic web page. You\u2019ll learn how to automate interactions [&hellip;]","og_url":"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/","og_site_name":"Syntera","article_published_time":"2024-10-09T14:02:01+00:00","article_modified_time":"2024-10-09T14:02:02+00:00","og_image":[{"width":2000,"height":750,"url":"https:\/\/www.syntera.ch\/blog\/wp-content\/uploads\/2024\/10\/banner-selenium.png","type":"image\/png"}],"author":"Kail Kuhn Schlicht","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Kail Kuhn Schlicht","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/","url":"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/","name":"Scrape Dynamic APIs Like a Pro with Selenium - Syntera","isPartOf":{"@id":"https:\/\/www.syntera.ch\/blog\/#website"},"datePublished":"2024-10-09T14:02:01+00:00","dateModified":"2024-10-09T14:02:02+00:00","author":{"@id":"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/8048dfb9e4b2f044222a4baa11ee3e68"},"breadcrumb":{"@id":"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.syntera.ch\/blog\/2024\/10\/09\/scrape-dynamic-apis-like-a-pro-with-selenium\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.syntera.ch\/blog\/"},{"@type":"ListItem","position":2,"name":"Scrape Dynamic APIs Like a Pro with Selenium"}]},{"@type":"WebSite","@id":"https:\/\/www.syntera.ch\/blog\/#website","url":"https:\/\/www.syntera.ch\/blog\/","name":"Syntera","description":"translating data into business value.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.syntera.ch\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/8048dfb9e4b2f044222a4baa11ee3e68","name":"Kail Kuhn Schlicht","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&d=mm&r=g","caption":"Kail Kuhn Schlicht"},"sameAs":["https:\/\/www.linkedin.com\/in\/kail-kuhn-schlicht-603584a3\/"],"url":"https:\/\/www.syntera.ch\/blog\/author\/kail\/"}]}},"_links":{"self":[{"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/posts\/738","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/comments?post=738"}],"version-history":[{"count":6,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/posts\/738\/revisions"}],"predecessor-version":[{"id":778,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/posts\/738\/revisions\/778"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/media\/748"}],"wp:attachment":[{"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/media?parent=738"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/categories?post=738"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/tags?post=738"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}