Что нового

Парсинг строки с помощью регулярного выражения

Maria

Новичок
Сообщения
29
Репутация
0
Здравствуйте.


1) Помогите пожалуйста вытащить из строки определённую часть текста.

href="/albert-fargas-die-symbolik-des-tempels-sagrada-familia-guies-broschiert-M0848478408X.html

Выделенный жирным шрифтом текст должен быть найден/вытащен.
Примечание
Иногда там может и не быть Х, цифры могут меняться и само количество цифр тоже.

2) Так же и тут, мне нужно вытащить цену обозначенную жирным шрифтом, цена может меняться

<span class="notice-list-product__price">46,93&nbsp;€</span>

Примечание.
Если я нажимаю на цену и беру исследовать, то вижу следующее
<span class="notice-list-product__price">46,93 €</span>
Если копирую и вставляю, то получается
<span class="notice-list-product__price">46,93&nbsp;€</span>
не знаю на сколько это играет большую роль

Очень надеюсь на вашу помощь
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
Код:
#include <Array.au3>
$sText='href="/albert-fargas-die-symbolik-des-tempels-sagrada-familia-guies-broschiert-M0848478408X.html'
$aArray=StringRegExp($sText,'broschiert-M0([^.]+).html',1)
_ArrayDisplay($aArray,"Массив $aArray")
$sLine=StringRegExp($sText,'broschiert-M0([^.]+).html',1)[0]
MsgBox(4096,"Переменная $sLine","$sLine =>"&$sLine&"<=")
; ------------
$sText='<span class="notice-list-product__price">46,93&nbsp;€</span>'
$aArray=StringRegExp($sText,'__price">([\d,]+)',1)
_ArrayDisplay($aArray,"Массив $aArray")
$sLine=StringRegExp($sText,'__price">([\d,]+)',1)[0]
MsgBox(4096,"Переменная $sLine","$sLine =>"&$sLine&"<=")
 
Последнее редактирование:
Автор
M

Maria

Новичок
Сообщения
29
Репутация
0
Код:
#include <Array.au3>
$aArray=StringRegExp($sText,'broschiert-M0([^.]+).html',1)
_ArrayDisplay($aArray,"Массив $aArray")
$sLine=StringRegExp($sText,'broschiert-M0([^.]+).html',1)[0]
MsgBox(4096,"Переменная $sLine","$sLine =>"&$sLine&"<=")
; ------------
$sText='<span class="notice-list-product__price">46,93&nbsp;€</span>'
$aArray=StringRegExp($sText,'__price">([\d,]+)',1)
_ArrayDisplay($aArray,"Массив $aArray")
$sLine=StringRegExp($sText,'__price">([\d,]+)',1)[0]
MsgBox(4096,"Переменная $sLine","$sLine =>"&$sLine&"<=")

Здравствуйте .
Вторая часть работает, первая выдаёт следующее

: ==> Illegal text at the end of statement (one statement per line).:
$sLine=StringRegExp($sText,'broschiert-M0([^.]+).html',1)[0]
$sLine=StringRegExp($sText,'broschiert-M0([^.]+).html',1)^ ERROR
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
Исправил сообщение, забыл добавить $sText=
 
Автор
M

Maria

Новичок
Сообщения
29
Репутация
0
Исправил сообщение, забыл добавить $sText=
Супер работает! Огромное вам спасибо!

У меня есть вопрос один ещё, он не по теме.

Я в дальнейшем буду парсить страницу. И всегда использовала для этого ШУ
Но на данный момент ИЕ отмирает и многие сайты уже с ним не работают.

Какую мне нужно использовать функцию например для ФИ, как альтернативу _IEBodyReadHTML. что бы потом дальнейшем парсить ?
Сообщение автоматически объединено:

Супер работает! Огромное вам спасибо!

У меня есть вопрос один ещё, он не по теме.

Я в дальнейшем буду парсить страницу. И всегда использовала для этого ШУ
Но на данный момент ИЕ отмирает и многие сайты уже с ним не работают.

Какую мне нужно использовать функцию например для ФИ, как альтернативу _IEBodyReadHTML. что бы потом дальнейшем парсить ?

*IE Использвала
сейцахс хочу Firefox
Сообщение автоматически объединено:

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

Что то у меня не получается вытащить все номера и цены. Вытаскивает только первый номер и цену.
Можете привести пример.

