{
    "content": [
        {
            "type": "text",
            "text": "# WWW::Mechanize::FAQ (info)\n\n## NAME\n\nWWW::Mechanize::FAQ - Frequently Asked Questions about WWW::Mechanize\n\n## Sections\n\n- **NAME**\n- **VERSION**\n- **How to get help with WWW::Mechanize**\n- **JavaScript**\n- **Why doesn't this work: Debugging your Mechanize program**\n- **AUTHOR**\n- **COPYRIGHT AND LICENSE**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "WWW::Mechanize::FAQ",
        "section": "",
        "mode": "info",
        "summary": "WWW::Mechanize::FAQ - Frequently Asked Questions about WWW::Mechanize",
        "synopsis": null,
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "VERSION",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "How to get help with WWW::Mechanize",
                "lines": 12,
                "subsections": []
            },
            {
                "name": "JavaScript",
                "lines": 210,
                "subsections": []
            },
            {
                "name": "Why doesn't this work: Debugging your Mechanize program",
                "lines": 174,
                "subsections": []
            },
            {
                "name": "AUTHOR",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "COPYRIGHT AND LICENSE",
                "lines": 6,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "WWW::Mechanize::FAQ - Frequently Asked Questions about WWW::Mechanize\n",
                "subsections": []
            },
            "VERSION": {
                "content": "version 2.06\n",
                "subsections": []
            },
            "How to get help with WWW::Mechanize": {
                "content": "If your question isn't answered here in the FAQ, please turn to the\ncommunities at:\n\no   StackOverflow\n<https://stackoverflow.com/questions/tagged/www-mechanize>\n\no   #lwp on irc.perl.org\n\no   <http://perlmonks.org>\n\no   The libwww-perl mailing list at <http://lists.perl.org>\n",
                "subsections": []
            },
            "JavaScript": {
                "content": "I have this web page that has JavaScript on it, and my Mech program doesn't\nwork.\nThat's because WWW::Mechanize doesn't operate on the JavaScript.  It\nonly understands the HTML parts of the page.\n\nI thought Mech was supposed to work like a web browser.\nIt does pretty much, but it doesn't support JavaScript.\n\nI added some basic attempts at picking up URLs in \"window.open()\" calls\nand return them in \"$mech->links\".  They work sometimes.\n\nSince Javascript is completely visible to the client, it cannot be used\nto prevent a scraper from following links. But it can make life\ndifficult. If you want to scrape specific pages, then a solution is\nalways possible.\n\nOne typical use of Javascript is to perform argument checking before\nposting to the server. The URL you want is probably just buried in the\nJavascript function. Do a regular expression match on\n\"$mech->content()\" to find the link that you want and \"$mech->get\" it\ndirectly (this assumes that you know what you are looking for in\nadvance).\n\nIn more difficult cases, the Javascript is used for URL mangling to\nsatisfy the needs of some middleware. In this case you need to figure\nout what the Javascript is doing (why are these URLs always really\nlong?). There is probably some function with one or more arguments\nwhich calculates the new URL. Step one: using your favorite browser,\nget the before and after URLs and save them to files. Edit each file,\nconverting the argument separators ('?', '&' or ';') into newlines. Now\nit is easy to use diff or comm to find out what Javascript did to the\nURL.  Step 2 - find the function call which created the URL - you will\nneed to parse and interpret its argument list. The Javascript Debugger\nin the Firebug extension for Firefox helps with the analysis. At this\npoint, it is fairly trivial to write your own function which emulates\nthe Javascript for the pages you want to process.\n\nHere's another approach that answers the question, \"It works in\nFirefox, but why not Mech?\"  Everything the web server knows about the\nclient is present in the HTTP request. If two requests are identical,\nthe results should be identical. So the real question is \"What is\ndifferent between the mech request and the Firefox request?\"\n\nThe Firefox extension \"Tamper Data\" is an effective tool for examining\nthe headers of the requests to the server. Compare that with what LWP\nis sending. Once the two are identical, the action of the server should\nbe the same as well.\n\nI say \"should\", because this is an oversimplification - some values are\nnaturally unique, e.g. a SessionID, but if a SessionID is present, that\nis probably sufficient, even though the value will be different between\nthe LWP request and the Firefox request. The server could use the\nsession to store information which is troublesome, but that's not the\nfirst place to look (and highly unlikely to be relevant when you are\nrequesting the login page of your site).\n\nGenerally the problem is to be found in missing or incorrect POSTDATA\narguments, Cookies, User-Agents, Accepts, etc. If you are using mech,\nthen redirects and cookies should not be a problem, but are listed here\nfor completeness. If you are missing headers, \"$mech->addheader\" can\nbe used to add the headers that you need.\n\nWhich modules work like Mechanize and have JavaScript support?\nIn no particular order: Gtk2::WebKit::Mechanize, Win32::IE::Mechanize,\nWWW::Mechanize::Firefox, WWW::Scripter, WWW::Selenium\n\nHow do I do X?\nCan I do [such-and-such] with WWW::Mechanize?\nIf it's possible with LWP::UserAgent, then yes.  WWW::Mechanize is a\nsubclass of LWP::UserAgent, so all the wondrous magic of that class is\ninherited.\n\nHow do I use WWW::Mechanize through a proxy server?\nSee the docs in LWP::UserAgent on how to use the proxy.  Short version:\n\n$mech->proxy(['http', 'ftp'], 'http://proxy.example.com:8000/');\n\nor get the specs from the environment:\n\n$mech->envproxy();\n\n# Environment set like so:\ngopherproxy=http://proxy.my.place/\nwaisproxy=http://proxy.my.place/\nnoproxy=\"localhost,my.domain\"\nexport gopherproxy waisproxy noproxy\n\nHow can I see what fields are on the forms?\nUse the mech-dump utility, optionally installed with Mechanize.\n\n$ mech-dump --forms http://search.cpan.org\nDumping forms\nGET http://search.cpan.org/search\nquery=\nmode=all                        (option)  [*all|module|dist|author]\n<NONAME>=CPAN Search            (submit)\n\nHow do I get Mech to handle authentication?\nuse MIME::Base64;\n\nmy $agent = WWW::Mechanize->new();\nmy @args = (\nAuthorization => \"Basic \" .\nMIME::Base64::encode( USER . ':' . PASS )\n);\n\n$agent->credentials( ADDRESS, REALM, USER, PASS );\n$agent->get( URL, @args );\n\nIf you want to use the credentials for all future requests, you can\nalso use the LWP::UserAgent \"defaultheader()\" method instead of the\nextra arguments to \"get()\"\n\n$mech->defaultheader(\nAuthorization => 'Basic ' . encodebase64( USER . ':' . PASSWORD ) );\n\nHow can I get WWW::Mechanize to execute this JavaScript?\nYou can't.  JavaScript is entirely client-based, and WWW::Mechanize is\na client that doesn't understand JavaScript.  See the top part of this\nFAQ.\n\nHow do I check a checkbox that doesn't have a value defined?\nSet it to the value of \"on\".\n\n$mech->field( mycheckbox => 'on' );\n\nHow do I handle frames?\nYou don't deal with them as frames, per se, but as links.  Extract them\nwith\n\nmy @framelinks = $mech->findlink( tag => \"frame\" );\n\nHow do I get a list of HTTP headers and their values?\nAll HTTP::Headers methods work on a HTTP::Response object which is\nreturned by the get(), reload(), response()/res(), click(),\nsubmitform(), and request() methods.\n\nmy $mech = WWW::Mechanize->new( autocheck => 1 );\n$mech->get( 'http://my.site.com' );\nmy $response = $mech->response();\nfor my $key ( $response->headerfieldnames() ) {\nprint $key, \" : \", $response->header( $key ), \"\\n\";\n}\n\nHow do I enable keep-alive?\nSince WWW::Mechanize is a subclass of LWP::UserAgent, you can use the\nsame mechanism to enable keep-alive:\n\nuse LWP::ConnCache;\n...\n$mech->conncache(LWP::ConnCache->new);\n\nHow can I change/specify the action parameter of an HTML form?\nYou can access the action of the form by utilizing the HTML::Form\nobject returned from one of the specifying form methods.\n\nUsing \"$mech->formnumber($number)\":\n\nmy $mech = WWW::mechanize->new;\n$mech->get('http://someurlhere.com');\n# Access the form using its Zero-Based Index by DOM order\n$mech->formnumber(0)->action('http://newAction'); #ABS URL\n\nUsing \"$mech->formname($number)\":\n\nmy $mech = WWW::mechanize->new;\n$mech->get('http://someurlhere.com');\n#Access the form using its Zero-Based Index by DOM order\n$mech->formname('trgForm')->action('http://newAction'); #ABS URL\n\nHow do I save an image?  How do I save a large tarball?\nAn image is just content.  You get the image and save it.\n\n$mech->get( 'photo.jpg' );\n$mech->savecontent( '/path/to/my/directory/photo.jpg' );\n\nYou can also save any content directly to disk using the\n\":contentfile\" flag to \"get()\", which is part of LWP::UserAgent.\n\n$mech->get( 'http://www.cpan.org/src/stable.tar.gz',\n':contentfile' => 'stable.tar.gz' );\n\nHow do I pick a specific value from a \"<select>\" list?\nFind the \"HTML::Form::ListInput\" in the page.\n\nmy ($listbox) = $mech->findallinputs( name => 'listbox' );\n\nThen create a hash for the lookup:\n\nmy %namelookup;\n@namelookup{ $listbox->valuenames } = $listbox->possiblevalues;\nmy $value = $namelookup{ 'Name I want' };\n\nIf you have duplicate names, this method won't work, and you'll have to\nloop over \"$listbox->valuenames\" and \"$listbox->possiblevalues\" in\nparallel until you find a matching name.\n\nHow do I get Mech to not follow redirects?\nYou use functionality in LWP::UserAgent, not Mech itself.\n\n$mech->requestsredirectable( [] );\n\nOr you can set \"maxredirect\":\n\n$mech->maxredirect( 0 );\n\nBoth these options can also be set in the constructor.  Mech doesn't\nunderstand them, so will pass them through to the LWP::UserAgent\nconstructor.\n",
                "subsections": []
            },
            "Why doesn't this work: Debugging your Mechanize program": {
                "content": "My Mech program doesn't work, but it works in the browser.\nMechanize acts like a browser, but apparently something you're doing is\nnot matching the browser's behavior.  Maybe it's expecting a certain\nweb client, or maybe you've not handling a field properly.  For some\nreason, your Mech problem isn't doing exactly what the browser is\ndoing, and when you find that, you'll have the answer.\n\nMy Mech program gets these 500 errors.\nA 500 error from the web server says that the program on the server\nside died.  Probably the web server program was expecting certain\ninputs that you didn't supply, and instead of handling it nicely, the\nprogram died.\n\nWhatever the cause of the 500 error, if it works in the browser, but\nnot in your Mech program, you're not acting like the browser.  See the\nprevious question.\n\nWhy doesn't my program handle this form correctly?\nRun mech-dump on your page and see what it says.\n\nmech-dump is a marvelous diagnostic tool for figuring out what forms\nand fields are on the page.  Say you're scraping CNN.com, you'd get\nthis:\n\n$ mech-dump http://www.cnn.com/\nGET http://search.cnn.com/cnn/search\nsource=cnn                     (hidden readonly)\ninvocationType=search/top      (hidden readonly)\nsites=web                      (radio)    [*web/The Web ??|cnn/CNN.com ??]\nquery=                         (text)\n<NONAME>=Search                (submit)\n\nPOST http://cgi.money.cnn.com/servlets/quoteredirect\nquery=                         (text)\n<NONAME>=GET                   (submit)\n\nPOST http://polls.cnn.com/poll\npollid=2112                   (hidden readonly)\nquestion1=<UNDEF>             (radio)    [1/Simplistic option|2/VIEW RESULTS]\n<NONAME>=VOTE                  (submit)\n\nGET http://search.cnn.com/cnn/search\nsource=cnn                     (hidden readonly)\ninvocationType=search/bottom   (hidden readonly)\nsites=web                      (radio)    [*web/??CNN.com|cnn/??]\nquery=                         (text)\n<NONAME>=Search                (submit)\n\nFour forms, including the first one duplicated at the end.  All the\nfields, all their defaults, lovingly generated by HTML::Form's \"dump\"\nmethod.\n\nIf you want to run mech-dump on something that doesn't lend itself to a\nquick URL fetch, then use the \"savecontent()\" method to write the HTML\nto a file, and run mech-dump on the file.\n\nWhy don't https:// URLs work?\nYou need either IO::Socket::SSL or Crypt::SSLeay installed.\n\nWhy do I get \"Input 'fieldname' is readonly\"?\nYou're trying to change the value of a hidden field and you have\nwarnings on.\n\nFirst, make sure that you actually mean to change the field that you're\nchanging, and that you don't have a typo.  Usually, hidden variables\nare set by the site you're working on for a reason.  If you change the\nvalue, you might be breaking some functionality by faking it out.\n\nIf you really do want to change a hidden value, make the changes in a\nscope that has warnings turned off:\n\n{\nlocal $^W = 0;\n$agent->field( name => $value );\n}\n\nI tried to [such-and-such] and I got this weird error.\nAre you checking your errors?\n\nAre you sure?\n\nAre you checking that your action succeeded after every action?\n\nAre you sure?\n\nFor example, if you try this:\n\n$mech->get( \"http://my.site.com\" );\n$mech->followlink( \"foo\" );\n\nand the \"get\" call fails for some reason, then the Mech internals will\nbe unusable for the \"followlink\" and you'll get a weird error.  You\nmust, after every action that GETs or POSTs a page, check that Mech\nsucceeded, or all bets are off.\n\n$mech->get( \"http://my.site.com\" );\ndie \"Can't even get the home page: \", $mech->response->statusline\nunless $mech->success;\n\n$mech->followlink( \"foo\" );\ndie \"Foo link failed: \", $mech->response->statusline\nunless $mech->success;\n\nHow do I figure out why \"$mech->get($url)\" doesn't work?\nThere are many reasons why a \"get()\" can fail. The server can take you\nto someplace you didn't expect. It can generate redirects which are not\nproperly handled. You can get time-outs. Servers are down more often\nthan you think! etc, etc, etc. A couple of places to start:\n\n1 Check \"$mech->status()\" after each call\n2 Check the URL with \"$mech->uri()\" to see where you ended up\n3 Try debugging with \"LWP::ConsoleLogger\".\n\nIf things are really strange, turn on debugging with \"use\nLWP::ConsoleLogger::Everywhere;\" Just put this in the main program.\nThis causes LWP to print out a trace of the HTTP traffic between client\nand server and can be used to figure out what is happening at the\nprotocol level.\n\nIt is also useful to set many traps to verify that processing is\nproceeding as expected. A Mech program should always have an \"I didn't\nexpect to get here\" or \"I don't recognize the page that I am\nprocessing\" case and bail out.\n\nSince errors can be transient, by the time you notice that the error\nhas occurred, it might not be possible to reproduce it manually. So for\nautomated processing it is useful to email yourself the following\ninformation:\n\no   where processing is taking place\n\no   An Error Message\n\no   $mech->uri\n\no   $mech->content\n\nYou can also save the content of the page with \"$mech->savecontent(\n'filename.html' );\"\n\nI submitted a form, but the server ignored everything!  I got an empty form\nback!\nThe post is handled by application software. It is common for PHP\nprogrammers to use the same file both to display a form and to process\nthe arguments returned. So the first task of the application programmer\nis to decide whether there are arguments to processes. The program can\ncheck whether a particular parameter has been set, whether a hidden\nparameter has been set, or whether the submit button has been clicked.\n(There are probably other ways that I haven't thought of).\n\nIn any case, if your form is not setting the parameter (e.g. the submit\nbutton) which the web application is keying on (and as an outsider\nthere is no way to know what it is keying on), it will not notice that\nthe form has been submitted. Try using \"$mech->click()\" instead of\n\"$mech->submit()\" or vice-versa.\n\nI've logged in to the server, but I get 500 errors when I try to get to\nprotected content.\nSome web sites use distributed databases for their processing. It can\ntake a few seconds for the login/session information to percolate\nthrough to all the servers. For human users with their slow reaction\ntimes, this is not a problem, but a Perl script can outrun the server.\nSo try adding a sleep(5) between logging in and actually doing anything\n(the optimal delay must be determined experimentally).\n\nMech is a big memory pig!  I'm running out of RAM!\nMech keeps a history of every page, and the state it was in.  It\nactually keeps a clone of the full Mech object at every step along the\nway.\n\nYou can limit this stack size with the \"stackdepth\" param in the\n\"new()\" constructor.  If you set stacksize to 0, Mech will not keep\nany history.\n",
                "subsections": []
            },
            "AUTHOR": {
                "content": "Andy Lester <andy at petdance.com>\n",
                "subsections": []
            },
            "COPYRIGHT AND LICENSE": {
                "content": "This software is copyright (c) 2004 by Andy Lester.\n\nThis is free software; you can redistribute it and/or modify it under\nthe same terms as the Perl 5 programming language system itself.\n\nperl v5.32.1                      2021-10-30          WWW::Mechanize::FAQ(3pm)",
                "subsections": []
            }
        }
    }
}