Подтвердить что ты не робот

Существует ли PHP-эквивалент Perl WWW:: Mechanize?

Я ищу библиотеку, функциональность которой похожа на Perl WWW:: Mechanize, но для PHP. В принципе, это должно позволить мне отправлять HTTP GET и POST-запросы с простым синтаксисом, а затем анализировать полученную страницу и возвращать в простом формате все формы и их поля вместе со всеми ссылками на странице.

Я знаю о CURL, но это немного слишком баребоны, а синтаксис довольно уродлив (тонны curl_foo($curl_handle, ...) statement

Разъяснение:

Я хочу что-то более высокого уровня, чем ответы до сих пор. Например, в 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.

4b9b3361

Ответ 1

SimpleTest ScriptableBrowser можно использовать независимо от рамки тестирования. Я использовал его для многочисленных задач автоматизации.

Ответ 2

Я чувствую себя вынужденным ответить на этот вопрос, хотя его старый пост... Я много работал с PHP-скручиванием, и он не так хорош, как можно ближе к чему-то вроде WWW: Mechanize, к которому я перехожу (Я думаю, что я собираюсь пойти с реализацией языка Ruby). Curl устарел, поскольку для автоматизации чего-либо требуется слишком много "грубой работы", простой скриптовый браузер выглядел многообещающим для меня, но при его тестировании он не будет работать на большинстве веб-форм я пробовал это... честно, я думаю, что PHP не хватает в этой категории соскабливания, веб-автоматизации, поэтому лучше всего смотреть на другой язык, просто хотел опубликовать это, так как я потратил бесчисленные часы на эту тему и, возможно, это спасет кого-то еще в будущем.

Ответ 3

Это 2016 сейчас и там Mink. Он даже поддерживает различные двигатели от безголового чистого PHP-браузера (без JavaScript), через Selenium (который нуждается в браузере, таком как Firefox или Chrome), к безглавому "browser.js" в NPM, который поддерживает JavaScript.

Ответ 4

Попробуйте найти в библиотеке 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);
    }
}

Ответ 5

Попробуйте выполнить одно из следующих действий:

(Да, это код ZendFramework, но он не делает ваш класс более медленным, используя его, поскольку он просто загружает требуемые библиотеки.)

Ответ 7

Curl - это путь для простых запросов. Он выполняет кросс-платформу, имеет расширение PHP и широко применяется и проверяется.

Я создал хороший класс, который может GET и POST массива данных (ВКЛЮЧАЯ ФАЙЛЫ!) к URL-адресу, просто называя CurlHandler:: Get ($ url, $data) || 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 $_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);
        }
    }

}

?>

[edit] Прочитайте разъяснение только сейчас... Возможно, вы захотите пойти с одним из упомянутых выше инструментов, который автоматизирует материал. Вы также можете решить использовать расширение firefox для клиентов, например ChickenFoot для большей гибкости. Я оставлю класс примера выше для будущих поисков.

Ответ 8

Если вы используете CakePHP в своем проекте, или если вы склонны извлекать соответствующую библиотеку, вы можете использовать их завиток 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

Если вы используете систему * nix, вы можете использовать shell_exec() с wget, у которого есть много приятных опций.