2016-02-05 2 views
0

Я купил книгу о веб-соскабливании с помощью php. В нем автор входит в систему https://www.packtpub.com/. Книга устарела, поэтому я не могу проверить идеи, потому что веб-сайт изменился с момента выпуска. Это модифицированный код, который я использую, но логины не увенчались успехом, и я пришел к выводу, что строка «Параметры учетной записи» не входит в переменную $results. Что я должен изменить? Я считаю, что ошибка исходит из неправильного указания адресата.Войти на веб-страницу с php с cURL

<?php 
// Function to submit form using cURL POST method 
function curlPost($postUrl, $postFields, $successString) { 
    $useragent = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; 
     en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3'; // Setting useragent of a popular browser 
    $cookie = 'cookie.txt'; // Setting a cookie file to storecookie 
    $ch = curl_init(); // Initialising cURL session 
    // Setting cURL options 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // PreventcURL from verifying SSL certificate 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
    curl_setopt($ch, CURLOPT_FAILONERROR, TRUE); // Script shouldfail silently on error 
    curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE); // Use cookies 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // FollowLocation: headers 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // Returningtransfer as a string 
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); // Settingcookiefile 
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie); // Settingcookiejar 
    curl_setopt($ch, CURLOPT_USERAGENT, $useragent); // Settinguseragent 
    curl_setopt($ch, CURLOPT_URL, $postUrl); // Setting URL to POSTto 
    curl_setopt($ch, CURLOPT_POST, TRUE); // Setting method as POST 
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postFields)); // Setting POST fields as array 
      $results = curl_exec($ch); // Executing cURL session 
      $httpcode = curl_getinfo($ch,CURLINFO_HTTP_CODE); 
       echo "$httpcode"; 
      curl_close($ch); // Closing cURL session 
      // Checking if login was successful by checking existence of string 
      if (strpos($results, $successString)) { 
       echo "I'm in."; 
       return $results; 
      } else { 
       echo "Nope, sth went wrong."; 
       return FALSE; 
      } 
} 

$userEmail = '[email protected]'; // Setting your email address for site login 
$userPass = 'yourpass'; // Setting your password for sitelogin 
$postUrl = 'https://www.packtpub.com'; // Setting URL toPOST to 
// Setting form input fields as 'name' => 'value' 
$postFields = array(
     'email' => $userEmail, 
     'password' => $userPass, 
     'destination' => 'https://www.packtpub.com', 
     'form_id' => 'packt-user-login-form' 
); 
$successString = 'Account Options'; 
$loggedIn = curlPost($postUrl, $postFields, $successString); //Executing curlPost login and storing results page in $loggedIn 

EDIT: после запроса:

enter image description here

Я заменил линию

'destination' => 'https://www.packtpub.com' 
with  

'op' => 'Login' 

, добавлено

'form_build_id' => '' 

и редактируются

$postUrl = 'https://www.packtpub.com/register'; 

так как это URL, который я получаю при выборе копии как cURL и вставки в редакторе.

Я все еще получаю сообщение «Нет, я ошибался». Я думаю, это потому, что $successString не хранится в curl в первую очередь. Каким должен быть установлен тип-build-id? Он меняется каждый раз, когда я вхожу в систему.

+0

'form_build_id' может быть токеном CSRF. Если это так, вам нужно будет сделать запрос на страницу входа в систему (запрос GET), а затем проанализировать HTML, чтобы извлечь это значение. Вероятно, это скрытое поле формы. Попробуйте воспроизвести запрос в Firefox с пустым 'form_build_id' и проверить ответ. – BugHunterUK

+0

Похоже, что 'form_build_id' является токеном CSRF. Кажется, они используют Drupal. У меня нет времени, чтобы написать запрос cURL в PHP. Если у меня будет время, когда я вернусь домой, я выбью пример для вас. Вот некоторая полезная информация о том, что такое токен CSRF и почему они используются: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29 – BugHunterUK

+1

Также обратите внимание: вместо этого вы использовали '-' '_' в' form_id': p – BugHunterUK

