Управление IE из php

by SeoCoder on Июль 29, 2009

Давно я хотел это вынести в паблик, но что-то не было времени. Сейчас появилось немножко времени.
Что представляет собой скрипт?!

  1. Работает только под виндой, где установлен IE
  2. Это «обертка» для управления браузером, с возможностью, смены прокси, юзерагента, очистки кук и кеша.
  3. Дает полный доступ к DOM страницы. AJAX не преграда. ;)
  4. Подходит для быстрого написания регалок.
  5. Использование форфри как всегда, но от пару баксов на пиво не откажусь – Z260880410831.

Первым у нас идет базовый класс самого браузера с примером использования.

<?php
 
define('READYSTATE_COMPLETE', 4);
 
class IEEvents {
	public $dom = null;
 
	function DocumentComplete($dom, $url) {
		$this->dom = $dom;
	}
}
 
class browser {
	public  $document;
	public $ie = null;
	private $useragent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6';
	private $sink;
 
	function __construct() {
		$this->__initie();
		$this->dom = new dom();
	}
 
	function  __destruct() {
 
	}
 
	function __initie($left = 0, $top = 0, $width = 800, $height = 700, $visible = 1) {
		$this->ie = new COM("InternetExplorer.Application", null, CP_UTF8);
		$this->sink = new IEEvents;
		com_event_sink($this->ie, $this->sink, 'DWebBrowserEvents2');
		$this->ie->left = $left;
		$this->ie->top = $top;
		$this->ie->width = $width;
		$this->ie->height = $height;
 
		$this->ie->menubar = 0;
		$this->ie->toolbar = 0;
		$this->ie->statusbar = 0;
		$this->ie->visible = $visible;
		$this->ie->silent = true;
	}
 
	function navigate($url, $post = null) {
		$this->ie->navigate($url, null, $post, null, "User-Agent: " . $this->useragent . "\r\n");
		$this->wait();
	}
 
 
	function wait($sec = 0) {
		$this->sink->dom = null;
		while (!$this->sink->dom)
		{
			com_message_pump(4000);
		}
		while ($this->ie->Busy);
		while ($this->ie->ReadyState != READYSTATE_COMPLETE);
		sleep($sec);
		$this->document = $this->ie->document;
		$this->dom->setdocument( $this->document );
	}
 
	function innertext() {
		return $this->ie->Document->body->innerTEXT;
	}
 
	function clearcache()
	{
		$oFileSys = new COM("Scripting.FileSystemObject");
		$objShell = new COM("Shell.Application");
 
		$objFolder = $objShell->Namespace(32);
 
		$oFileSys->DeleteFile($objFolder->Self->Path . '\*.*');
		$sPath = $oFileSys->GetFolder($objFolder->Self->path) . "\\Content.IE5\\";
 
		$oFolder = $oFileSys->GetFolder($sPath);
		$oFolders = $oFolder->SubFolders;
		foreach ($oFolders as $item)
		{
			$oFileSys->DeleteFolder($item);
		}
		unset($oFileSys);
		unset($objShell);
	}
 
 
	function clearcookies()
	{
		$objShell = new COM("Shell.Application");
		$objFSO = new COM("Scripting.FileSystemObject");
 
		$objFolder = $objShell->Namespace(33);
		$objFolderItem = $objFolder->Self;
		$strPath = $objFolderItem->Path;
		$oFolder = $objFSO->GetFolder($strPath);
		$oFiles = $oFolder->Files;
		if (count($oFiles) > 2)
		$objFSO->DeleteFile($strPath . '\*.txt');
		unset($objFSO);
		unset($objShell);
	}
 
}
 
 
if (!defined('ROOT')) define('ROOT', dirname(__file__) . '/');
 
 
function __autoload($class_name)
{
require_once ROOT.$class_name . '.class.php';
}
 
 
$yaru = new browser();
$yaru->navigate('http://ya.ru');
echo $yaru->innertext();

ну и чтобы это у вас заработало класс dom

<?php
class dom {
	public $anchors;
	public $input;
	public $textarea;
	public $radiobutton;
	public $images;
	public $debug;
 
	private $document = null;
 
 
	function __construct() {
		$this->anchors = new anchors();
		$this->input = new input();
		$this->select = new select();
		$this->textarea = new textarea();
		$this->radiobutton = new radiobutton();
		$this->images = new images();
		$this->debug = new debug();
 
	}
 
