Что нового

RegExp Парсинг со страницы или файла

Пост номер 6 был отмечен как лучший ответ.

TiranCool

Новичок
Сообщения
68
Репутация
0
Ребят, не получается получить данные со страницы, помогите пожалуйста разобраться, вроде все должно быть сделано правильно
Код:
#include <Inet.au3>
#include <IE.au3>
 $logins = FileReadToArray(@ScriptDir & "\log.txt") ;берем логины из файла
if IsArray($logins) Then
    For $login In $logins
        $url = "https://ru.wargaming.net/clans/wot/" & $login
        ConsoleWrite("Проверяем " & $url & @CRLF)
        $str = InetRead($url, 1) ;запрашиваем страницу для каждого логина
        $str = BinaryToString($str, 16)
;~         MsgBox(0,'',$str)
        ConsoleWrite("Получено " & StringLen($str) & @CRLF)
         $tanks10lvl = StringRegExp($str, '<span class=(.*)/span>', 3) ;парсим список
          MsgBox(0,'',$tanks10lvl)
       If IsArray($tanks10lvl) Then
                For $tank In $tanks10lvl
                $name = StringRegExp($tank, 'member_name">(.*)<', 1) ;из списка парсим имя
          MsgBox(0,'',$name)
                FileWriteLine($File,$name)
                FileWriteLine(@ScriptDir & "\save.txt",$name) ;пишем в файл
            Next
        Else
             FileWriteLine(@ScriptDir & "\save.txt", $login & ";")
        EndIf
    Next
    Else
    ConsoleWrite("Список логинов не получен" & @CRLF)
    Exit
EndIf

А так хотелось бы парсить прям с сайта.
Сего хотелось бы добиться:
Взять список 100 кланов, по ним отсортировать кто вышел из клана за последние сутки, просмотреть имеется ли у них к примеру 2 определенных танка и отправить приглашение в клан.
Заранее Спасибо!
 

gunter123

Продвинутый
Сообщения
130
Репутация
52
Привет. Написал вот небольшой скрипт, он читает лог кланов и записывает в файл всех кто ливнул за последние N дней в файл в формате имя@ссылка.

Код:
#include <Array.au3>
#include <Date.au3>

$aLogins = FileReadToArray(@ScriptDir & "\ids.txt") ;берем id кланов из файла
If Not IsArray($aLogins) Then Exit MsgBox(4096, "", "Файл с ID не найден")

$sMinDate = _DateAdd('D', -10, _NowCalc()) ; Последние 10 дней

For $sLogin In $aLogins
   $sUrl = "https://ru.wargaming.net/clans/wot/" & $sLogin & "/newsfeed/api/events/?date_until=2021-01-01T00%3A00%3A00%2B00%3A00&offset=10800"
   ConsoleWrite("Проверяем " & $sUrl & @CRLF)
   $sHtml = BinaryToString(InetRead($sUrl, 8), 16)
   ;ConsoleWrite($sHtml)

   $aPlayers = StringRegExp($sHtml, '"subtype":"leave_clan"(.+?)}}}', 3) ; Массив всех игроков что ливнули из клана
   ;_ArrayDisplay($aPlayers)

   For $sPlayers In $aPlayers
      If _DateDiff('s', $sMinDate, StringRegExp($sPlayers, '"created_at":"(.+?)"', 3)[0]) > 0 Then ; Отсеиваем тех что вышли из кланов давно
         $sPlayerName = StringRegExp($sPlayers, '"name":"(.+?)"', 3)[0]
         ConsoleWrite($sPlayerName & @CRLF)
         $sPlayerUrl = StringRegExp($sPlayers, '"url":"(.+?)"', 3)[0]

         FileWrite(@ScriptDir & '/result.txt', $sPlayerName & '@' & $sPlayerUrl & @CRLF)
      EndIf
   Next
Next


Содержимое файла ids.txt:
56982
 
Автор
T

TiranCool

Новичок
Сообщения
68
Репутация
0
Привет, Gunter123.
Все работает, но если вышло 2 и более одновременно, то он выдает только первого из списка.
Вот пример на том же клане:
Покинули клан
Игроки (2) покинули клан: Oppressors, Yahoooo_eu
[email protected]/clans/wot/search/#wgsearch&search=Oppressors&type=accounts&account_id=33865582
[email protected]/clans/wot/search/#wgsearch&search=Cousin_Avi_Denovitz&type=accounts&account_id=29755645
 
Последнее редактирование:

gunter123

Продвинутый
Сообщения
130
Репутация
52
Да, действительно. Попробуйте эту версию:

Код:
#include <Array.au3>
#include <Date.au3>

