【问题标题】:Automatically filling out web forms and returning the resulting page自动填写网络表单并返回结果页面
【发布时间】:2012-12-21 01:29:24
【问题描述】:

这是我第一次在这里发帖。我非常感谢有关此主题的任何和所有指导。

我正在尝试制作一个程序来自动填写网络表单并提交数据,将结果页面返回给程序,以便它可以继续“浏览”页面,从而允许它递归地提交更多数据。

我遇到的主要问题是:

  • “提交”按钮是用 Javascript 编码的,所以在发出页面请求时我不知道表单数据的去向。
  • 我想使用 Excel 表格中的数据填写表格,因此我需要能够从页面外部访问数据。
  • 我需要能够浏览结果页面才能继续提交更多数据。

更具体地说,我正在尝试首先登录Practice Mate website,导航到“管理患者”,点击“添加患者”,然后填写正确的表格并提交。 我正在从数千行长的 Excel 表格中填写表格。
抱歉,如果不提供用户名和密码,我无法更清楚地说明这一点。

我一直在尝试做的是使用 Javascript 从使用 PHP 从 Excel 文档中检索信息的页面发出页面请求。不过,我似乎仍然无法使用这种方法。

对于这方面的新手,我深表歉意。提前致谢。

【问题讨论】:

  • 因为涉及到一些 Javascript,所以您无法在 PHP 中执行此操作(因为您已标记此问题)。您是否考虑将其编写为浏览器用户脚本或浏览器扩展程序?此外,他们的网站 TOS 似乎禁止屏幕抓取,因此请准备好被他们主动屏蔽。
  • 为什么不能用 PHP 完成?
  • @PastorBones,告诉我如何在 PHP 中处理 HTML 中的 Javascript,我会改变我的说法。
  • 听起来工作量很大。为什么不直接使用网络嗅探器来确定表单帖子如何发送到服务器并使用 cURL 自己发送呢?如果您需要来自 javascript 变量的值,您总是可以在发送表单之前解析 html 并获取它。我已经做了很多次了......
  • 好的,查看登录表单。这是一个aspx页面。粗略一看,它需要一个 viewstate 值与表单数据一起传递,这些数据可以从页面中的 CDATA 中抓取。

标签: php javascript webforms automation


【解决方案1】:

您可以使用PHP cURL 浏览和提交表单到网站,但这取决于网站的设置方式。大多数都进行了安全检查以防止僵尸程序,但要让一切正常运行可能会很棘手。

我花了一点时间想出了这个登录脚本。如果没有有效的用户名和密码,我无法验证它是否成功,但应该做你需要的。这个简短的示例首先浏览到页面以设置任何 cookie 并抓取提交表单所需的 __VIEWSTATE 值。然后它使用您提供的用户名/密码提交表单。

<?php

// Login information
$username = 'test';
$password = 'mypass';
$utcoffset = '-6';
$cookiefile = '/writable/directory/for/cookies.txt';

$client = new Client($cookiefile);

// Retrieve page first to store cookies 
$page = $client -> get("https://pm.officeally.com/pm/login.aspx");
// scrape __VIEWSTATE value
$start = strpos($page, '__VIEWSTATE" value="') + 20;
$end = strpos($page, '"', $start);
$viewstate = substr($page, $start, $end - $start);

// Do our actual login
$form_data = array(
    '__LASTFOCUS' => '', 
    '__EVENTTARGET' => '',
    '__EVENTARGUMENT' => '',
    '__VIEWSTATE' => $viewstate,
    'hdnUtcOffset' => $utcoffset,
    'Login1$UserName' => $username,
    'Login1$Password' => $password,
    'Login1$LoginButton' => 'Log In'
);
$page = $client -> get("https://pm.officeally.com/pm/login.aspx", $form_data);

// cURL wrapper class    
class Login {
    private $_cookiefile;

    public function __construct($cookiefile) {
        if (!is_writable($cookiefile)) {
            throw new Exception('Cannot write cookiefile: ' . $cookiefile);
        }
        $this -> _cookiefile = $cookiefile;
    }

    public function get($url, $referer = 'http://www.google.com', $data = false) {
        // Setup cURL
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_REFERER, $referer);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $this -> _cookiefile);
        curl_setopt($ch, CURLOPT_COOKIEJAR, $this -> _cookiefile);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 10);

        // Is there data to post
        if (!empty($data)) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        }

        return curl_exec($ch);
    }

}

【讨论】:

  • 非常感谢您的详细回复!我已经设法让您的示例脚本工作(在对 Guzzle 和自动加载进行了一些研究之后),但我必须对 cURL 进行更多研究才能正确弄清楚如何使用它。如果我遇到更多问题,我一定会在此线程中发布更多内容。
【解决方案2】:

好吧,我认为 cURL 可以解决问题,curl_init() 处理程序已经足够解释了。仍然在文档阅读的开始,但是,预期会有好的结果。好吧,不太确定结构的 PHP 灵活性,因为这对 cURL 意义重大。希望能找到好运。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-06
    相关资源
    最近更新 更多