Как должен выглядеть скрипт который считывает ВСЕ номера из страницы?
у меня почему то получается только первый номер вытащить

Саму страницу дать к сожалению не могу. Но подскажите где моя ошибка, она наверно в логике ...
Код:
$oIE =_IECreate(URL,0,1)

 $sHTML2 = _IEDocReadHTML ($oIE)
      _IELoadWait($oIE)

     FileWrite("1.html",$sHTML2)


Global $Fline,$b = 0
While $b < 1000
$Fline = FileReadLine("1.html",$b)

$aArray=StringRegExp( $Fline ,'M0([^.]+).html',1)

_ArrayDisplay($aArray,"Массив $aArray")


$b=$b+1

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

К сожалению я не могу редактировать

Вот к примеру мне нужно парсить эте страницу.
https://www.medimops.de/produkte-C0/?fcIsSearch=1&searchparam=java

Каждая ссылка на книгу имеет URL, который включает в себя, те цифры, которые мне нужно вытащить.

Например на сайте указанно 30 книг.
Мне нужно вытащить 30 номеров и 30 цен.
Сообщение автоматически объединено:

Я наверно открою новую тему так будет удобней.
 
Последнее редактирование:

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
Код:
$aArray=StringRegExp($sText,'M0([^.]+).html',3)

flag=3
 
Автор
M

Maria

Новичок
Сообщения
29
Репутация
0
Код:
$aArray=StringRegExp($sText,'M0([^.]+).html',3)

flag=3
Супер! Огромное спасибо.

Может подсказать, как сделать так, что бы не было повторяющихся переменных в массиве? Я вытаскиваю много повторяющихся номеров и они мешают. Как можно пропустить этот массив, через фильтр и получить новый, с уникальными переменными
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
Код:
$aArray=StringRegExp($sText,'M0([^.]+).html',3)
_ArrayDisplay($aArray,"Массив $aArray")
$aArray2=_ArrayUnique($aArray)
_ArrayDisplay($aArray2,"Массив $aArray2")
 
Автор
M

Maria

Новичок
Сообщения
29
Репутация
0
Код:
$aArray=StringRegExp($sText,'M0([^.]+).html',3)
_ArrayDisplay($aArray,"Массив $aArray")
$aArray2=_ArrayUnique($aArray)
_ArrayDisplay($aArray2,"Массив $aArray2")
У меня последняя трудность.

По моей задумке должно было быть так.
Два Массива номер и цена. И Номера переменных должны были подходить. например Номер Аррай[5] соответствует цене Аррай[5].

Но к сожалению некоторые номера не имеют цены, так как товар распродан.
Когда товар распродан, то стоит следующее

<div class="notice-list-product__pricing"><div class="notice-list-product__out-of-stock">Gerade ausverkauft</div></div>

Вот так выгляди, когда цена есть
<span class="notice-list-product__price">46,93&nbsp;€</span>

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

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
В ссылке, которую вы дали цены все есть, вот пример получения 2-х массивов
Код:
#include <Array.au3>
#include <IE.au3> 
$sURL='https://www.medimops.de/produkte-C0/?fcIsSearch=1&searchparam=java'

$oIE=_IECreate($sURL,0,0,1)
$sHTML=_IEDocReadHTML($oIE)

$aArrayID=StringRegExp($sHTML,'M0([^.]+).html"><div class="product__title">',3)
_ArrayDisplay($aArrayID,"Массив $aArrayID")

$aArrayPRICE=StringRegExp($sHTML,'product__price[^>"]*">([\d,]*)&nbsp',3)
_ArrayDisplay($aArrayPRICE,"Массив $aArrayPRICE")

Что касается товара без цены, то нужна ссылка для теста...
 
Автор
M

Maria

Новичок
Сообщения
29
Репутация
0
В ссылке, которую вы дали цены все есть, вот пример получения 2-х массивов

