Что нового

[Данные, строки, WinHTTP]Прочитать JSON ответ сервера, извлечь данные

valldar

Новичок
Сообщения
32
Репутация
2
Вдохновленный вот этой темой, накатал скрипт для заливки картинок на avit0.ru

Код:
#Include <winhttp.au3>
#Include <array.au3>

$sLocalFile = FileOpenDialog('Select Image To upload', 'c:\', 'Все (*.*)')
If @Error Then
	MsgBox(0, 'Error', 'FileOpen Error ' & @Error)
	Exit
EndIf
$sFileRead = FileRead($sLocalFile)
$sFileType = _TCPGetMIMEType(StringRegExpReplace($sLocalFile, '^.*\\', '')) ; см. примечание в конце сообщения
$Boundary = 'Jc0H5MXlYC527Z3W'
$imageUploadHeaders = 'Host: www.avito.ru' & @CRLF & _
		'Proxy-Connection: keep-alive' & @CRLF & _
		'Content-Type: multipart/form-data; boundary=----WebKitFormBoundary' & $Boundary & @CRLF & _
		'Accept: */*' & @CRLF & _
		'Referer: http://www.avito.ru/additem' & @CRLF & _
		'Accept-Encoding:gzip,deflate,sdch' & @CRLF & _
		'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4'
$imageUploadData = '------WebKitFormBoundary' & $Boundary & @CRLF & _
		'Content-Disposition: form-data; name="image"; filename="' & StringRegExpReplace($sLocalFile, '^.*\\', '') & '"' & @CRLF & _
		'Content-Type: ' & $sFileType & @CRLF & @CRLF & _
		$sFileRead & @CRLF & '------WebKitFormBoundary' & $Boundary & '--' & @CRLF

$hOpen = _WinHttpOpen('Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)')
$hConnect = _WinHttpConnect($hOpen, 'www.avito.ru')
$slData = _WinHttpSimpleRequest($hConnect, 'get', '/additem')
$sdata = _WinHttpSimpleRequest($hConnect, 'post', '/additem/image', Default, $imageUploadData, $imageUploadHeaders)
MsgBox(0, '', $sdata) ; ничего нет, кроме двух символов
MsgBox(0, '', StringReplace($sdata, Chr(0), ' '))
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)


Все прекрасно, все работает, НО не могу прочитать ответ сервера после загрузки картинки. Там должен содержаться id закаченной картинки.
Ответ сервака выглядит следующим образом:

Image 001.png


Как быть? Что это за кодировка?
Сам экспериментировал с разными кодировками, записывал в файл - все без результата.

Примечание: Функция _TCPGetMIMEType
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Json - это формат данных, записанный таким вот способом как у вас на скриншоте.
К примеру:
{"host":"54.img.avito.st","id":"540072854"}
Все данные вам вернули id = 540072854 а host=54.img.avito.st
В autoit нет функций для разбора этого формата. Можете написать регулярку или же пользоваться библиотекой
Примеры для нее есть в этой теме
 
Автор
V

valldar

Новичок
Сообщения
32
Репутация
2
Спасибо за ответ
Я скачал эту UDF, вот что получилось:
Код:
#Include <winhttp.au3>
#Include <array.au3>
#include <JSMN.au3>

$sFileRead = FileRead($sLocalFile)
$sFileType = _TCPGetMIMEType(StringRegExpReplace($sLocalFile, '^.*\\', ''))
$Boundary = 'Jc0H5MXlYC527Z3W'
$imageUploadHeaders = 'Host: www.avito.ru' & @CRLF & _
		'Proxy-Connection: keep-alive' & @CRLF & _
		'Content-Type: multipart/form-data; boundary=----WebKitFormBoundary' & $Boundary & @CRLF & _
		'Accept: */*' & @CRLF & _
		'Referer: http://www.avito.ru/additem' & @CRLF & _
		'Accept-Encoding:gzip,deflate,sdch' & @CRLF & _
		'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4'
$imageUploadData = '------WebKitFormBoundary' & $Boundary & @CRLF & _
		'Content-Disposition: form-data; name="image"; filename="' & StringRegExpReplace($sLocalFile, '^.*\\', '') & '"' & @CRLF & _
		'Content-Type: ' & $sFileType & @CRLF & @CRLF & _
		$sFileRead & @CRLF & '------WebKitFormBoundary' & $Boundary & '--' & @CRLF

$hOpen = _WinHttpOpen('Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)')
$hConnect = _WinHttpConnect($hOpen, 'www.avito.ru')
$sData = _WinHttpSimpleRequest($hConnect, 'get', '/additem')
;$sdata = BinaryToString(_WinHttpSimpleRequest($hConnect, 'post', '/additem/image', Default, $imageUploadData, $imageUploadHeaders),4)
$sdata = _WinHttpSimpleRequest($hConnect, 'post', '/additem/image', Default, $imageUploadData, $imageUploadHeaders)
$oJSON = Jsmn_Encode($sData)
$1=Jsmn_ObjGetKeys($oJSON)
$2=Jsmn_ObjGet($oJSON, 'id')
ConsoleWrite('> Keys: ' & $1 & @LF)
ConsoleWrite('> Id: ' & $2 & @LF)
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)