	function __destruct() {
		unset($this->anchors);
		unset($this->input);
		unset($this->select);
		unset($this->textarea);
		unset($this->radiobutton);
		unset($this->images);
		unset($this->debug);
	}
 
	function setdocument($document) {
		$class_vars = get_class_vars(get_class($this));
 
		foreach ($class_vars as $name => $value) {
			$this->{$name}->document =  $document;
		}
	}
}

Ну и напоследок замечательный класс для дебага, который мне сразу генерил код для регалки ;)

<?php
class debug {
 
	public $document;
 
 
	function analyze($class) {
		$elements = $this->document->body->all;
		for ($i = 0; $i <= $elements->length; $i++) {
 
			$tag = $elements->item($i)->tagName;
 
			switch ($tag) {
				case 'INPUT': case 'SELECT':
					$type = $elements{$i}->getAttribute("type");
					$name = $elements{$i}->getAttribute("name");
					$classname = $elements{$i}->getAttribute("classname");
					$value = $elements{$i}->value;
					$id = $elements{$i}->getAttribute("id");
					if (($type == 'checkbox') or ($type == 'password') or ($type == 'text') or ($type == 'submit') or ($type == 'select-one')) {
						$div = $this->document->createElement('div');
 
 
						$data = " type: $type";
 
						if ($id != null) $data .= " id: $id";
						if ($name !=  null) $data .= " name: $name";
						if ($classname !=  null) $data .= " classname: $classname";
						if ($value !=  null) $data .= "  value: $value";
						$div->innerHTML = $data;
						$div->style->backgroundColor = 'yellow';
						$elements{$i}->parentNode->appendChild($div);
 
						switch ($type) {
							case 'text': case 'password': case 'submit': case 'textarea':
								if ($id != null) {
									echo '$'.$class.'->dom->input->set_by_id(\''.$id.'\', \'\',  false);'.'<br>';
								} elseif  ($name!= null) {
									echo '$'.$class.'->dom->input->set_by_name(\''.$name.'\', \'\',  false);'.'<br>';
								} elseif ($classname!= null) {
									echo '$'.$class.'->dom->input->set_by_classname(\''.$classname.'\', \'\',  false);'.'<br>';
								}
								break;
							case 'checkbox' :
								if ($id != null) {
									echo '$'.$class.'->dom->input->set_by_id(\''.$id.'\', \'true\',  false);'.'<br>';
								} elseif  ($name!= null) {
									echo '$'.$class.'->dom->input->set_by_name(\''.$name.'\', \'true\',  false);'.'<br>';
								} elseif ($classname!= null) {
									echo '$'.$class.'->dom->input->set_by_classname(\''.$classname.'\', \'true\',  false);'.'<br>';
								}
								break;
 
							case 'select-one' :
								if ($id != null) {
									echo '$'.$class.'->dom->input->set_by_id(\''.$id.'\', \'\',  false);'.'<br>';
								} elseif  ($name!= null) {
									echo '$'.$class.'->dom->input->set_by_name(\''.$name.'\', \'\',  false);'.'<br>';
								} elseif ($classname!= null) {
									echo '$'.$class.'->dom->input->set_by_classname(\''.$classname.'\', \'\',  false);'.'<br>';
								}
								break;
 
 
						}
 
					}
					break;
 
				case 'IMG' :
					$type = $elements{$i}->getAttribute("type");
					$name = $elements{$i}->getAttribute("name");
					$classname = $elements{$i}->getAttribute("classname");
					$width = $elements{$i}->getAttribute("width");
					$height = $elements{$i}->getAttribute("height");
					$id = $elements{$i}->getAttribute("id");
					$src = $elements{$i}->getAttribute("src");
 
					$div = $this->document->createElement('div');
 
					$data = '';
					if ($src !=  null) $data .= "  src: $src";
					if ($id != null) {
						$data .= " id: $id";
						echo '$'.$class.'->dom->images->save_by_id(\''.$id.'\', \'\',  false);'.'<br>';
					}
					if ($name !=  null) $data .= " name: $name";
					if ($classname !=  null) $data .= " classname: $classname";
					if ($width !=  null) $data .= "  w: $width";
					if ($height !=  null) $data .= "  h: $height";
 
					$div->innerHTML = $data;
					$div->style->backgroundColor = 'yellow';
					$elements{$i}->parentNode->appendChild($div);
 
					break;
 
			}
 
		}
	}
 
}

