Что нового

[Автоматизация] Парсер с EsiTronic

rivega

Новичок
Сообщения
45
Репутация
1
Добрый день. нужна помощь в оптимизации и ускорении работы скрипта.

Парсер- извлекает информацию из EsiTronic(каталог бош), и кладет ее в БД.
Проблемы:
1.на каждый запрос в БД тратится порядочное время, можно ли как то ускорить это? Либо единым моно запросом, либо созданием БД в памяти с последующим сохранением в основную БД(и то и др у меня не получилось)
2.общая оптимизация скрипта...(я новичок и вероятно что то делаю не оптимально)
Код:
HotKeySet("^!x", "MyExit") 

#include <SQLite.au3>
#include <SQLite.dll.au3>
#include <File.au3>
#Include <GuiListView.au3>

;Opt('ExpandEnvStrings', 1)

local $timeout=600
local $timeoutbig=600
Local $sDbName = "E:\esibd.db3"
_SQLite_Startup()
_SQLite_Open($sDbName) ; открывает базу данных 
If @error Then
    MsgBox(16, "Ошибка SQLite", "Не удалось открыть/загрузить постоянную базу данных на диске!")
    Exit -1
EndIf

#cs
_SQLite_Exec(-1, "CREATE TABLE esi1 ('uid' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,`naim` varchar(255) NOT NULL);") ; создает таблицу esi1
_SQLite_Exec(-1, "CREATE TABLE cars ('uid' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,'rb' varchar(20));")              ; создает таблицу cars
_SQLite_Exec(-1, "CREATE TABLE esi2 ('uid' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,`naim` varchar(255) NOT NULL);") ; создает таблицу esi2
_SQLite_Exec(-1, "CREATE TABLE detali ('uid' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,'rb' varchar(200));")            ; создает таблицу detali

_SQLite_Exec(-1, 'INSERT INTO esi1(naim) VALUES ("Ключ RB");')
;_SQLite_Exec(-1, 'INSERT INTO (naim) VALUES ("Ключ RB");')
#ce

Run("C:\Program Files\Bosch\ESItronic\Esi2.exe")
WinWait("ESI[tronic]")
WinActivate("ESI[tronic]", "")
WinWait("ESI[tronic]")
WinMove("ESI[tronic]", "",0, 0,1590,1040)
ControlClick("ESI[tronic]", "", "[CLASS:Afx:400000:3; INSTANCE:1]","left","1","20","10")
WinWait("ESI[tronic] - Выбор автомобиля по наименованию", "")

	  For $a=0 To 1 Step 1  ;перебираем марки
			
			ControlFocus("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:ComboBox; INSTANCE:3]")
			ControlEnable("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:ComboBox; INSTANCE:3]")
			ControlCommand ("ESI[tronic] - Выбор автомобиля по наименованию","","[CLASS:ComboBox; INSTANCE:3]","SetCurrentSelection", 16)
			ControlFocus("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:ToolbarWindow32; INSTANCE:3]")
			ControlEnable("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:ToolbarWindow32; INSTANCE:3]")
			ControlClick("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:ToolbarWindow32; INSTANCE:3]","left","1","40","10")
			   Do
			     sleep(50)    
			   Until  ControlListView("ESI[tronic] - Выбор автомобиля по наименованию", "", "SysListView321", "GetItemCount")<>0 ;ожидание загрузки списка моделей
			Beep(700, 1500)
			Local $sText = ControlGetText("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:Static; INSTANCE:12]")
			Local $result = StringInStr($sText, "/")
			Local $len=StringLen ($sText) 
			$result = StringTrimLeft($sText, 2)
			ControlFocus("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:SysListView32; INSTANCE:1]")
		    ControlEnable("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:SysListView32; INSTANCE:1]")
			   For $o = 0 To $result 	Step 1 ; перебираем машины
					 Sleep($timeout)
					 ControlFocus("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:SysListView32; INSTANCE:1]")
					 ControlEnable("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:SysListView32; INSTANCE:1]") 
					 $chn=ControlGetHandle("ESI[tronic]", "", "[CLASS:SysListView32; INSTANCE:1]")  
