2008-10-13 7 views
23

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

Я знаю о 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.

+0

Фактически * есть * порт этого: http://www.compasswebpublisher.com/php/www-mechanize-for-php, но это часть некоторых CMS и нет загрузки. – Gordon 2013-03-06 08:34:43

ответ

21

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

1

Попробуйте искать в библиотеке PEAR. Если все остальное не удается, создайте обертку объекта для завивки.

Вы можете так-то просто, как это:

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); 
    } 
} 
+0

Это не совсем то, что я ищу, я добавил разъяснение, которое, надеюсь, сделает его более понятным, спасибо. – davr 2008-10-13 23:21:57

1

Выполните одно из следующих действий:

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

+0

Они все еще намного больше работают, чем Механизируют, см. Мое разъяснение к вопросу. – davr 2008-10-13 23:10:30

+0

Хороший Q. Я думаю, что никто из них этого не делает. Но я думаю, что буду готовиться к этому, я завтра посмотрю на Mechanize API. – Till 2008-10-14 13:13:28

+0

Если вы делаете что-то, напишите новый ответ, и я обязательно посмотрю на него. Возможно, вы захотите взглянуть на ответ «ScriptableBrowser» в качестве отправной точки, я думаю, ему просто нужно еще несколько функций, чтобы сделать все, что делает Mechanize – davr 2008-10-14 20:43:12

-1

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

+1

О, ну да, я бы не выбрал вход пользователя прямо там. – 2008-10-15 13:56:31

1

Посмотрите в Снупи: http://sourceforge.net/projects/snoopy/

+0

Выглядит интересно, но он довольно старый (последнее обновление 2005), и, хотя лучше, чем curl/wget, у него отсутствуют некоторые функции, которые бы сделали его приятнее. – davr 2008-10-13 23:20:20

1

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

Я создал хороший класс, который может GET и POST массива данных (ВКЛЮЧАЯ ФАЙЛЫ!) К URL-адресу, просто называя CurlHandler :: Get ($ url, $ data) || CurlHandler :: Post ($ url, $ data). Там в дополнительный HTTP User вариант аутентификации тоже :)

/** 
* 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); 
     } 
    } 

} 

?> 

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

2

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

1

Если вы используете 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.

2

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

Смежные вопросы