{ 4 trackbacks }

Управление IE из php : Блог Молчуна
07.30.09 at 00:26
Про управление браузером из пхп
08.03.09 at 15:36
Xedant Human Emulator и Python. | Python for SEO
09.21.09 at 13:00
Яндекс ввел географический таргетинг для Беларуси | AVL
02.08.10 at 21:42

{ 26 comments… read them below or add one }

1 resident 07.29.09 at 09:03

Пишет ошибку: Fatal error: Class ‘anchors’ not found in Z:\home\test2.ru\www\dom.php on line 14

Де взять этот класс?

2 SeoCoder 07.29.09 at 09:04

ааа. ну это можно отключить.
там еще много классов.
$this->anchors = new anchors();
$this->input = new input();
$this->select = new select();
$this->textarea = new textarea();
$this->radiobutton = new radiobutton();
$this->images = new images();
$this->debug = new debug();
вот это заремарить.

3 shuppe 07.29.09 at 09:22

известная прога Xedant Human Emulator работает по тому же принципу. но стоит дорого.
напишите свой аналог, наверняка найдутся покупатели

4 mescalito 07.29.09 at 09:25

бесплатный аналог хеданта что-ли?

5 SeoCoder 07.29.09 at 10:27

угу

6 Благодарный 07.29.09 at 11:17

еще бы полностью рабочий пример увидеть

7 SeoCoder 07.29.09 at 11:21

90% рабочего кода тут представлено.

8 Кодер 07.29.09 at 14:05

Спасибо, отличная инфа. Работает, только есть пара вопросов.
Как дебаг сделать?
$yaru->sink->dom->debug не работает(
И как скрпиты то быстро писать?) Или вся фишка в том, что нужно просто в ручную забивать названия кнопок и т.п. (кст, доп классы все таки было бы полезны) и скрпит будет это выполнять.

9 SeoCoder 07.29.09 at 14:37

вот пример одного из классов.
< ?php
class input {
public $document;

function set_by_id($findintag, $value, $part = false) {
$forms = $this->document->forms;
for ($i = 0; $i < = $forms->length; $i++)
{
$form = $forms->item($i);
for ($j = 0; $j < $form->elements->all->length; $j++)
{

$tag = $form->elements->all[$j]->tagName;
if (($tag == ‘INPUT’) or ($tag == ‘SELECT’) or ($tag == ‘TEXTAREA’) ) {
$id = $form->elements->all{$j}->getAttribute(«id»);
if ($part)
{
$pos = strpos($id, $findintag);
if (is_int($pos))
{
$mustset = true;
}

}
else
if ($id == $findintag)
{
$mustset = true;
}
if ($mustset)
{
$type = $form->elements->all{$j}->getAttribute(«type»);
if (($type==’text’) or ($type==’password’) or ($type==’textarea’) ) {
$form->elements->all{$j}->value = $value;
} elseif (($type==’select-one’)) {
$form->elements->all{$j}->selectedIndex =
rand(0, $form->elements->all{$j}->length – 1);

} elseif (($type==’checkbox’)) {
$form->elements->all{$j}->checked = $value;
} elseif (($type==’submit’)) {
$form->elements->all{$j}->click();
}
return true;
}
}
}
}
return false;
}

function set_by_name($findintag, $value, $part = false) {
$forms = $this->document->forms;
for ($i = 0; $i < = $forms->length; $i++)
{
$form = $forms->item($i);
for ($j = 0; $j < $form->elements->all->length; $j++)
{

$tag = $form->elements->all[$j]->tagName;
if (($tag == ‘INPUT’) or ($tag == ‘SELECT’) or ($tag == ‘TEXTAREA’) ) {
$name = $form->elements->all{$j}->getAttribute(«name»);
if ($part)
{
$pos = strpos($id, $findintag);
if (is_int($pos))
{
$mustset = true;
}

}
else
if ($name == $findintag)
{
$mustset = true;
}
if ($mustset)
{
$type = $form->elements->all{$j}->getAttribute(«type»);
if (($type==’text’) or ($type==’password’) or ($type==’textarea’) ) {
$form->elements->all{$j}->value = $value;
} elseif (($type==’select-one’)) {
$form->elements->all{$j}->selectedIndex =
rand(0, $form->elements->all{$j}->length – 1);

} elseif (($type==’checkbox’)) {
$form->elements->all{$j}->checked = $value;
} elseif (($type==’submit’)) {
$form->elements->all{$j}->click();
}
return true;
}
}
}
}
return false;

}

function set_by_classname($classname, $value, $part = false) {

}

function set_by_value($findintag, $value, $part = false) {
$forms = $this->document->forms;
for ($i = 0; $i < = $forms->length; $i++)
{
$form = $forms->item($i);
for ($j = 0; $j < $form->elements->all->length; $j++)
{

$tag = $form->elements->all[$j]->tagName;
if (($tag == ‘INPUT’) or ($tag == ‘SELECT’) or ($tag == ‘TEXTAREA’) ) {
$valueout = $form->elements->all{$j}->value;
if ($part)
{
$pos = strpos($valueout, $findintag);
if (is_int($pos))
{
$mustset = true;
}

}
else
if ($valueout == $findintag)
{
$mustset = true;
}
if ($mustset)
{
$type = $form->elements->all{$j}->getAttribute(«type»);
if (($type==’text’) or ($type==’password’) ) {
$form->elements->all{$j}->value = $value;
} elseif (($type==’select-one’)) {
$form->elements->all{$j}->selectedIndex =
rand(0, $form->elements->all{$j}->length – 1);

} elseif (($type==’checkbox’)) {
$form->elements->all{$j}->checked = $value;
} elseif (($type==’submit’)) {
$form->elements->all{$j}->click();
}
return true;
}
}
}
}
return false;

}

}

