首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用WWW::Mechanize登录

使用WWW::Mechanize登录
EN

Stack Overflow用户
提问于 2020-07-09 03:01:29
回答 4查看 220关注 0票数 4

我正在考虑使用以下内容登录到https://imputationserver.sph.umich.edu/index.html#!pages/login

代码语言:javascript
复制
#!/usr/bin/env perl

use strict;
use warnings FATAL => 'all';
use feature 'say';
use autodie ':all';
use WWW::Mechanize;
use DDP;

my $mech = WWW::Mechanize->new();
$mech->get( 'https://imputationserver.sph.umich.edu/index.html#!pages/login' );
my $username = '';
my $password = '';
#$mech->set_visible( $username, $password );
#$mech -> field('Username:', $username);
#$mech -> field('Password:', $password);

my %data;
@{ $data{links} } = $mech -> find_all_links();
@{ $data{inputs}    } = $mech -> find_all_inputs();
@{ $data{submits} } = $mech ->find_all_submits();
@{ $data{forms} } = $mech -> forms();
p %data;

#$mech->set_fields('Username' => $username, 'Password' => $password);

但似乎没有任何有用的信息,这是通过打印显示的:

代码语言:javascript
复制
{
    forms     [],
    inputs    [],
    links     [
        [0] WWW::Mechanize::Link  {
            public methods (9) : attrs, base, name, new, tag, text, URI, url, url_abs
            private methods (0)
            internals: [
                [0] "favicon.ico",
                [1] undef,
                [2] undef,
                [3] "link",
                [4] URI::https,
                [5] {
                    href   "favicon.ico",
                    rel    "icon"
                }
            ]
        },
        [1] WWW::Mechanize::Link  {
            public methods (9) : attrs, base, name, new, tag, text, URI, url, url_abs
            private methods (0)
            internals: [
                [0] "assets/css/loader.css",
                [1] undef,
                [2] undef,
                [3] "link",
                [4] var{links}[0][4],
                [5] {
                    href   "assets/css/loader.css",
                    rel    "stylesheet"
                }
            ]
        }
    ],
    submits   []
}

我查看了火狐的工具->页面信息,但没有找到任何有价值的东西,我不知道用户名和密码是从哪里来的。

我试过了

代码语言:javascript
复制
$mech -> submit_form(
    form_number => 0,
    fields      => { username => $username, password => $password },
);

但后来我得到了No form defined

在链接、输入、字段方面,我看不到任何内容,也不知道如何继续。

在这种情况下,我在https://metacpan.org/pod/WWW::Mechanize::Examples上看不到任何对我有帮助的东西。

如何使用Perl的WWW::Mechanize登录到此页面?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-07-09 04:27:20

来自该页面的源代码中有趣的部分是:

代码语言:javascript
复制
<body class="bg-light">

  <div id="main">
    <div class="spinner">
        <div class="bounce1"></div>
      <div class="bounce2"></div>
      <div class="bounce3"></div>
    </div>
  </div>

  <script src="./dist/bundles/cloudgene/index.js"></script>


</body>

因此,在构成该页面的HTML中没有登录表单。这就解释了为什么WWW::Mechanize看不到任何东西--没有什么可看的。

这个页面似乎都是由Javascript文件-- index.js构建的。

现在,您可以花几个小时阅读JS,了解页面的工作原理。但这将是一项艰巨的工作,而且有一种更容易的方法。

无论客户端(浏览器或您的代码)如何工作,实际的登录都必须由HTTP请求和响应处理。客户端发送请求,服务器响应,客户端对该响应执行操作。你只需要弄清楚请求和响应是什么样子,然后在你的代码中重现它。

你可以使用浏览器中内置的工具来检查HTTP请求和响应(在Chrome中,它是点菜单-> more tools -> developer tools)。这将使您能够确切地看到HTTP请求的样子。

完成此操作后,您“只需要”使用Perl代码创建一个类似的响应。您可能会发现,使用LWP::UserAgent及其相关模块比使用WWW::Mechanize更容易。

票数 5
EN

Stack Overflow用户

发布于 2020-07-09 05:55:13

正如Dave所说,许多现代网站将通过Javascript驱动的(私有) API来处理登录。您需要在浏览器中打开Network选项卡,像往常一样手动登录,并观察GET、PUT、POST等的序列,以了解完成登录需要哪些交互,然后使用MechLWP自己执行该序列。

页面上的Javascript可能会创建JSON甚至JWTs来进行交互;您必须在代码中复制它才能工作。

特别是,检查cookies的头部,以及设置的身份验证和CSRF令牌;您需要捕获这些内容并通过请求重新发送它们(POST请求将需要CSRF令牌)。这可能需要与站点进行更多的交互,以捕获操作序列并复制它们。HTTP::Cookies应该会自动为您处理cookies,但更复杂的报头使用将要求您使用HTTP::Headers提取数据,并可能以这种方式重新提交数据。

从本质上讲,这些过程都非常简单;只需要准确地复制它们,以便您可以将它们自动化即可。

您应该检查站点是否已经有程序员的API,如果有,就使用它;这样的API几乎总是为您提供更简单、直接的站点函数接口和更易于使用的返回数据格式。如果站点是高度动态的,比如一个繁重的React站点,那么站点中的其他页面可能会加载一个框架HTML页面,然后使用Javascript来填充它;随着页面的发展,您的代码也将不得不这样做。如果您使用的是已定义的程序员的API,那么只要API版本不变,您就可能能够依赖于交互和返回的数据保持不变。

最后要注意的是:您应该验证您没有通过使用自动化来违反您的用户协议。一些网站明确禁止使用自动登录方法。

票数 6
EN

Stack Overflow用户

发布于 2020-07-09 04:41:09

Mechanize是一个具有一些HTML解析功能的web客户端。但正如Dave Cross指出的那样,您想要的表单并不在您请求的HTML文档中。它是由一些JavaScript代码生成的。要做浏览器所做的事情,需要一个JavaScript引擎,而WWW::Mechanize没有。

实现这一目标的最简单方法是远程控制web浏览器(例如,使用Selenium::Chrome)。

另一种方法是在不获取和填写表单的情况下手动创建登录请求。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62801891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档