$aLogins = FileReadToArray(@ScriptDir & "\ids.txt") ;берем id кланов из файла
If Not IsArray($aLogins) Then Exit MsgBox(4096, "", "Файл с ID не найден")

$sMinDate = _DateAdd('D', -1, _NowCalc()) ; Последние 10 дней

For $sLogin In $aLogins
   $sUrl = "https://ru.wargaming.net/clans/wot/" & $sLogin & "/newsfeed/api/events/?date_until=2021-01-01T00%3A00%3A00%2B00%3A00&offset=10800"
   ConsoleWrite("Проверяем " & $sUrl & @CRLF)
   $sHtml = BinaryToString(InetRead($sUrl, 8), 16)
   ;ConsoleWrite($sHtml)

   $aPlayers = StringRegExp($sHtml, '"subtype":"leave_clan"(.+?)}}}', 3) ; Массив всех игроков что ливнули из клана
   ;_ArrayDisplay($aPlayers)

   For $sPlayers In $aPlayers
      If _DateDiff('s', $sMinDate, StringRegExp($sPlayers, '"created_at":"(.+?)"', 3)[0]) > 0 Then ; Отсеиваем тех что вышли из кланов давно
         $sAccounts = StringRegExp($sPlayers, '"accounts_info":(.+)', 3)[0]
         $aPlayerNames = StringRegExp($sAccounts, '"name":"(.+?)"', 3)
         $aPlayerUrls = StringRegExp($sAccounts, '"url":"(.+?)"', 3)

         For $iPlayerNumber = 0 To UBound($aPlayerNames) -1
            FileWrite(@ScriptDir & '/result.txt', $aPlayerNames[$iPlayerNumber] & '@' & $aPlayerUrls[$iPlayerNumber] & @CRLF)
         Next
      EndIf
   Next
Next
 
Автор
T

TiranCool

Новичок
Сообщения
68
Репутация
0
Привет, Gunter123.
Спасибо, работает, буду дальше думать как довести до желаемого результата.
Сообщение автоматически объединено:

Понять не могу откуда взял "/newsfeed/api/events/?date_until=2021-01-01T00%3A00%3A00%2B00%3A00&offset=10800" ?
 
Последнее редактирование:

gunter123

Продвинутый
Сообщения
130
Репутация
52
В браузере Chrome откройте новую вкладку, нажмите F12. В появившейся панели откройте вкладку Network, нажмите на XHR. Перейдите на страницу клана. В таблице будут видны все "левые" запросы, из которых на главной странице появляются данные. Один из таких запросов содержит JSON массив со всеми событиями клана, включая данные о игроках, покинувших клан. Чтобы просмотреть отформатированный ответ запроса, откройте вкладку Response, скопируйте содержимое и закиньте в любой Json Formatter, например https://jsonformatter.curiousconcept.com/
wot.png
Сообщение автоматически объединено:

Решил дописать скрипт. Теперь он еще проверяет список танков каждого игрока.

Код:
#include <Array.au3>
#include <Date.au3>

$hFile = FileOpen(@ScriptDir & '/result.txt', 2)
$aLogins = FileReadToArray(@ScriptDir & "/clanList.txt") ;берем id кланов из файла
If Not IsArray($aLogins) Then Exit MsgBox(4096, "", "Файл с ID не найден")

$aTankList = FileReadToArray(@ScriptDir & "/tankList.txt") ; В файле tankList должны быть ID танков, по 1 в каждой строке. ID ищем в файле tankInfo.txt
$sMinDate = _DateAdd('D', -1, _NowCalc()) ; Последние 10 дней