остальное пишется также по аналогии

10 SideWinder 08.03.09 at 08:42

Спасибо. Только собрался нечто подобное написать )

11 Vera 08.09.09 at 12:45

SideWinder ну и как успехи написал?

12 Fantom 08.12.09 at 12:50

Всегда поражали такие люди когда свои хорошие наработки в паблик выкладывают совершенно безвозмездно. Спасибо бро…

13 renault 08.12.09 at 15:16

Спасибо огромное. Действительно очень полезная штука

14 JackSoft 08.12.09 at 16:45

Еще зимой накидал схожый класс, а потом ушел на HtmlUnit. Причина – не смог дать фокус окну, открываемому яваскриптом, например вставка html-кода в TinyME редакторе. У тебя получилось бегать по потомкам? В принципе если интересно – стукни в аську на блоге – пообщаемся.

15 SeoCoder 08.12.09 at 16:53

tinymce легко
стучи в аську – покажу

16 SeoCoder 08.12.09 at 16:57

Ладно, покажу тут ;)
$this->browser->document->getElementById(‘txt_msg_ifr’)->contentWindow->document->body->innerHTML = $this->getposttext();

17 JackSoft 08.12.09 at 17:12

Ты бы асю засветил :)

18 JackSoft 08.12.09 at 17:20

Еще вопрос по клику на таких батонах был:
Save your profile

19 JackSoft 08.12.09 at 17:21


Save your profile

20 JackSoft 08.12.09 at 17:22

не вставляется :)
почисти.
моя ася 4443б588 (б – это шесть ;)

21 JackSoft 08.12.09 at 18:00

Про клик не актуально – посмотрел твои примеры – разобрался – респект.

Еще вспомнил :)
Сохранение картинки в файл для отправки антикапча сервисам ;)
Неужели тоже поможеш? ;)

22 Enyusha 08.15.09 at 11:51

Классная тема. Вот бы еще разобратся может кто поможет.

23 skyman 08.24.09 at 10:17

Какие плюсы и минусы такого способа написания регалок, кроме простоты написания?

24 Bambino 09.04.09 at 11:31

Че-то я не врубил как працює. :) Попробовал выполнить эмуляцию регистрации на сайте. Что за параметр $class, который нужно передатьв debug->analyze?

25 Leonida 09.24.09 at 13:27

Тема действительно хороша, также нужно разбираться.

26 sergsam1 12.08.09 at 03:37

Ну вот я запустил это дело, выскочило окно ya.ru а дальше что делать?

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">