Есть ли PHP-эквивалент WWW :: Mechanize в Perl? - PullRequest
24 голосов
/ 14 октября 2008

Я ищу библиотеку, которая имеет функциональность, аналогичную 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. *

Ответы [ 9 ]

22 голосов
/ 14 октября 2008

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

3 голосов
/ 08 июля 2016

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

3 голосов
/ 04 июля 2010

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

1 голос
/ 02 марта 2011

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

1 голос
/ 14 октября 2008

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

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

<code>/**
 * 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.
     * 
* @param mixed $ method Метод запроса (Получить / Опубликовать) * @param mixed URI $ url для получения или публикации * @param mixed $ vars Массив переменных (обязательно для запросов POST) * @return string вывод HTML * / публичная статическая функция 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) { генерировать новое исключение ('Ошибка запроса Curl:' .curl_errno ($ curlInterface). "-". curl_error ($ curlInterface)); } еще { возврат ($ результат); } } } ?>

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

1 голос
/ 14 октября 2008

Загляни в Снупи: http://sourceforge.net/projects/snoopy/

1 голос
/ 14 октября 2008

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

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

1 голос
/ 14 октября 2008

Попробуйте поискать в библиотеке 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);
    }
}
0 голосов
/ 14 октября 2008

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

...