На выходе получаю ошибку:
Код:
C:\Program Files\AutoIt3\Include\JSMN.au3 (420) : ==> Variable must be of type "Object".:
Return $Object.Keys()
Return $Object^ ERROR
Суть ошибки мне понятна, требуется тип переменной "Объект", но откуда берется этот объект?
Я явно что-то делаю не так, но что именно не понимаю.
Код:
;Может необходимо как-то обработать ответ сервера, прежде чем передавать его функции Jsmn_Encode?
$sdata = _WinHttpSimpleRequest($hConnect, 'post', '/additem/image', Default, $imageUploadData, $imageUploadHeaders)
$oJSON = Jsmn_Encode($sData)
 
Автор
V

valldar

Новичок
Сообщения
32
Репутация
2
ivsatel, это было бы слишком просто ;D
Дело в том, что вот эта строка
Код:
$sData = '{"host":"54.img.avito.st","id":"540072854"}'

должна приходить как ответ вот на этот запрос
Код:
$sdata = _WinHttpSimpleRequest($hConnect, 'post', '/additem/image', Default, $imageUploadData, $imageUploadHeaders)

т.е. ее содержание мне заранее не известно.
Вся суть в том чтобы, выдернуть ID картинки из ответа на запрос :smile:
А я вместо этого получаю крякозябры((
 

ivsatel

Продвинутый
Сообщения
319
Репутация
84
valldar
Да, я поторопился...
А если в заголовке исправить на:
Код:
'Accept-Encoding:*/*'
и вывод прочитать так:
Код:
ConsoleWrite(BinaryToString($sData, 4)&@LF)

Что-то меняется?
У меня вот так получилось:
Код:
#Include <winhttp.au3>
#Include <array.au3>
#include <JSMN.au3>

$sLocalFile = @ScriptDir&'\FreeSpace.jpeg'
$sFileRead = FileRead($sLocalFile)
$sFileType = _TCPGetMIMEType(StringRegExpReplace($sLocalFile, '^.*\\', ''))
$Boundary = 'Jc0H5MXlYC527Z3W'
$imageUploadHeaders = 'Host: www.avito.ru' & @CRLF & _
        'Proxy-Connection: keep-alive' & @CRLF & _
        'Content-Type: multipart/form-data; boundary=----WebKitFormBoundary' & $Boundary & @CRLF & _
        'Accept: */*' & @CRLF & _
        'Referer: http://www.avito.ru/additem' & @CRLF & _
        'Accept-Encoding:*/*' & @CRLF & _
        'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4'
$imageUploadData = '------WebKitFormBoundary' & $Boundary & @CRLF & _
        'Content-Disposition: form-data; name="image"; filename="' & StringRegExpReplace($sLocalFile, '^.*\\', '') & '"' & @CRLF & _
        'Content-Type: ' & $sFileType & @CRLF & @CRLF & _
        $sFileRead & @CRLF & '------WebKitFormBoundary' & $Boundary & '--' & @CRLF

$hOpen = _WinHttpOpen('Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)')
$hConnect = _WinHttpConnect($hOpen, 'www.avito.ru')
$sData = _WinHttpSimpleRequest($hConnect, 'get', '/additem')
;$sdata = BinaryToString(_WinHttpSimpleRequest($hConnect, 'post', '/additem/image', Default, $imageUploadData, $imageUploadHeaders),4)
$sdata = _WinHttpSimpleRequest($hConnect, 'post', '/additem/image', Default, $imageUploadData, $imageUploadHeaders)

$oJSON = Jsmn_Decode($sData)
$1=Jsmn_ObjGetKeys($oJSON)
$2=Jsmn_ObjGet($oJSON, 'id')
ConsoleWrite('> Keys: ' & $1 & @LF)
ConsoleWrite('> Id: ' & $2 & @LF)

ConsoleWrite(BinaryToString($sdata, 4)&@LF)

_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)

Func _TCPGetMIMEType($sFileName)
    Local $sMIMEAssocString = ";ai|application/postscript;aif|audio/x-aiff;aifc|audio/x-aiff;aiff|audio/x-aiff;asc|text/plain;atom|application/atom+xml;au|audio/basic;avi|video/x-msvideo;bcpio|application/x-bcpio;bin|application/octet-stream;bmp|image/bmp;cdf|application/x-netcdf;cgm|image/cgm;class|application/octet-stream;cpio|application/x-cpio;cpt|application/mac-compactpro;csh|application/x-csh;css|text/css;dcr|application/x-director;dif|video/x-dv;dir|application/x-director;djv|image/vnd.djvu;djvu|image/vnd.djvu;dll|application/octet-stream;dmg|application/octet-stream;dms|application/octet-stream;doc|application/msword;dtd|application/xml-dtd;dv|video/x-dv;dvi|application/x-dvi;dxr|application/x-director;eps|application/postscript;etx|text/x-setext;exe|application/octet-stream;ez|application/andrew-inset;gif|image/gif;gram|application/srgs;grxml|application/srgs+xml;gtar|application/x-gtar;hdf|application/x-hdf;hqx|application/mac-binhex40;htm|text/html;html|text/html;ice|x-conference/x-cooltalk;ico|image/x-icon;ics|text/calendar;ief|image/ief;ifb|text/calendar;iges|model/iges;igs|model/iges;jnlp|application/x-java-jnlp-file;jp2|image/jp2;jpe|image/jpeg;jpeg|image/jpeg;jpg|image/jpeg;js|application/x-javascript;kar|audio/midi;latex|application/x-latex;lha|application/octet-stream;lzh|application/octet-stream;m3u|audio/x-mpegurl;m4a|audio/mp4a-latm;m4b|audio/mp4a-latm;m4p|audio/mp4a-latm;m4u|video/vnd.mpegurl;m4v|video/x-m4v;mac|image/x-macpaint;man|application/x-troff-man;mathml|application/mathml+xml;me|application/x-troff-me;mesh|model/mesh;mid|audio/midi;midi|audio/midi;mif|application/vnd.mif;mov|video/quicktime;movie|video/x-sgi-movie;mp2|audio/mpeg;mp3|audio/mpeg;mp4|video/mp4;mpe|video/mpeg;mpeg|video/mpeg;mpg|video/mpeg;mpga|audio/mpeg;ms|application/x-troff-ms;msh|model/mesh;mxu|video/vnd.mpegurl;nc|application/x-netcdf;oda|application/oda;ogg|application/ogg;pbm|image/x-portable-bitmap;pct|image/pict;pdb|chemical/x-pdb;pdf|application/pdf;pgm|image/x-portable-graymap;pgn|application/x-chess-pgn;pic|image/pict;pict|image/pict;png|image/png;pnm|image/x-portable-anymap;pnt|image/x-macpaint;pntg|image/x-macpaint;ppm|image/x-portable-pixmap;ppt|application/vnd.ms-powerpoint;ps|application/postscript;qt|video/quicktime;qti|image/x-quicktime;qtif|image/x-quicktime;ra|audio/x-pn-realaudio;ram|audio/x-pn-realaudio;ras|image/x-cmu-raster;rdf|application/rdf+xml;rgb|image/x-rgb;rm|application/vnd.rn-realmedia;roff|application/x-troff;rtf|text/rtf;rtx|text/richtext;sgm|text/sgml;sgml|text/sgml;sh|application/x-sh;shar|application/x-shar;silo|model/mesh;sit|application/x-stuffit;skd|application/x-koan;skm|application/x-koan;skp|application/x-koan;skt|application/x-koan;smi|application/smil;smil|application/smil;snd|audio/basic;so|application/octet-stream;spl|application/x-futuresplash;src|application/x-wais-source;sv4cpio|application/x-sv4cpio;sv4crc|application/x-sv4crc;svg|image/svg+xml;swf|application/x-shockwave-flash;t|application/x-troff;tar|application/x-tar;tcl|application/x-tcl;tex|application/x-tex;texi|application/x-texinfo;texinfo|application/x-texinfo;tif|image/tiff;tiff|image/tiff;tr|application/x-troff;tsv|text/tab-separated-values;txt|text/plain;ustar|application/x-ustar;vcd|application/x-cdlink;vrml|model/vrml;vxml|application/voicexml+xml;wav|audio/x-wav;wbmp|image/vnd.wap.wbmp;wbmxl|application/vnd.wap.wbxml;wml|text/vnd.wap.wml;wmlc|application/vnd.wap.wmlc;wmls|text/vnd.wap.wmlscript;wmlsc|application/vnd.wap.wmlscriptc;wrl|model/vrml;xbm|image/x-xbitmap;xht|application/xhtml+xml;xhtml|application/xhtml+xml;xls|application/vnd.ms-excel;xml|application/xml;xpm|image/x-xpixmap;xsl|application/xml;xslt|application/xslt+xml;xul|application/vnd.mozilla.xul+xml;xwd|image/x-xwindowdump;xyz|chemical/x-xyz;zip|application/zip;"

    Local $aArray = StringRegExp($sMIMEAssocString, "(?i)\Q;" & StringRegExpReplace($sFileName, ".*\.", "") & "\E\|(.*?);", 3)
    If @error Then Return "application/octet-stream"
    Return $aArray[0]
EndFunc
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
valldar
Вы получаете не "кракозябры" а ответ в gzip :smile:

P.s ivsatel valldar функция _TCPGetMIMEType вам ненужна, она уже есть, но называется __WinHttpMIMEType
 
Автор
V

valldar

Новичок
Сообщения
32
Репутация
2
ivsatel получилось, то что надо! :ok:
Все заголовки я брал непосредственно из браузера, не знал что их можно так менять :D

inververs, у меня нет такой функции в паке include, но это мелочи)
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
valldar
ну начнете разбираться в языке, поймете что я имел ввиду. ;)
 
Верх