25

我正在寻找一个功能类似于 Perl 的WWW::Mechanize的库,但适用于 PHP。基本上,它应该允许我使用简单的语法提交 HTTP GET 和 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_Client 或 wget 或 CURL 做同样的事情会做很多工作,我必须手动解析页面以查找链接、查找表单 URL、提取所有隐藏字段等等。我要求使用 PHP 解决方案的原因是我没有使用 Perl 的经验,我可能会通过大量工作来构建我需要的东西,但如果我能在 PHP 中完成上述操作会快得多。

4

9 回答 9

23

SimpleTest 的ScriptableBrowser可以独立于测试框架使用。我已经将它用于许多自动化工作。

于 2008-10-13T23:11:50.980 回答
3

我觉得有必要回答这个问题,即使它是一个旧帖子......我一直在使用 PHP curl 并且它在任何地方都不如我正在切换到的 WWW:Mechanize 之类的东西好(我认为我将使用 Ruby 语言实现).. Curl 已经过时了,因为它需要太多“繁重的工作”来自动化任何东西,最简单的可脚本化浏览器对我来说看起来很有希望,但在测试它时,它不会在大多数网络上工作我尝试过的表格......老实说,我认为 PHP 在这类抓取、网络自动化方面缺乏,所以最好看看另一种语言,只是想发布这个,因为我在这个主题上花费了无数小时,也许它将来会为别人节省一些时间。

于 2010-07-04T09:40:50.707 回答
3

现在是 2016 年,还有Mink。它甚至支持不同的引擎,从无头纯 PHP“浏览器”(没有 JavaScript)、Selenium(需要像 Firefox 或 Chrome 这样的浏览器)到 NPM 中的无头“browser.js”,它确实支持 JavaScript。

于 2016-07-08T08:38:34.083 回答
1

尝试查看 PEAR 库。如果一切都失败了,请为 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);
    }
}
于 2008-10-13T21:14:55.880 回答
1

尝试以下方法之一:

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

于 2008-10-13T21:57:30.100 回答
1

查看史努比:http: //sourceforge.net/projects/snoopy/

于 2008-10-13T23:03:01.280 回答
1

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

我创建了一个不错的类,它可以通过调用 CurlHandler::Get($url, $data) || 获取和发布数据数组(包括文件!)到 url CurlHandler::Post($url, $data)。还有一个可选的 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这样的客户端 Firefox 扩展,以获得更大的灵活性。我将把上面的示例类留在这里以供将来搜索。

于 2008-10-13T23:12:29.763 回答
1

如果您在项目中使用 CakePHP,或者如果您倾向于提取相关库,您可以使用他们的 curl 包装器 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 所拥有的出色的抓取/自动化库。

于 2011-03-02T14:44:14.593 回答
-1

如果您在 *nix 系统上,您可以将 shell_exec() 与 wget 一起使用,它有很多不错的选项。

于 2008-10-13T22:10:35.537 回答