Что касается товара без цены, то нужна ссылка для теста...
К сожалению ссылку на страницу дать не смогу так как там нужна регистрация.
Но я сохранила часть страницы.
<div class="notice-list-product__grid "><div class="notice-list-product__image"><a role="button" tabindex="0" href="/the-legend-of-zelda-breath-of-the-wild-collector-s-edition-loesungsbuch-gebundene-ausgabe-M01911015311.html"><img src="https://images2.medimops.eu/product/0055c1/M01911015311-small.jpg" alt="The Legend of Zelda - Breath of the Wild Collector&#x27;s Edition (Lösungsbuch)"/></a></div><div class="notice-list-product__description"><a role="button" tabindex="0" href="/the-legend-of-zelda-breath-of-the-wild-collector-s-edition-loesungsbuch-gebundene-ausgabe-M01911015001.html"><div class="notice-list-product__title">The Legend of Zelda - Breath of the Wild Collector&#x27;s Edition (Lösungsbuch)</div></a><div class="notice-list-product__manufacturer">von <a role="button" tabindex="0" href="/,x-keine-angabe/">unbekannt</a><div class="notice-list-product__sale"></div></div><div class="notice-list-product__pricing"><div class="notice-list-product__out-of-stock">Gerade ausverkauft</div>

<div class="notice-list-product__grid "><div class="notice-list-product__image"><a role="button" tabindex="0" href="/the-legend-of-zelda-breath-of-the-wild-collector-s-edition-loesungsbuch-gebundene-ausgabe-M01911015311.html"><img src="https://images2.medimops.eu/product/0055c1/M01911015311-small.jpg" alt="The Legend of Zelda - Breath of the Wild Collector&#x27;s Edition (Lösungsbuch)"/></a></div><div class="notice-list-product__description"><a role="button" tabindex="0" href="/the-legend-of-zelda-breath-of-the-wild-collector-s-edition-loesungsbuch-gebundene-ausgabe-M01911015002.html"><div class="notice-list-product__title">The Legend of Zelda - Breath of the Wild Collector&#x27;s Edition (Lösungsbuch)</div></a><div class="notice-list-product__manufacturer">von <a role="button" tabindex="0" href="/,x-keine-angabe/">unbekannt</a><div class="notice-list-product__sale"></div></div><span class="notice-list-product__price">46,93&nbsp;€</span>

<div class="notice-list-product__grid "><div class="notice-list-product__image"><a role="button" tabindex="0" href="/the-legend-of-zelda-breath-of-the-wild-collector-s-edition-loesungsbuch-gebundene-ausgabe-M01911015311.html"><img src="https://images2.medimops.eu/product/0055c1/M01911015311-small.jpg" alt="The Legend of Zelda - Breath of the Wild Collector&#x27;s Edition (Lösungsbuch)"/></a></div><div class="notice-list-product__description"><a role="button" tabindex="0" href="/the-legend-of-zelda-breath-of-the-wild-collector-s-edition-loesungsbuch-gebundene-ausgabe-M01911015003.html"><div class="notice-list-product__title">The Legend of Zelda - Breath of the Wild Collector&#x27;s Edition (Lösungsbuch)</div></a><div class="notice-list-product__manufacturer">von <a role="button" tabindex="0" href="/,x-keine-angabe/">unbekannt</a><div class="notice-list-product__sale"></div></div><span class="notice-list-product__price notice-list-product__price-sale">50,00&nbsp;€</span>
Там три товара. Можно сохранить просто как ХТМЛ и открыть в браузере.
(не обращайте внимание на одинаковые названия и фото, номера и цены там всегда разные).

Там показаны 3 варианта отображения цены, которые встречаются на сайте.

1) <div class="notice-list-product__pricing"><div class="notice-list-product__out-of-stock">Gerade ausverkauft</div></div>
2) </div><span class="notice-list-product__price">46,93&nbsp;€</span>
3) <span class="notice-list-product__price notice-list-product__price-sale">50,00&nbsp;€</span>

Мне нужно; что бы все три номера были считаны и все три цены. Там где нет цены и стоит >Gerade ausverkauft<, автоматически обозначать цену как 1000.
Грубо говоря, скрипт должен понимать/пробовать каждый вариант из трёх, что бы вытащить цену.

По итогу я хочу записать это в один текстовой фай/CSV в виде

Номер;цена
1911015001;1000
1911015002;46,93
1911015003;50

Вот такая собственно задумка у меня
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
К сожалению ссылку на страницу дать не смогу
Прикольно, интересно то что вы каждый раз даёте разную страницу и поэтому регулярка везде различная..
Сохранил вашу информацию в файл Name.xxx, примерно так получается:

Код:
#include <Array.au3>

$sFile='D:\Test\55117980\Name.xxx'
$sText=FileRead($sFile)
$sCSV=''

$aArrayID=StringRegExp($sText,'M0([^.]+).html"><div',3)
_ArrayDisplay($aArrayID,"Массив $aArrayID")

