代码之家  ›  专栏  ›  技术社区  ›  davr

是否有与Perl的www::mechanical等效的PHP?

  •  24
  • davr  · 技术社区  · 17 年前

    我在找一个功能类似于Perl的库 WWW::Mechanize ,但是对于PHP来说。基本上,它应该允许我用一个简单的语法提交HTTPGET和POST请求,然后解析结果页面并以简单的格式返回所有表单及其字段,以及页面上的所有链接。

    我知道curl,但是它有点太简单了,语法也很难看(很多 curl_foo($curl_handle, ...) 声明

    澄清:

    我想要比答案更高层次的东西。例如,在Perl中,您可以执行如下操作:

    # navigate to the main page
    $mech->get( 'http://www.somesite.com/' ); 
    
    # follow a link that contains the text 'download this'
    $mech->follow_link( text_regex => qr/download this/i );
    
    # submit a POST form, to log into the site
    $mech->submit_form(
        with_fields      => {
            username    => 'mungo',
            password    => 'lost-and-alone',
        }
    );
    
    # save the results as a file
    $mech->save_content('somefile.zip');
    

    要使用http_客户机、wget或curl执行相同的操作,需要做很多工作,我必须手动解析页面以查找链接、查找表单URL、提取所有隐藏字段等。我之所以要求一个PHP解决方案,是因为我对Perl没有经验,而且我可以通过大量的工作来构建我需要的东西,但是如果我能用PHP来实现上面的工作,那会更快。

    9 回复  |  直到 9 年前
        1
  •  22
  •   Aziz    12 年前

    单纯型 ScriptableBrowser 可以独立于测试框架使用。我把它用于许多自动化工作。

        2
  •  2
  •   Rick    15 年前

    我觉得有必要回答这个问题,尽管这是一个古老的帖子…我已经使用过很多php curl,但它在任何地方都不如www:mechanical这样的东西好,我将切换到它(我想我将使用Ruby语言实现)。curl已经过时了,因为它需要太多的“咕哝工作”来自动化任何东西,simpletest可脚本浏览器在我看来是很有前途的,但是在测试它时,它不能在我尝试过的大多数Web表单上工作…老实说,我认为php缺乏这种类型的抓取、web自动化,所以最好看一种不同的语言,只是想发表这篇文章,因为我在这个主题上花了无数个小时,也许将来它会节省别人一些时间。

        3
  •  2
  •   mbirth    9 年前

    现在是2016年, Mink . 它甚至支持不同的引擎,从headless pure php“browser”(不带javascript),到selenium(需要像firefox或chrome这样的浏览器),再到NPM中的headless“browser.js”(支持javascript)。

        4
  •  1
  •   community wiki 2 revs moo    17 年前

    试试看梨图书馆。如果所有其他操作都失败,请为curl创建一个对象包装器。

    你可以这样简单:

    class curl {
        private $resource;
    
        public function __construct($url) {
            $this->resource = curl_init($url);
        }
    
        public function __call($function, array $params) {
            array_unshift($params, $this->resource);
            return call_user_func_array("curl_$function", $params);
        }
    }
    
        5
  •  1
  •   Till    17 年前

    尝试下列操作之一:

    (是的,它是ZendFramework代码,但它不会使类使用它变慢,因为它只加载所需的libs。)

        6
  •  1
  •   Eli    17 年前
        7
  •  1
  •   SchizoDuckie    17 年前

    curl是处理简单请求的方法。它跨平台运行,具有PHP扩展,被广泛采用和测试。

    我创建了一个很好的类,可以获取和发布数据数组(包括文件!)只需调用curlhandler::get($url,$data)curlhandler::post($url,$data),就可以得到URL。还有一个可选的HTTP用户身份验证选项:)

    /**
     * CURLHandler handles simple HTTP GETs and POSTs via Curl 
     * 
     * @package Pork
     * @author SchizoDuckie
     * @copyright SchizoDuckie 2008
     * @version 1.0
     * @access public
     */
    class CURLHandler
    {
    
        /**
         * CURLHandler::Get()
         * 
         * Executes a standard GET request via Curl.
         * Static function, so that you can use: CurlHandler::Get('http://www.google.com');
         * 
         * @param string $url url to get
         * @return string HTML output
         */
        public static function Get($url)
        {
           return self::doRequest('GET', $url);
        }
    
        /**
         * CURLHandler::Post()
         * 
         * Executes a standard POST request via Curl.
         * Static function, so you can use CurlHandler::Post('http://www.google.com', array('q'=>'StackOverFlow'));
         * If you want to send a File via post (to e.g. PHP's $_FILES), prefix the value of an item with an @ ! 
         * @param string $url url to post data to
         * @param Array $vars Array with key=>value pairs to post.
         * @return string HTML output
         */
        public static function Post($url, $vars, $auth = false) 
        {
           return self::doRequest('POST', $url, $vars, $auth);
        }
    
        /**
         * CURLHandler::doRequest()
         * This is what actually does the request
         * <pre>
         * - Create Curl handle with curl_init
         * - Set options like CURLOPT_URL, CURLOPT_RETURNTRANSFER and CURLOPT_HEADER
         * - Set eventual optional options (like CURLOPT_POST and CURLOPT_POSTFIELDS)
         * - Call curl_exec on the interface
         * - Close the connection
         * - Return the result or throw an exception.
         * </pre>
         * @param mixed $method Request Method (Get/ Post)
         * @param mixed $url URI to get or post to
         * @param mixed $vars Array of variables (only mandatory in POST requests)
         * @return string HTML output
         */
        public static function doRequest($method, $url, $vars=array(), $auth = false)
        {
            $curlInterface = curl_init();
    
            curl_setopt_array ($curlInterface, array( 
                CURLOPT_URL => $url,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_FOLLOWLOCATION =>1,
                CURLOPT_HEADER => 0));
            if (strtoupper($method) == 'POST')
            {
                curl_setopt_array($curlInterface, array(
                    CURLOPT_POST => 1,
                    CURLOPT_POSTFIELDS => http_build_query($vars))
                );  
            }
            if($auth !== false)
            {
                  curl_setopt($curlInterface, CURLOPT_USERPWD, $auth['username'] . ":" . $auth['password']);
            }
            $result = curl_exec ($curlInterface);
            curl_close ($curlInterface);
    
            if($result === NULL)
            {
                throw new Exception('Curl Request Error: '.curl_errno($curlInterface) . " - " . curl_error($curlInterface));
            }
            else
            {
                return($result);
            }
        }
    
    }
    
    ?>
    

    [编辑]现在才阅读说明…您可能想使用上面提到的自动化工具之一。你也可以决定使用客户端的火狐扩展,比如 ChickenFoot 更灵活。我将把上面的示例类留在这里,以便将来搜索。

        8
  •  1
  •   method    14 年前

    如果您在项目中使用cakephp,或者您倾向于提取相关的库,那么可以使用它们的curl-wrapper httpsocket。它具有您描述的简单页面获取语法,例如,

    # This is the sugar for importing the library within CakePHP       
    App::import('Core', 'HttpSocket');
    $HttpSocket = new HttpSocket();
    
    $result = $HttpSocket->post($login_url,
    array(
      "username" => "username",
      "password" => "password"
    )
    );
    

    …尽管它没有解析响应页的方法。为此,我将使用simplehtmldom: http://net.tutsplus.com/tutorials/php/html-parsing-and-screen-scraping-with-the-simple-html-dom-library/ 它将自己描述为具有类似jquery的语法。

    我倾向于认为底线是PHP没有Perl/Ruby拥有的出色的刮擦/自动化库。

        9
  •  -1
  •   Francisco Presencia    11 年前

    如果您使用的是*nix系统,那么可以将shell_exec()与wget结合使用,wget有很多不错的选择。

    推荐文章