Что нового

Получить ссылки из html текста по критерию

Dotacka

Новичок
Сообщения
37
Репутация
0
Добрый день.
Задался задачей получить определенные ссылки из сайта.

Cуть задачи такая: Необходимо получить все ссылки из полученного html содержащие в своей структуре слово context
Например :
https://site/context/ - ccылка подходит
https://site/archive/ - ccылка не подходит

Вот что я начал делать
Код:
$sHTML =  BinaryToString(_INetGetSource('https://www.site.ru'), $SB_UTF8)
--дальше незнаю как выдернуть ссылки---(((
$filename = "ссылки.txt"
$hFile = FileOpen(@ScriptDir & '\' & $filename, 1)
FileWriteLine($hFile, $sHTML)
FileClose($hFile)


Надеюсь кто-нибудь поможет. Cпасибо.
 

Alecsis

Знающий
Сообщения
27
Репутация
14
Код:
#include <AutoItConstants.au3>
#include <FileConstants.au3>
#include <StringConstants.au3>
#include <Array.au3>
Opt('MustDeclareVars', True)

Local $sURL, $sHTML, $aRefs, $sFileName, $hFile, $i

; $sHTML =  BinaryToString(InetRead('https://www.site.ru'), $SB_UTF8)

;--дальше незнаю как выдернуть ссылки---(((

;
; Обычно (но не всегда) практически полезные ссылки выглядят примерно так:
; <a href="фактический URL" что-то ещё</a>
; где «фактический URL» м.б. как абсолютный (типа http://www.site123.ru),
; так и относительно секущей страницы, например qwerty/asdfh/…
; по сути, надо выцепить всё, что в кавычках после href=
;
Local Const _
  $csRefAbs = '(?isU)(?:<a href="(http[^"]+)")+',  _   ;  только абсолютные ссылки
  $csRefAll = '(?isU)(?:<a href="([^"]+)")+'           ;  любые ссылки

$sURL = 'https://docs.microsoft.com/en-us/sysinternals/downloads/' ; из взятого наугад реального скрипта
$sHTML = BinaryToString(InetRead($sURL), $SB_UTF8)
$aRefs = StringRegExp($sHTML, $csRefAbs, $STR_REGEXPARRAYGLOBALMATCH)
If @error Then
  MsgBox($MB_ICONSTOP, @ScriptName, 'Облом поиска ссылок')
  Exit 362
EndIf

; _ArrayDisplay($aRefs) ;
;
; остальное — «на автопилоте» :-)
;
$sFileName= "ссылки.txt"
$hFile = FileOpen(@ScriptDir & '\' & $sFileName,  $FO_APPEND) ; дописывать в конец файла
For $i = 0 To UBound($aRefs) - 1
  FileWriteLine($hFile, $aRefs[$i])
Next
FileClose($hFile)
MsgBox($MB_ICONINFORMATION, @ScriptName, 'Ok, всего найдено ссылок: ' & UBound($aRefs))
Exit
Соотв-но, если нужны любые ссылки, то в вызове StringRegExp подставить $csRefAll
Разумеется, надо учесть, что абс. ссылки м,б. ftp://адрес и др., подпилить regexp-ы imho не проблема.
 
Автор
D

Dotacka

Новичок
Сообщения
37
Репутация
0
Код:
#include <AutoItConstants.au3>
#include <FileConstants.au3>
#include <StringConstants.au3>
#include <Array.au3>
Opt('MustDeclareVars', True)

Local $sURL, $sHTML, $aRefs, $sFileName, $hFile, $i

; $sHTML =  BinaryToString(InetRead('https://www.site.ru'), $SB_UTF8)

;--дальше незнаю как выдернуть ссылки---(((

;
; Обычно (но не всегда) практически полезные ссылки выглядят примерно так:
; <a href="фактический URL" что-то ещё</a>
; где «фактический URL» м.б. как абсолютный (типа http://www.site123.ru),
; так и относительно секущей страницы, например qwerty/asdfh/…
; по сути, надо выцепить всё, что в кавычках после href=
;
Local Const _
  $csRefAbs = '(?isU)(?:<a href="(http[^"]+)")+',  _   ;  только абсолютные ссылки
  $csRefAll = '(?isU)(?:<a href="([^"]+)")+'           ;  любые ссылки

$sURL = 'https://docs.microsoft.com/en-us/sysinternals/downloads/' ; из взятого наугад реального скрипта
$sHTML = BinaryToString(InetRead($sURL), $SB_UTF8)
$aRefs = StringRegExp($sHTML, $csRefAbs, $STR_REGEXPARRAYGLOBALMATCH)
If @error Then
  MsgBox($MB_ICONSTOP, @ScriptName, 'Облом поиска ссылок')
  Exit 362
EndIf

; _ArrayDisplay($aRefs) ;
;
; остальное — «на автопилоте» :-)
;
$sFileName= "ссылки.txt"
$hFile = FileOpen(@ScriptDir & '\' & $sFileName,  $FO_APPEND) ; дописывать в конец файла
For $i = 0 To UBound($aRefs) - 1
  FileWriteLine($hFile, $aRefs[$i])
Next
FileClose($hFile)
MsgBox($MB_ICONINFORMATION, @ScriptName, 'Ok, всего найдено ссылок: ' & UBound($aRefs))
Exit
Соотв-но, если нужны любые ссылки, то в вызове StringRegExp подставить $csRefAll
Разумеется, надо учесть, что абс. ссылки м,б. ftp://адрес и др., подпилить regexp-ы imho не проблема.
Работает. Получил исправно все ссылки. Благодарю.
А не подскажете как отсортировать эти ссылки что бы остались только те ссылки - которые содержать слово "context"?
Сообщение автоматически объединено:

Работает. Получил исправно все ссылки. Благодарю.
А не подскажете как отсортировать эти ссылки что бы остались только те ссылки - которые содержать слово "context"?
Ну или хотябы, что бы скрипт, после того как вписал ссылки в текстовый файл- прошелся по списку и оставил только те ссылки в которых есть слово "context"
 
Последнее редактирование:

Alecsis

Знающий
Сообщения
27
Репутация
14
Тогда что-то такое:
Код:
#include <AutoItConstants.au3>
#include <FileConstants.au3>
#include <StringConstants.au3>
#include <Array.au3>
Opt('MustDeclareVars', True)

Local $sURL, $sHTML, $aRefs, $sFileName, $hFile, $i

; $sHTML =  BinaryToString(InetRead('https://www.site.ru'), $SB_UTF8)

;--дальше незнаю как выдернуть ссылки---(((

;
; Обычно (но не всегда) практически полезные ссылки выглядят примерно так:
; <a href="фактический URL" что-то ещё</a>
; где «фактический URL» м.б. как абсолютный (типа http://www.site123.ru),
; так и относительно секущей страницы, например qwerty/asdfh/…
; по сути, надо выцепить всё, что в кавычках после href=
;
Local Const _
  $csRefAbs = '(?isU)(?:<a href="(http[^"]+)")+',  _   ;  только абсолютные ссылки
  $csRefAll = '(?isU)(?:<a href="([^"]+)")+'           ;  любые ссылки

$sURL = 'https://docs.microsoft.com/en-us/sysinternals/downloads/' ; из взятого наугад реального скрипта
$sHTML = BinaryToString(InetRead($sURL), $SB_UTF8)
$aRefs = StringRegExp($sHTML, $csRefAbs, $STR_REGEXPARRAYGLOBALMATCH)
If @error Then
  MsgBox($MB_ICONSTOP, @ScriptName, 'Облом поиска ссылок')
  Exit 362
EndIf

; _ArrayDisplay($aRefs) ;
;
; остальное — «на автопилоте» :-)
;

; *** 2020-09-26 ***
; фильтруем ссылки по заданному слову, в примере — «context»
; регэксп строим так, чтобы такие случаи, как context1, cont, xxxcontext  итп не «прокатывали»
; кстати, можно не отходя от кассы фильтровать по нескольким словам задав фильтр в таком стиле:
; '(?iU)\bcontext|qwerty|sdvbgj'  === прокатит любое из пересисленных через «|»
;
Local $sRE_Filter = '(?iU)\bcontext\b', _   ; интересующее слово
      $iFiltered, _                         ; сч-к ссылок, прошедших фильтр
      $sReport                              ; микроотчёт

$sFileName= "ссылки.txt"
$hFile = FileOpen(@ScriptDir & '\' & $sFileName,  $FO_APPEND) ; дописывать в конец файла
$iFiltered = 0
For $i = 0 To UBound($aRefs) - 1
  If StringRegExp($aRefs[$i], $sRE_Filter) Then ; проверяем на соотв-е фильтру
    FileWriteLine($hFile, $aRefs[$i])           ; Ok, выводим наружу
    $iFiltered += 1
  EndIf
Next
FileClose($hFile)
$sReport = 'Всего ссылок = ' & UBound($aRefs) & @CR & 'Из них отфильтровано ' & $iFiltered
If ($iFiltered > 0) Then
    MsgBox($MB_ICONINFORMATION, @ScriptName, $sReport)
  Else
    MsgBox($MB_ICONWARNING, @ScriptName, 'Интересующих ссылок нет')
EndIf
Exit
 
Автор
D

Dotacka

Новичок
Сообщения
37
Репутация
0
Тогда что-то такое:
Код:
#include <AutoItConstants.au3>
#include <FileConstants.au3>
#include <StringConstants.au3>
#include <Array.au3>
Opt('MustDeclareVars', True)

Local $sURL, $sHTML, $aRefs, $sFileName, $hFile, $i

; $sHTML =  BinaryToString(InetRead('https://www.site.ru'), $SB_UTF8)

;--дальше незнаю как выдернуть ссылки---(((

;
; Обычно (но не всегда) практически полезные ссылки выглядят примерно так:
; <a href="фактический URL" что-то ещё</a>
; где «фактический URL» м.б. как абсолютный (типа http://www.site123.ru),
; так и относительно секущей страницы, например qwerty/asdfh/…
; по сути, надо выцепить всё, что в кавычках после href=
;
Local Const _
  $csRefAbs = '(?isU)(?:<a href="(http[^"]+)")+',  _   ;  только абсолютные ссылки
  $csRefAll = '(?isU)(?:<a href="([^"]+)")+'           ;  любые ссылки

$sURL = 'https://docs.microsoft.com/en-us/sysinternals/downloads/' ; из взятого наугад реального скрипта
$sHTML = BinaryToString(InetRead($sURL), $SB_UTF8)
$aRefs = StringRegExp($sHTML, $csRefAbs, $STR_REGEXPARRAYGLOBALMATCH)
If @error Then
  MsgBox($MB_ICONSTOP, @ScriptName, 'Облом поиска ссылок')
  Exit 362
EndIf

; _ArrayDisplay($aRefs) ;
;
; остальное — «на автопилоте» :-)
;

; *** 2020-09-26 ***
; фильтруем ссылки по заданному слову, в примере — «context»
; регэксп строим так, чтобы такие случаи, как context1, cont, xxxcontext  итп не «прокатывали»
; кстати, можно не отходя от кассы фильтровать по нескольким словам задав фильтр в таком стиле:
; '(?iU)\bcontext|qwerty|sdvbgj'  === прокатит любое из пересисленных через «|»
;
Local $sRE_Filter = '(?iU)\bcontext\b', _   ; интересующее слово
      $iFiltered, _                         ; сч-к ссылок, прошедших фильтр
      $sReport                              ; микроотчёт

$sFileName= "ссылки.txt"
$hFile = FileOpen(@ScriptDir & '\' & $sFileName,  $FO_APPEND) ; дописывать в конец файла
$iFiltered = 0
For $i = 0 To UBound($aRefs) - 1
  If StringRegExp($aRefs[$i], $sRE_Filter) Then ; проверяем на соотв-е фильтру
    FileWriteLine($hFile, $aRefs[$i])           ; Ok, выводим наружу
    $iFiltered += 1
  EndIf
Next
FileClose($hFile)
$sReport = 'Всего ссылок = ' & UBound($aRefs) & @CR & 'Из них отфильтровано ' & $iFiltered
If ($iFiltered > 0) Then
    MsgBox($MB_ICONINFORMATION, @ScriptName, $sReport)
  Else
    MsgBox($MB_ICONWARNING, @ScriptName, 'Интересующих ссылок нет')
EndIf
Exit
Благодарю! Здорово сделано, c отчетом!
Скажите , а что значит "по нескольким словам задав фильтр в таком стиле:
; '(?iU)\bcontext|qwerty|sdvbgj'" ?
Это любое совпадение? 1 из 3 ?
 

Alecsis

Знающий
Сообщения
27
Репутация
14
Да, любое из перечисленных
Благодарю! Здорово сделано, c отчетом!
Скажите , а что значит "по нескольким словам задав фильтр в таком стиле:
; '(?iU)\bcontext|qwerty|sdvbgj'" ?
Это любое совпадение? 1 из 3 ?
Да, любое из трёх (или сколько их там будет перечислено через спец символ «|») выдаст совпадение.
Детали см. в help'е ф-ции StringRegExp, где расписан «сакральный» смысл спец. символов типа той же вертикальной черты и ряда других. И ещё здесь https://autoit-script.ru/docs/regexp/regexpref.htm
 
Автор
D

Dotacka

Новичок
Сообщения
37
Репутация
0
Код:
#include <AutoItConstants.au3>
#include <FileConstants.au3>
#include <StringConstants.au3>
#include <Array.au3>
Opt('MustDeclareVars', True)

Local $sURL, $sHTML, $aRefs, $sFileName, $hFile, $i

; $sHTML =  BinaryToString(InetRead('https://www.site.ru'), $SB_UTF8)

;--дальше незнаю как выдернуть ссылки---(((

;
; Обычно (но не всегда) практически полезные ссылки выглядят примерно так:
; <a href="фактический URL" что-то ещё</a>
; где «фактический URL» м.б. как абсолютный (типа http://www.site123.ru),
; так и относительно секущей страницы, например qwerty/asdfh/…
; по сути, надо выцепить всё, что в кавычках после href=
;
Local Const _
  $csRefAbs = '(?isU)(?:<a href="(http[^"]+)")+',  _   ;  только абсолютные ссылки
  $csRefAll = '(?isU)(?:<a href="([^"]+)")+'           ;  любые ссылки

$sURL = 'https://docs.microsoft.com/en-us/sysinternals/downloads/' ; из взятого наугад реального скрипта
$sHTML = BinaryToString(InetRead($sURL), $SB_UTF8)
$aRefs = StringRegExp($sHTML, $csRefAbs, $STR_REGEXPARRAYGLOBALMATCH)
If @error Then
  MsgBox($MB_ICONSTOP, @ScriptName, 'Облом поиска ссылок')
  Exit 362
EndIf

; _ArrayDisplay($aRefs) ;
;
; остальное — «на автопилоте» :-)
;
$sFileName= "ссылки.txt"
$hFile = FileOpen(@ScriptDir & '\' & $sFileName,  $FO_APPEND) ; дописывать в конец файла
For $i = 0 To UBound($aRefs) - 1
  FileWriteLine($hFile, $aRefs[$i])
Next
FileClose($hFile)
MsgBox($MB_ICONINFORMATION, @ScriptName, 'Ok, всего найдено ссылок: ' & UBound($aRefs))
Exit
Соотв-но, если нужны любые ссылки, то в вызове StringRegExp подставить $csRefAll
Разумеется, надо учесть, что абс. ссылки м,б. ftp://адрес и др., подпилить regexp-ы imho не проблема.
Хотел еще немного развить ваш скрипт, но что-то не хватило у меня мозгов. Может вы снова сможете подсказать:

У меня есть два типа ссылок в html коде:
Пример:
1 - Вариант <a href=' https://site/context/ '>Cсылка 1</a><div class='status_not valid'>Не валидная</div><остальной html текст>
2 - Вариант <a href=' https://site/context/ '>Cсылка 2</a><остальной html текст> )

Как видите у невалидных ссылок сразу после них прописана константа в виде : <div class='status_not valid'>Не валидная</div>

Я пробую изменить ваш фильтр:
Код:
$csRefAll = '(?isU)(?:<a href="([^"]+)")+'
таким образом- что если после ссылки есть такая константа <div class='status_not valid'>Не валидная</div> скрипт пропускает эту ссылку....

Только вот как это сделать?
 

Alecsis

Знающий
Сообщения
27
Репутация
14
Как видите у невалидных ссылок сразу после них прописана константа в виде : <div class='status_not valid'>Не валидная</div>
Только вот как это сделать?
М.б. прокатит $csRefAbs = '(?isU)(?:<a href="(http\S+)".*</a>(.*))+', но это не точно
См. личку, а также здесь Пример = развитие 1-го варианта
 
Автор
D

Dotacka

Новичок
Сообщения
37
Репутация
0
М.б. прокатит $csRefAbs = '(?isU)(?:<a href="(http\S+)".*</a>(.*))+', но это не точно
См. личку, а также здесь Пример = развитие 1-го варианта
Cпасибо большое.
Взял из скрипта отдельные части и немного упростил задачу. Оптимизировать такие сложные вещи - это не мой уровень))))))
 
Верх