For $sLogin In $aLogins
   $sUrl = "https://ru.wargaming.net/clans/wot/" & $sLogin & "/newsfeed/api/events/?date_until=2021-01-01T00%3A00%3A00%2B00%3A00&offset=10800"
   ConsoleWrite("Проверяем " & $sUrl & @CRLF)
   $sHtml = BinaryToString(InetRead($sUrl, 8), 16)
   ;ConsoleWrite($sHtml)

   $aPlayers = StringRegExp($sHtml, '"subtype":"leave_clan"(.+?)}}}', 3) ; Массив всех игроков что ливнули из клана
   ;_ArrayDisplay($aPlayers)

   For $sPlayers In $aPlayers
      If _DateDiff('s', $sMinDate, StringRegExp($sPlayers, '"created_at":"(.+?)"', 3)[0]) > 0 Then ; Отсеиваем тех что вышли из кланов давно
         $sAccounts = StringRegExp($sPlayers, '"accounts_info":(.+)', 3)[0]
         $aPlayerNames = StringRegExp($sAccounts, '"name":"(.+?)"', 3)
         $aPlayerUrls = StringRegExp($sAccounts, '"url":"(.+?)"', 3)

         For $iPlayerNumber = 0 To UBound($aPlayerNames) -1
            ; Проверяем список танков игрока
            $sPlayerId = StringRegExp($aPlayerUrls[$iPlayerNumber], 'account_id=(\d+)', 3)[0]

            $oHttp = ObjCreate("winhttp.winhttprequest.5.1")
            $oHttp.Open("GET", 'https://ru.wargaming.net/clans/wot/vehicles/account/' & $sPlayerId & '/?offset=0&limit=1000&order=&battle_type=default', False)
            $oHttp.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36")
            $oHttp.SetRequestHeader("X-Requested-With", 'XMLHttpRequest')
            $oHttp.SetRequestHeader("Accept", 'application/json, text/javascript, */*; q=0.01')
            $oHttp.SetRequestHeader("Sec-Fetch-Mode", 'cors')
            $oHttp.Send()
            ;ConsoleWrite($aPlayerNames[$iPlayerNumber] & ' --- > ' & $oHTTP.ResponseText)  ; <<< ------------ Массив всех танков игрока

            $sTanks = StringRegExp($oHttp.ResponseText, '"items": \[(.+?)\]', 3)[0]
            $bNotFound = False
            For $sTankId In $aTankList    ; Проверяем, есть ли у игрока все танки из списка
               If Not StringInStr($sTanks, '"vehicle_id": ' & $sTankId & ',') Then
                  ConsoleWrite('У игрока ' & $aPlayerNames[$iPlayerNumber] & ' нет танка #' & $sTankId & @CRLF)
                  $bNotFound = True
                  ExitLoop
               EndIf
            Next

            ; Если у игрока есть все танки из списка, пишем его в файл
            If Not $bNotFound Then
               FileWrite($hFile, $aPlayerNames[$iPlayerNumber] & '@' & $aPlayerUrls[$iPlayerNumber] & @CRLF)
               ConsoleWrite('Записали игрока ' & $aPlayerNames[$iPlayerNumber] & @CRLF)
            EndIf
         Next
      EndIf
   Next
Next

Создаем в директории со скриптом файл tankList.txt. В него пишем список ID танков, по которым ищем игроков. ID танков можно взять из еще одного скрипта:

Код:
#include <Array.au3>

$sPage = InetRead('https://ru.wargaming.net/clans/wot/search/#wgsearch&search=Law_Concrete_Jungle&type=accounts&account_id=42154685&limit=10&accounts-battle_type=random', 8)
If @error Then Exit MsgBox(4096, '', 'Ошибка загрузки страницы с танками')
$sPage = BinaryToString($sPage, 16)

$hFile = FileOpen(@ScriptDir & '/tankInfo.txt', 2)

$sTanks = StringRegExp($sPage, 'vehicles: \[(.+?)\]', 3)[0]
$sTanks = _Encoding_JavaUnicodeDecode($sTanks)

$aTanks = StringRegExp($sTanks, '{(.+?)}', 3)
For $sTank In $aTanks
   $sTankInfo = StringRegExp($sTank, '"id": (\d+)', 3)[0] & ':' & StringRegExp($sTank, '"vehicle_name": "(.+?)"', 3)[0]
   FileWrite($hFile, $sTankInfo & @CRLF)
   ConsoleWrite($sTankInfo & @CRLF)
Next

Func _Encoding_JavaUnicodeDecode($sString)
    Local $iOld_Opt_EVS = Opt('ExpandVarStrings', 0)
    Local $iOld_Opt_EES = Opt('ExpandEnvStrings', 0)

    Local $sOut = "", $aString = StringRegExp($sString, "(\\\\|\\'|\\u[[:xdigit:]]{4}|[[:ascii:]])", 3)

    For $i = 0 To UBound($aString) - 1
        Switch StringLen($aString[$i])
            Case 1
                $sOut &= $aString[$i]
            Case 2
                $sOut &= StringRight($aString[$i], 1)
            Case 6
                $sOut &= ChrW(Dec(StringRight($aString[$i], 4)))
        EndSwitch
    Next

    Opt('ExpandVarStrings', $iOld_Opt_EVS)
    Opt('ExpandEnvStrings', $iOld_Opt_EES)

    Return $sOut
EndFunc

Этот скрипт записывает список всех танков в игре в файл tankInfo.txt
 
Последнее редактирование:
Автор
T

TiranCool

Новичок
Сообщения
68
Репутация
0
Привет, Спасибо. Круто), буду вспоминать и учиться)
 
Верх