Sleep(100)					 
					 _GUICtrlListView_ClickItem($chn, $o)											;кликаем по строчкам машин
					 Sleep(50)
					 ControlClick("ESI[tronic]", "", "[CLASS:ToolbarWindow32; INSTANCE:4]","left","1","500","16") ; кликаем Ф7
Local $sTitle="ESI[tronic] - Выбор автомобиля по наименованию"
WinActivate ( "ESI[tronic] - Выбор автомобиля по наименованию" )
Local $r = ControlListView("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:SysListView32; INSTANCE:2]", "GetItemCount" ) ;определяем количество строк
Local $RBKz = ControlGetText("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:Static; ID:1045]")
Local $RBKx = StringInStr($RBKz, "/") ;определяем еомер позиции "/"
Local $RBK = StringLeft($RBKz, $RBKx-1) ;определяем РБ ключ
Local $z ='INSERT INTO cars(rb) VALUES ('&'"'&$RBK&'"'&');' ; вставляем значение рб ключа 1 раз в колонку рб
			_SQLite_Exec(-1, $z)
Local $z ='SELECT uid FROM cars WHERE rowid=last_insert_rowid();'
Local $hQuery
		 Local $aRow		
		_SQLite_Query(-1, $z, $hQuery) ; выполняет запрос
		 _SQLite_FetchData($hQuery, $aRow)
			Local $currentcarid = $aRow[0]		
	  While $r <> -1
		 Local $k =ControlListView("ESI[tronic]", "", "[CLASS:SysListView32; INSTANCE:2]", "GetText" , $r, 0)
		 $k = StringReplace(StringReplace($k,";", ""),"""","")
		 if $k<>'Ключ RB'  Then
		 ;MsgBox(16, "Ошибка SQLite", $k)
		 Local $n = ControlListView("ESI[tronic]", "", "[CLASS:SysListView32; INSTANCE:2]", "GetText" , $r, 1)
		 $n = StringReplace(StringReplace($n,";", ""),"""","")
		 Local $z ='SELECT uid FROM esi1 WHERE naim='&'"'&$k&'"'&';'; текст запроса поиска вхождений наименования в таблицу соответвия
		 Local $hQuery
		 Local $aRow
		 _SQLite_Query(-1, $z, $hQuery) ; выполняет запрос
		 _SQLite_FetchData($hQuery, $aRow)
		 If $aRow[0] Then				
			 Local $z ='UPDATE cars SET id'&$aRow[0]&'='&'"'&$n&'"'&' WHERE uid='&'"'&$currentcarid&'"'&';' ; вставляем значение 2-го поля в изи, в таблицу машин, в поле уида
			_SQLite_Exec(-1, $z)				
		 Else
			 Local $z ='INSERT INTO esi1(naim) VALUES ('&'"'&$k&'"'&');'			 
			_SQLite_Exec(-1, $z)
			Local $z ='SELECT uid FROM esi1 WHERE rowid=last_insert_rowid();'
			_SQLite_Query(-1, $z, $hQuery) ; выполняет запрос
		 _SQLite_FetchData($hQuery, $aRow)
			Local $lastid =$aRow[0]
		Local $z ='ALTER TABLE cars ADD COLUMN id'&$lastid&';'
		_SQLite_Exec(-1, $z)	
			Local $z ='UPDATE cars SET id'&$aRow[0]&'='&'"'&$n&'"'&' WHERE uid='&'"'&$currentcarid&'"'&';' ; вставляем значение 2-го поля в изи, в таблицу машин, в поле уида
			_SQLite_Exec(-1, $z)					
		EndIf 		 
		 EndIf		
		 $r = $r -1 
WEnd															
					  ControlClick("ESI[tronic]", "", "[CLASS:ToolbarWindow32; INSTANCE:4]","left","1","500","16") ; кликаем Ф7
					 Sleep(20)
					 ControlClick("ESI[tronic] - Выбор автомобиля по наименованию", "", "[CLASS:Afx:400000:3; INSTANCE:2]","left","1","40","10") ;кликаем по кнопке оборудование
				     Sleep(100) ;ждем загрузки списка 
									   if	 Not ControlGetText("ESI[tronic]", "", "[CLASS:Static; INSTANCE:16]") Then
									   Else
									   Do
										  sleep(50)    
									    Until  ControlGetText("ESI[tronic] - Оборудование автомобиля", "", "[CLASS:Static; INSTANCE:16]")
											 ControlEnable("ESI[tronic] - Оборудование автомобиля", "", "[CLASS:SysTabControl32; INSTANCE:2]")
                                                      Local $t = "Все" ;переходим на вкладку "Все" в оборудовании автомобиля
													  While ControlGetText( "ESI[tronic] - Оборудование автомобиля", "", "[CLASS:ComboBox; INSTANCE:8]" ) <> $t 
														 												    
														   ControlCommand("ESI[tronic] - Оборудование автомобиля", "", "[CLASS:SysTabControl32; INSTANCE:2]","TabRight", "") 
												   
													   WEnd
											 Local $kolnaim = ControlGetText("ESI[tronic] - Оборудование автомобиля", "", "[CLASS:Static; INSTANCE:16]") ;определение количества строк наименований
											 Local $result2 = StringInStr($kolnaim, "/")
											 Local $len=StringLen ($kolnaim) 
											 $result2 = StringTrimLeft($kolnaim, 2)
   
   For $b=0 To $result2-1	 Step 1
   $chnd=ControlGetHandle("ESI[tronic]", "", "[CLASS:SysListView32; INSTANCE:2]")   
    Sleep(50)
   ;MsgBox("","",$b&" "&$chnd)
   Local $name = ControlListView("", "", "[CLASS:SysListView32; INSTANCE:2]", "GetText",$b,0)
    Sleep(50)
   Local $number = ControlListView("", "", "[CLASS:SysListView32; INSTANCE:2]", "GetText",$b,3)
   Sleep(50)
    ;MsgBox("","",$name&" "&$number )
   $name = StringReplace(StringReplace($name,";", ""),"""","")
   $number = StringReplace(StringReplace($number,";", ""),"""","")  
   Sleep(50) ;НЕ МЕНЯТЬ!!!
   _GUICtrlListView_ClickItem($chnd, $b);кликаем по строчкам оборудованию
   Sleep(230) ;НЕ МЕНЯТЬ!!!
   Local $Pix = PixelGetColor(616,1006,'ESI[tronic] - Оборудование автомобиля')
   
  
   Global $pid
   ;Global $i
   Global $pid0
   Global $pid1
   Global $pid2
   Global $pid3
   Global $cleanname
   Global $cleannumber
  


												
												
																						   
												;MsgBox("","",$Pix)
	  If Not $Pix = 0 Then ;проверка на цвет конпки Ф8, если черная(активная, то нажимаем ф8)
	  
		 ;Local $z ='INSERT INTO detali(rb,name,pid) VALUES ('&'"'&$RBK&'"'&','&'"'&$name&'"'&','&'"'&$pid&'"'&');' ; вставляем значение рб ключа 1 раз в колонку рб
		 Local $z ='INSERT INTO detali(rb,name,pid) VALUES ('&'"'&$RBK&'"'&','&'"'&$name&'"'&','&'"'&$pid&'"'&');'
		 _SQLite_Exec(-1, $z)
		 Local $currenteqid=lastdetaliid()
	  Else
		 ControlClick("ESI[tronic]", "", "[CLASS:ToolbarWindow32; INSTANCE:4]","left","1","590","16") ;нажали ф8
		 Sleep(50) ;НЕ МЕНЯТЬ!!!
		 WinActivate ( "ESI[tronic] - Оборудование автомобиля" )
		 Sleep(50) ;НЕ МЕНЯТЬ!!!											 
		 Local $kn = ControlListView("ESI[tronic] - Оборудование автомобиля", "", "[CLASS:SysListView32; INSTANCE:5]", "GetItemCount" ) ;определяем количество строк
		 ;Local $z ='INSERT INTO detali(rb,name,number,pid) VALUES ('&'"'&$RBK&'"'&','&'"'&$name&'"'&','&'"'&$number&'"'&','&'"'&$pid&'"'&');' ; вставляем значение рб ключа 1 раз в колонку рб
		 Local $z ='INSERT INTO detali(rb,number) VALUES ('&'"'&$RBK&'"'&','&'"'&$number&'"'&');' 
		 _SQLite_Exec(-1, $z)
		 Local $currenteqid=lastdetaliid()
		 
		 Global $zQuery=""
			While $kn <> -1 ;цикл обхода описания номенклатуры 	
			   
			EqDetails($kn,$currenteqid)	
			_SQLite_Exec(-1, $zQuery)
			$kn = $kn -1 
			WEnd
		 Sleep(20)											
		 ControlClick("ESI[tronic]", "", "[CLASS:ToolbarWindow32; INSTANCE:4]","left","1","590","16") ;выход из описания номенклатуры
		 Sleep(50)
	  EndIf
   $pid=detaliparents($name,$currenteqid)
   Sleep(50)
   ;MsgBox("","",$name&" "&@CRLF&"pid"&$pid&" "&$pid0&" "&$pid1&" "&$pid2&" "&$pid3)
   ;Sleep(50)
   Next
Sleep(100)
ControlClick("ESI[tronic]", "", "[CLASS:ToolbarWindow32; INSTANCE:3]","left","1","70","10") ;кликаем по кнопке выход
Sleep(100)
EndIf
Sleep(100)
Next
Sleep(100)
Next
_SQLite_Close($sDbName)
_SQLite_Shutdown()


Func EqDetails($kn,$currenteqid)
Local $nm = ControlListView("ESI[tronic] - Оборудование автомобиля", "", "[CLASS:SysListView32; INSTANCE:5]", "GetText" , $kn, 0)
$nm = StringReplace(StringReplace($nm,";", ""),"""","")
if $nm<>""  Then
   Local $zn = '"'&ControlListView("ESI[tronic] - Оборудование автомобиля", "", "[CLASS:SysListView32; INSTANCE:5]", "GetText" , $kn, 1)&'"'
   $zn = StringReplace(StringReplace($zn,";", ""),"""","")
   Local $z ='SELECT uid FROM esi2 WHERE naim='&'"'&$nm&'"'&';'; текст запроса поиска вхождений наименования в таблицу соответвия
   Local $hQuery
   Local $aRow
   _SQLite_Query(-1, $z, $hQuery) ; выполняет запрос
   _SQLite_FetchData($hQuery, $aRow)
   If $aRow[0] Then
	  $zQuery &= 'UPDATE detali SET '&'id'&$aRow[0]&'='&'"'&$zn&'"'&' WHERE uid='&'"'&$currenteqid&'"'&';'&@CRLF ; вставляем значение 2-го поля в изи, в таблицу машин, в поле уида
	  _SQLite_Exec(-1, $z)
   Else
	  Local $z ='INSERT INTO esi2(naim) VALUES ('&'"'&$nm&'"'&');';&@CRLF&'SELECT uid FROM esi2 WHERE rowid=last_insert_rowid();'

	  _SQLite_Exec(-1, $z)
	  Local $z ='SELECT uid FROM esi2 WHERE rowid=last_insert_rowid();'
	  _SQLite_Query(-1, $z, $hQuery) ; выполняет запрос
	  _SQLite_FetchData($hQuery, $aRow)
	  Local $lastid = $aRow[0]
	  Local $z ='ALTER TABLE detali ADD COLUMN id'&$lastid&' varchar(255);'&@CRLF&'UPDATE detali SET id'&$lastid&'='&'"'&$zn&'"'&' WHERE uid='&'"'&$currenteqid&'"'&';'	
	  ;_SQLite_Exec(-1, $z)	
	  ;Local $z ='UPDATE detali SET id'&$lastid&'='&'"'&$zn&'"'&' WHERE uid='&'"'&$currenteqid&'"'&';' ; вставляем значение 2-го поля в изи, в таблицу машин, в поле уида
	  _SQLite_Exec(-1, $z)
   EndIf 
EndIf
EndFunc


Func lastdetaliid() 
   
 Local $z ='SELECT uid FROM detali WHERE rowid=last_insert_rowid();'
Local $hQuery
Local $aRow		
		_SQLite_Query(-1, $z, $hQuery) ; выполняет запрос
		 _SQLite_FetchData($hQuery, $aRow)
			Local $currenteqid = $aRow[0]
Return $currenteqid			
EndFunc


func detaliparents($name,$currenteqid)
   
If StringLeft($name, 9)="         " Then 
$cleanname=StringTrimLeft ( $name, 9 )

   ;$i=3
   $pid3=$currenteqid
   $pid=$pid2
   
ElseIf StringLeft($name, 5)="     " Then 
$cleanname=StringTrimLeft ( $name, 5 )

   ;$i=2
   $pid2=$currenteqid
   $pid=$pid1
   
ElseIf StringLeft($name, 2)="  " Then
$cleanname=StringTrimLeft ( $name, 2 )

   ;$i=1
   $pid1=$currenteqid
   $pid=$pid0
   
Else
   $cleanname=$name
   ;$i=0	
   $pid0=$currenteqid
   $pid=0

		EndIf  
		Local $z ='UPDATE detali SET pid='&'"'&$pid&'"'&',name='&'"'&$cleanname&'"'&' WHERE  uid='&'"'&$currenteqid&'"'&';' ; вставляем значение рб ключа 1 раз в колонку рбUPDATE detali SET '&'id'&$aRow[0]&'='&'"'&$zn&'"'&' WHERE uid='&'"'&$currenteqid&'"'&';' 
		 _SQLite_Exec(-1, $z)
Return $pid		
EndFunc
 

idbehold

Новичок
Сообщения
42
Репутация
4
Могу помочь с запросами. Опишите задачу поподробнее.
 
Автор
R

rivega

Новичок
Сообщения
45
Репутация
1
http://autoit-script.ru/index.php?topic=12705.msg81848#msg81848

Если не сложно будет..


Ситуация такая:
у меня на каждое извлечение информации из изитроника влечет за собой несколько запросов в бд.
1.смотрю таблицу(описание модели)(в скрипте между нажатиями ф7)
смотрю первую строку(наименование) и ищу ее в бд, если нету, то вношу в бд, вношу(значение)
смотрю вторую строку........(цикл по количеству строк)

2.смотрю таблицу "список делатей"
-смотрю первую строку беру наименование(название) и значение(каталожный номер) вношу в бд с пидом и уидом(цикл по количеству строк)
- нажимаю ф8(открывает таблицу список запчастей к детали):
смотрю первую строку(наименование) и ищу ее в бд, если нету, то вношу в бд, вношу(значение)
смотрю вторую строку........(цикл по количеству строк)....


в принципе последовательности в коде прослеживаются. Мне посто тут насоветовали, что вроде как можно все запросы к бд формировать в едином запросе......либо создавать промежуточную бд в памяти и потом ее вгружать в основную на диске.


Если моих путанных описаний не достаточно, то скажи, какую инфу предоставить.
 

idbehold

Новичок
Сообщения
42
Репутация
4
Доберусь до дома - разберемся. Можете, пока что, описать структуру таблиц?
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
rivega
Добавить в начало запроса BEGIN TRANSACTION; и в конец COMMIT;, а все строки импорта объединять в одну строку. Тогда работает быстро. Вот пример для изучения.

На счёт оптимизации:
1. "Step 1" обычно не пишут, так как это по умолчанию.
2. Используйте Tidy для себя же.


Добавлено:
Сообщение автоматически объединено:

Local внутри цикла? Некоторые избавляются от него вообще ради увеличения скорости. Если переменная не внутри функции то она является глобальной, видимой всем. Соответственно без определения Local она всё равно будет видимой всем.
По описанию на форуме я так и не понял почему используется Local вне функции если переменные видимы как глобальные и всё равно будут просматриваться.


Добавлено:
Сообщение автоматически объединено:

Код:
WinWait("ESI[tronic]")
Посмотрите команду в справке. Она возвращает дескриптор. В дельнейшем для всех вызовов используется дескриптор окна, это избавляет от сравнения с заголовком при каждом вызове.
 

denispuh

Новичок
Сообщения
1
Репутация
0
Интересует вопрос по поводу описания таблиц esi tronic . Где их можно нарыть?
 
Верх