{"id":225,"date":"2014-05-01T05:31:58","date_gmt":"2014-05-01T09:31:58","guid":{"rendered":"http:\/\/qxf2.com\/blog\/?p=225"},"modified":"2017-06-14T02:12:33","modified_gmt":"2017-06-14T06:12:33","slug":"python-mechanize-the-missing-manual","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/python-mechanize-the-missing-manual\/","title":{"rendered":"Python Mechanize &#8211; the missing manual"},"content":{"rendered":"<p><strong>Problem:<\/strong> The online documentation for Mechanize in Python is lacking. Case in point, <a href=\"http:\/\/stackoverflow.com\/questions\/13810547\/http-put-method-in-python-mechanize\">this question on stackoverflow<\/a> remained unanswered until we added the answer. This post hopes to provide you with the key missing pieces.<\/p>\n<p>We love Python at <a href=\"http:\/\/www.qxf2.com\/?utm_source=mechanize&#038;utm_medium=click&#038;utm_campaign=From%20blog\">Qxf2 Services<\/a>. We chose the Mechanize module to test REST services and automate a lot of our test setup tasks by using REST end points that are used in the products. One of the BIG drawbacks of using the Python module Mechanize is the sparse online support. Let&#8217;s hope this post begins to change that. <\/p>\n<hr>\n<p><strong>1. How to encode parameters in Python<\/strong><\/p>\n<pre lang=\"python\">\r\n#Parameters can be URL encoded like this:\r\nmy_params={key1:'value1',key2:'value2'} \r\nmy_params_encoded = urllib.urlencode(my_params)\r\n<\/pre>\n<pre lang=\"python\">\r\n#For JSON parameters do this:\r\nmy_params={key1:'value1',key2:'value2'} \r\nmy_params_encoded = json.dumps(my_params)\r\n<\/pre>\n<p><strong>2. How to do a HTTP GET with Mechanize and Python<\/strong><br \/>\nMechanize supports HTTP GET and POST methods out of the box.<\/p>\n<pre lang=\"python\">\r\nurl = \"your desired url\"\r\n#NOTE: browser is the instance of mechanize.Browser()\r\nbrowser.open(mechanize.Request(url,data=my_params_encoded,headers={\"Content-type\":\"application\/json\"}))\r\n<\/pre>\n<p>Bonus: We just showed you how to make a request with an application\/json header<\/p>\n<p><strong>3. How to do a HTTP PUT with Mechanize and Python<\/strong><br \/>\nMechanize (the Python module) supports only HTTP GET and POST methods out of the box.  We arrived at this solution by digging into the mechanize code packages to find out where mechanize was setting the HTTP method. We noticed that when we call mechanize.Request, we are using the Request class in _request.py which in turn is extending the Request class in _urllib2_fork.py. The http method is actually set in get_method of the Request class in _urllib2_fork.py. Turns out get_method in _urllib2_fork.py was allowing only GET and POST methods. To get past this limitation, we ended up writing my own put and delete classes that extended mechanize. Request but over-rode get_method() only. <\/p>\n<pre lang=\"python\">\r\nclass PutRequest(mechanize.Request):\r\n    \"Extend the mechanize Request class to allow a http PUT\"\r\n    def get_method(self):\r\n        return \"PUT\"\r\n\r\n\r\n#NOTE: browser is the instance of mechanize.Browser()\r\nbrowser.open(PutRequest(url,data=sub_level_params_encoded,headers={\"Content-type\":\"application\/json\"}))\r\n<\/pre>\n<p><strong>4. How to do a HTTP DELETE with Mechanize and Python<\/strong><\/p>\n<pre lang=\"python\">\r\nclass DeleteRequest(mechanize.Request):\r\n    \"Extend the mechanize Request class to allow a http DELETE\"\r\n    def get_method(self):\r\n        return \"DELETE\"\r\n\r\n\r\n#NOTE: browser is the instance of mechanize.Browser()\r\nbrowser.open(DeleteRequest(url))\r\n<\/pre>\n<hr>\n<p><strong>Other useful links to learn Mechanize+Python:<\/strong><br \/>\n1. If you are new to Mechanize, use <a href=\"http:\/\/stockrt.github.io\/p\/emulating-a-browser-in-python-with-mechanize\/\">this link<\/a><br \/>\n2. Using <a href=\"https:\/\/qxf2.com\/blog\/?p=164\">Mechanize to login to CAS<\/a> <\/p>\n<p>If you have questions regarding any of these solutions, drop a comment below. <a href=\"http:\/\/www.qxf2.com\/?utm_source=mechanize&#038;utm_medium=click&#038;utm_campaign=From%20blog\">Qxf2<\/a> like helping testers!<\/p>\n<hr>\n<p><strong>WARNING:<\/strong> Mechanize has its limitations as an automated testing tool. The biggest drawback for web testers is that Mechanize does not mimic rendering of executed JavaScript in the browser. So DOM elements that are rendered by executing JavaScript cannot be accessed by Mechanize.<\/p>\n<hr>\n<script>(function() {\n\twindow.mc4wp = window.mc4wp || {\n\t\tlisteners: [],\n\t\tforms: {\n\t\t\ton: function(evt, cb) {\n\t\t\t\twindow.mc4wp.listeners.push(\n\t\t\t\t\t{\n\t\t\t\t\t\tevent   : evt,\n\t\t\t\t\t\tcallback: cb\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n})();\n<\/script><!-- Mailchimp for WordPress v4.10.1 - https:\/\/wordpress.org\/plugins\/mailchimp-for-wp\/ --><form id=\"mc4wp-form-1\" class=\"mc4wp-form mc4wp-form-6165 mc4wp-form-theme mc4wp-form-theme-blue\" method=\"post\" data-id=\"6165\" data-name=\"Newsletter\" ><div class=\"mc4wp-form-fields\"><div style=\"border:3px; border-style:dashed;border-color:#56d1e1;padding:1.2em;\">\r\n  <h1 style=\"text-align: center; padding-top: 20px; padding-bottom: 20px; color: #592b1b;\">Subscribe to our weekly Newsletter<\/h1>\r\n  <input style=\"margin: auto;\" type=\"email\" name=\"EMAIL\" placeholder=\"Your email address\" required \/>\r\n  <br>\r\n  <p style=\"text-align: center;\">\r\n    <input style=\"background-color: #890c06 !important; border-color: #890c06;\" type=\"submit\" value=\"Sign up\" \/>\r\n    \r\n  <\/p>\r\n  <p style=\"text-align: center;\">\r\n    <a href=\"http:\/\/mailchi.mp\/c9c7b81ddf13\/the-informed-testers-newsletter-20-oct-2017\"><small>View a sample<\/small><\/a>\r\n  <\/p>\r\n  <br>\r\n<\/div><\/div><label style=\"display: none !important;\">Leave this field empty if you're human: <input type=\"text\" name=\"_mc4wp_honeypot\" value=\"\" tabindex=\"-1\" autocomplete=\"off\" \/><\/label><input type=\"hidden\" name=\"_mc4wp_timestamp\" value=\"1777537115\" \/><input type=\"hidden\" name=\"_mc4wp_form_id\" value=\"6165\" \/><input type=\"hidden\" name=\"_mc4wp_form_element_id\" value=\"mc4wp-form-1\" \/><div class=\"mc4wp-response\"><\/div><\/form><!-- \/ Mailchimp for WordPress Plugin -->\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>Problem: The online documentation for Mechanize in Python is lacking. Case in point, this question on stackoverflow remained unanswered until we added the answer. This post hopes to provide you with the key missing pieces. We love Python at Qxf2 Services. We chose the Mechanize module to test REST services and automate a lot of our test setup tasks by [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,26,18],"tags":[25,24,27],"class_list":["post-225","post","type-post","status-publish","format-standard","hentry","category-how-to","category-mechanize-2","category-python","tag-mechanize","tag-python-2","tag-rest"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/225","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=225"}],"version-history":[{"count":23,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/225\/revisions"}],"predecessor-version":[{"id":6247,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/225\/revisions\/6247"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=225"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=225"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=225"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}