Что нового

как найти ссылку в тексте html, пришедшем через GET запрос

eropov

Jury
Сообщения
195
Репутация
25
Привет всем.
Я решил модифицировать скрипт, вместо работы с IE переделать на отправку запросов.
У меня есть вопрос по работе с запросами к серверу(пример взят с форума).
Для отправки запроса я использую следующий код:
Код:
#include <IE.au3>
#include <Array.au3>

$sDomain = 'www.bwc.ru' ;домен или ip-адрес
$iPort = 80 ;порт

;Запрос, который будет отправлен серверу
$sRequest = 'GET /cgi-bin/smssend.cgi HTTP/1.1' & @CRLF ;Request-строка, параметры GET-запроса
$sRequest &= 'Host: www.bwc.ru' & @CRLF
$sRequest &= 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1' & @CRLF
$sRequest &= 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' & @CRLF
$sRequest &= 'Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3' & @CRLF
$sRequest &= 'Accept-Encoding: gzip, deflate' & @CRLF
$sRequest &= 'Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7' & @CRLF
$sRequest &= 'Keep-Alive: 115' & @CRLF
$sRequest &= 'Connection: keep-alive' & @CRLF & @CRLF

If TCPStartup() = 0 Then ;запускаем TCP/UDP-службы
    MsgBox(16, 'Ошибка', 'Не удалось запустить TCP/UDP-службы.')
    Exit 1
EndIf

$sIP = TCPNameToIP($sDomain) ;получаем ip-адрес

If @error Then
    MsgBox(16, 'Ошибка', 'Не удалось получить ip-адрес сервера.')
    Exit 2
EndIf

$iSocket = TCPConnect($sIP, $iPort) ;соединяемся с сервером

If @error Then
    MsgBox(16, 'Ошибка', 'Не удалось соедениться с сервером.')
    Exit 3
EndIf

TCPSend($iSocket, $sRequest) ;отправляем сообщение

If @error Then
    MsgBox(16, 'Ошибка', 'Не удалось отправить запрос.')
    Exit 4
EndIf

$sData = ''
$iTimer = TimerInit() ;запускаем таймер

Do
    $sBuffer = TCPRecv($iSocket, 1024) ;получаем часть сообщения сервера
    $iError = @error
    If Not $sBuffer = '' Then ;если удалось получить сообщение
        $sData &= $sBuffer ;сохраняем полученное сообщение
        $iTimer = TimerInit() ;обнуляем таймер
    EndIf
Until $iError <> 0 Or TimerDiff($iTimer) > 5000 ;если при получении сообщения произошла ошибка (данные получены, соединение закрыто) или в течении 5 секунд ничего не было получено, выход из цикла

TCPCloseSocket($iSocket)
TCPShutdown()

$aData = StringRegExp($sData, '(?s)(.*?)\r\n\r\n(.*)', 3) ;отделяем http-заголовки от тела сообщения ('заголовки' & @CRLF & @CRLF & 'тело')

If @error Then
    MsgBox(16, 'Ошибка', 'Полученные данные неверны.')
    Exit 5
EndIf


$fileo = FileOpen("C:\Текстовый документ.txt",2)
$filew = FileWrite("C:\Текстовый документ.txt", $aData[1])
$filec = FileClose("C:\Текстовый документ.txt")

MsgBox(1,"", $aData[1])
MsgBox(1,"", $aData[1]) выводит html сайта, как вытащить ссылку такого вида (src="img2img.cgi?img=456e63cb248cffd1e9cc0abc4875ea5a") это картинка(captcha)
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
eropov,
Попробуйте сделать так:
Код:
;...
TCPCloseSocket($iSocket)
TCPShutdown()

;$aData = StringRegExp($sData, '(?s)(.*?)\r\n\r\n(.*)', 3) ;отделяем http-заголовки от тела сообщения ('заголовки' & @CRLF & @CRLF & 'тело')
;If @error Then
;    MsgBox(16, 'Ошибка', 'Полученные данные неверны.')
;    Exit 5
;EndIf
$sUrl = StringRegExpReplace($sData, '(?si).*?id="code_img.*?src="(.*?)"\s?/>.*', 'http://bwc.ru/cgi-bin/$1')
ConsoleWrite($sUrl & @LF)
InetGet($sUrl, @ScriptDir & '\img.png')


Или так, без скачивания.
Код:
#include <GDIPlus.au3>
#include <Memory.au3>
#include <WinAPIEx.au3>

Global Const $STM_SETIMAGE = 0x0172
Global Const $STM_GETIMAGE = 0x0173
Global $hForm, $Pic, $hPic, $hBitmap, $hObj, $hImage, $hStream, $bData, $hData, $pData, $tData, $Width, $Height, $Lenght

$sDomain = 'www.bwc.ru' ;домен или ip-адрес
$iPort = 80 ;порт

;Запрос, который будет отправлен серверу
$sRequest = 'GET /cgi-bin/smssend.cgi HTTP/1.1' & @CRLF ;Request-строка, параметры GET-запроса
$sRequest &= 'Host: www.bwc.ru' & @CRLF
$sRequest &= 'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1' & @CRLF
$sRequest &= 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' & @CRLF
$sRequest &= 'Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3' & @CRLF
$sRequest &= 'Accept-Encoding: gzip, deflate' & @CRLF
$sRequest &= 'Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7' & @CRLF
$sRequest &= 'Keep-Alive: 115' & @CRLF
$sRequest &= 'Connection: keep-alive' & @CRLF & @CRLF