ответ

2

Книга, которую вы используете, устарела, и Packt Publishing изменили свой сайт. Теперь он включает токен CSRF, и без этого вы никогда не сможете войти в систему.

Я разработал рабочее решение. Он использует pQuery для разбора HTML. Вы можете установить это с помощью Composer, или загрузить пакет и включить его в свое приложение. Если вы сделаете это, удалите require __DIR__ . '/vendor/autoload.php'; и замените его на папку pquery в вашей системе.

Для проверки через командную строку просто выполните: php packt_example.php.

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

<?php 

require __DIR__ . '/vendor/autoload.php'; 

$email = '[email protected]'; 
$password = 'mypassword'; 

# Initialize a cURL session. 
$ch = curl_init('https://www.packtpub.com/register'); 

# Set the cURL options. 
$options = [ 
    CURLOPT_COOKIEFILE  => 'cookies.txt', 
    CURLOPT_COOKIEJAR  => 'cookies.txt', 
    CURLOPT_RETURNTRANSFER => 1 
]; 

# Set the options 
curl_setopt_array($ch, $options); 

# Execute 
$html = curl_exec($ch); 

# Grab the CSRF token from the HTML source 
$dom = pQuery::parseStr($html); 
$csrfToken = $dom->query('[name="form_build_id"]')->val(); 

# Now we have the form_build_id (aka the CSRF token) we can 
# proceed with making the POST request to login. First, 
# lets create an array of post data to send with the POST 
# request. 
$postData = [ 
    'email'   => $email, 
    'password'  => $password, 
    'op'   => 'Login', 
    'form_build_id' => $csrfToken, 
    'form_id'  => 'packt_user_login_form' 
]; 


# Convert the post data array to URL encoded string 
$postDataStr = http_build_query($postData); 

# Append some fields to the CURL options array to make a POST request. 
$options[CURLOPT_POST] = 1; 
$options[CURLOPT_POSTFIELDS] = $postDataStr; 
$options[CURLOPT_HEADER] = 1; 

curl_setopt_array($ch, $options); 

# Execute 
$response = curl_exec($ch); 

# Extract the headers from the response 
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 
$headers = substr($response, 0, $headerSize); 

# Close cURL handle 
curl_close($ch); 

# If login is successful, the headers will contain a location header 
# to the url http://www.packtpub.com/index 
if(!strpos($headers, 'packtpub.com/index')) 
{ 
    print 'Login Failed'; 
    exit; 
} 

print 'Logged In'; 
+1

Вы должны отправить исправления в эту книгу! : P Спасибо! – brumbrum

+0

Какое название и версия книги и на какой странице отображается код. Мне было бы интересно представить исправления. – BugHunterUK

+1

Мгновенный php веб соскабливания. Я думаю, что есть только 1 версия. Исходный код бесплатный. https://www.packtpub.com/web-development/instant-php-web-scraping-instant – brumbrum

2

Я отправляю этот ответ, поскольку я думаю, что он может помочь вам в будущем, столкнувшись с такими проблемами. Я делаю это много, когда пишу веб-скребки.

  1. Открыть Firefox. Нажмите CTRL + SHIFT + Q
  2. Press Network tab
  3. Перейти на сайт. Вы заметите, что отслеживаются HTTP-запросы
  4. Войти успешно, пока HTTP-запросы находятся под контролем
  5. После входа в систему щелкните правой кнопкой мыши запрос HTTP, который был сделан для входа в систему, и скопируйте его как CURL.

Теперь у вас есть запрос CURL. Реплицируйте HTTP-запрос с помощью PHP cURL. И снова проверьте.

Для очистки веб-страниц вы должны быть хорошо знакомы с контрольными HTTP-заголовками. Вы можете использовать:

  • Сетевой монитор (Chrome, Firefox)

  • Скрипач

  • Wiresharp

  • MITMProxy

  • Чарльз

etc ...

+0

Спасибо! Некоторые действительно полезные данные. Я добавил изображение того, что я сейчас наблюдаю. – brumbrum

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