$aArrayPRICE=StringRegExp($sText,'product__price[^>"]*">([\d,]*)&nbsp|Gerade ausverkauft',3)
_ArrayDisplay($aArrayPRICE,"Массив $aArrayPRICE")

For $i=0 To UBound($aArrayID)-1
  $sCSV&=$aArrayID[$i]&';'&$aArrayPRICE[$i]&@CRLF
Next
$sCSV=StringReplace(StringTrimRight($sCSV,2),'Gerade ausverkauft','1000')
MsgBox(4096,"$sCSV",$sCSV)

; если надо удалить конечные нули ",00"
; $sCSV=StringRegExpReplace($sCSV,'(?m)(,00)$','')
; MsgBox(4096,"$sCSV",$sCSV)
 
Последнее редактирование:
Автор
M

Maria

Новичок
Сообщения
29
Репутация
0
Прикольно, интересно то что вы каждый раз даёте разную страницу и поэтому регулярка везде различная..
Сохранил вашу информацию в файл Name.xxx, примерно так получается:

Код:
#include <Array.au3>

$sFile='D:\Test\55117980\Name.xxx'
$sText=FileRead($sFile)
$sCSV=''

$aArrayID=StringRegExp($sText,'M0([^.]+).html"><div',3)
_ArrayDisplay($aArrayID,"Массив $aArrayID")

$aArrayPRICE=StringRegExp($sText,'product__price[^>"]*">([\d,]*)&nbsp|Gerade ausverkauft',3)
_ArrayDisplay($aArrayPRICE,"Массив $aArrayPRICE")

For $i=0 To UBound($aArrayID)-1
  $sCSV&=$aArrayID[$i]&';'&$aArrayPRICE[$i]&@CRLF
Next
$sCSV=StringReplace(StringTrimRight($sCSV,2),'Gerade ausverkauft','1000')
MsgBox(4096,"$sCSV",$sCSV)

; если надо удалить конечные нули ",00"
; $sCSV=StringRegExpReplace($sCSV,'(?m)(,00)$','')
; MsgBox(4096,"$sCSV",$sCSV)
Сообщение автоматически объединено:


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

Огромное Вам спасибо. Вы меня прям спасли, всё работает идеально!)
ПС.
Да так бывает, начнёшь проект, а там вечно что то меняется/дополняется))
Сообщение автоматически объединено:

Здравствуйте у меня маленькая проблема. Не могу понять как правильно оформить if.
Смысл такой

если цена не равна "Gerade Ausverkauft" и номер не равен ни одной переменной из массива $ArrayBlackList (Это текстовой файл blacklist.txt с номерами - исключениями, который был считан в массив), то ....
Я не понимаю как мне сделать/оформить, я понимаю, что должен быть перебор построчный с блэклистом, но как это оформить я не знаю
Код:
if &$aArrayPRICE[$i] <> "Gerade Ausverkauft" and $aArrayID[$i] <> ???????????       then


Помогите пожалуйста.
 
Последнее редактирование:

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
если цена не равна "Gerade Ausverkauft" и номер не равен ни одной переменной из массива $ArrayBlackList
Я не тестировал - не на чем, но примерно так можно сделать
Код:
$iCountBlackList=UBound($ArrayBlackList)-1

For $i=0 To UBound($aArrayID)-1
  If $aArrayPRICE[$i]<>'Gerade Ausverkauft'Then
    $n=1
    For $j=0 To $iCountBlackList
      If $aArrayID[$i]=$ArrayBlackList[$j]Then
        $n=0
        ExitLoop
      EndIf
    Next
    If $n Then $sCSV&=$aArrayID[$i]&';'&$aArrayPRICE[$i]&@CRLF
  EndIf
Next
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
Супер. Спасибо. Теперь я буду хоть понимать принцип:smile:)
В вашем примере я бы не использовал массив ArrayBlackList, т.к. в массиве может быть тысячи номеров и перебирать их постоянно в цикле как-то не очень красиво. Я не знаю точно как выглядит blacklist.txt (наверное каждый номер с новой строки)... вот 2 примера где используется StringInStr или StringRegExp и проверяют номер за один проход без использования 2-го цикла
Код:
$sFile='C:\blacklist.txt'
$sBlackList=FileRead($sFile)
$sBlackList=@CRLF&$sBlackList&@CRLF