If TCPStartup() = 0 Then ;запускаем TCP/UDP-службы
	MsgBox(16, 'Ошибка', 'Не удалось запустить TCP/UDP-службы.')
	Exit 1
EndIf

$sIP = TCPNameToIP($sDomain) ;получаем ip-адрес

If @error Then
	MsgBox(16, 'Ошибка', 'Не удалось получить ip-адрес сервера.')
	Exit 2
EndIf

$iSocket = TCPConnect($sIP, $iPort) ;соединяемся с сервером

If @error Then
	MsgBox(16, 'Ошибка', 'Не удалось соедениться с сервером.')
	Exit 3
EndIf

TCPSend($iSocket, $sRequest) ;отправляем сообщение

If @error Then
	MsgBox(16, 'Ошибка', 'Не удалось отправить запрос.')
	Exit 4
EndIf

$sData = ''
$iTimer = TimerInit() ;запускаем таймер

Do
	$sBuffer = TCPRecv($iSocket, 1024) ;получаем часть сообщения сервера
	$iError = @error
	If Not $sBuffer = '' Then ;если удалось получить сообщение
		$sData &= $sBuffer ;сохраняем полученное сообщение
		$iTimer = TimerInit() ;обнуляем таймер
	EndIf
Until $iError <> 0 Or TimerDiff($iTimer) > 5000 ;если при получении сообщения произошла ошибка (данные получены, соединение закрыто) или в течении 5 секунд ничего не было получено, выход из цикла

TCPCloseSocket($iSocket)
TCPShutdown()

$sUrl = StringRegExpReplace($sData, '(?si).*?id="code_img.*?src="(.*?)"\s?/>.*', 'http://bwc.ru/cgi-bin/$1')
If @extended <> 1 Then
	MsgBox(16, 'Ошибка', 'Полученные данные неверны.')
	Exit 5
EndIf
ConsoleWrite(@extended & @TAB & $sUrl & @LF)
$bData = InetRead($sUrl, 17)
If @error Then
	MsgBox(16, 'Ошибка', 'Ошибка')
	Exit 6
EndIf
$Lenght = BinaryLen($bData)
$hData = _MemGlobalAlloc($Lenght, 2)
$pData = _MemGlobalLock($hData)
$tData = DllStructCreate('byte[' & $Lenght & ']', $pData)
DllStructSetData($tData, 1, $bData)
_MemGlobalUnlock($hData)
$hStream = _WinAPI_CreateStreamOnHGlobal($hData)
_GDIPlus_Startup()
$hImage = _GDIPlus_BitmapCreateFromStream($hStream)
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$Width = _GDIPlus_ImageGetWidth($hImage)
$Height = _GDIPlus_ImageGetHeight($hImage)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()

$hForm = GUICreate('MyGUI', $Width + 100, $Height + 100)
$Pic = GUICtrlCreatePic('', 10, 10)
$hPic = GUICtrlGetHandle($Pic)
_SendMessage($hPic, $STM_SETIMAGE, 0, $hBitmap)
$hObj = _SendMessage($hPic, $STM_GETIMAGE)
If $hObj <> $hBitmap Then
	_WinAPI_DeleteObject($hBitmap)
EndIf
GUISetState()

Do
Until GUIGetMsg() = -3

Func _GDIPlus_BitmapCreateFromStream($hStream)
	Local $aResult = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromStream', 'ptr', $hStream, 'int*', 0)
	If @error Then
		Return SetError(@error, @extended, 0)
	EndIf
	Return $aResult[2]
EndFunc   ;==>_GDIPlus_BitmapCreateFromStream
 
Автор
E

eropov

Jury
Сообщения
195
Репутация
25
Спасибо madmasles все хорошо работает :ok:
Второй вариант не работает не находит #include <WinAPIEx.au3>
Не подскажите как получить cookie
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
eropov [?]
не находит #include <WinAPIEx.au3>
Ссылка в моей подписи.

как получить cookie
Сookie в данном случае появятся только после отправки кода CAPTCHA. Они будут в заголовке. Получайте заголовок
Код:
;...
TCPCloseSocket($iSocket)
TCPShutdown()
$aData = StringRegExp($sData, '(?s)(.*?)\r\n\r\n(.*)', 3)
If Not @error Then
	MsgBox(64, 'Info', $aData[0])
EndIf
И "выковыривайте" их оттуда.
 
Автор
E

eropov

Jury
Сообщения
195
Репутация
25
Сookie в данном случае появятся только после отправки кода CAPTCHA. Они будут в заголовке.
Как я понял чтобы получить cookie нужно отправить еще один запрос с ссылкой на captcha, но я думаю , что куки должны приходить еще при первом запросе т.к. я просмотрел запросы на сервер через плагин firefox и у меня все манипуляции с сайтом прошли в три этапа два первых get а третий post запросы.
Первый запрос представляет собой то что мы описали выше(страничка с формой)
Второй запрос ссылается на ссылку с captcha и в нем уже передаются cookie, хотя в первом запросе их не передавали и не получали(может я что, то делаю не так)
Третий post запрос это когда мы заполнили форму и отправляем ее
Мне cookie для этого и нужны что без них не отправить post запрос
 
Верх