For $i=0 To UBound($aArrayID)-1
  If $aArrayPRICE[$i]<>'Gerade Ausverkauft' And 0=StringInStr($sBlackList,@CRLF&$aArrayID[$i]&@CRLF)Then $sCSV&=$aArrayID[$i]&';'&$aArrayPRICE[$i]&@CRLF
Next


Код:
$sFile='C:\blacklist.txt'
$sBlackList=FileRead($sFile)
For $i=0 To UBound($aArrayID)-1
  If $aArrayPRICE[$i]<>'Gerade Ausverkauft' And 0=StringRegExp($sBlackList,'\b'&$aArrayID[$i]&'\b')Then $sCSV&=$aArrayID[$i]&';'&$aArrayPRICE[$i]&@CRLF
Next
 
Автор
M

Maria

Новичок
Сообщения
29
Репутация
0
В вашем примере я бы не использовал массив ArrayBlackList, т.к. в массиве может быть тысячи номеров и перебирать их постоянно в цикле как-то не очень красиво. Я не знаю точно как выглядит blacklist.txt (наверное каждый номер с новой строки)... вот 2 примера где используется StringInStr или StringRegExp и проверяют номер за один проход без использования 2-го цикла
Да, действительно, это более элегантное решение, Спасибо )

А вы случайно не знаете, как быть с тем, что многие сайты перестают поддерживать IE, какие сейчас есть рабочие библиотеки для FF или Chrome... Как мне сделать на том же FF _IEDocReadHTML
Сообщение автоматически объединено:

WebDriver Api ?
 

Andrey_A

Продвинутый
Сообщения
323
Репутация
68
какие сейчас есть рабочие библиотеки для FF или Chrome...
На сколько я знаю, они все недостаточно рабочие из-за многопоточности браузеров
Я не сильный спец инета, но можно прочитать страницу по разному, введи в поиск и выбирайте подходящее, к примеру так:
Код:
$sURL='https://www.medimops.de/produkte-C0/?fcIsSearch=1&searchparam=java'
$sText=_Downoad_MSXML($sURL)
MsgBox(4096,'Переменная $sText',$sText)

Func _Downoad_MSXML($sURL)
  $b=ObjCreate('MSXML2.XMLHTTP')
  $b.Open('GET',$sURL,0)
  $b.Send
  If $b.Status-200 Then Return ''
  Return $b.ResponseText
EndFunc


или так:
Код:
$sURL='https://www.medimops.de/produkte-C0/?fcIsSearch=1&searchparam=java'
$sFile='C:\List.html'
Local $hDownload = InetGet($sURL,$sFile,1,1)
Do
    Sleep(250)
Until InetGetInfo($hDownload, 2) ; Проверка выполнения полной загрузки.
$sText=FileRead($sFile)
MsgBox(4096,'Переменная $sText',$sText)
 
Последнее редактирование:
Автор
M

Maria

Новичок
Сообщения
29
Репутация
0
Да, примеры действительно хорошие, скопирую себе на будущее, спасибо.
Но для моих задач, они не всегда подходят. Ну или я чего то не знаю.
На многие сайты, доступ закрыт, то есть, вход только по логину и паролю, а это значит, что я не могу просто указать ссылку. Нужно всегда логиниться и время от времени сайт выбрасывает и нужно делать автоматическую проверку и ввод - заполнения полей итд. Так же нужно работать с данными, которые тебе выдаст сайт - с Юрл, которые скажем так не известны.
Может конечно есть способ, как отправлять и принимать "пакеты" в обход браузера ?
На сколько я знаю, они все недостаточно рабочие из-за многопоточности браузеров
Я не сильный спец инета, но можно прочитать страницу по разному, введи в поиск и выбирайте подходящее, к примеру так:
Да, примеры действительно хорошие, скопирую себе на будущее, спасибо.
Но для моих задач, они не всегда подходят. Ну или я чего то не знаю.
На многие сайты, доступ закрыт, то есть, вход только по логину и паролю, а это значит, что я не могу просто указать ссылку. Нужно всегда логиниться и время от времени сайт выбрасывает и нужно делать автоматическую проверку и ввод - заполнения полей итд. Так же нужно работать с данными, которые тебе выдаст сайт - с Юрл, которые скажем так не известны.
Может конечно есть способ, как отправлять и принимать "пакеты" в обход браузера ?
 
Верх