PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Парсинг HTML


Парсинг HTML

Сообщений 1 страница 11 из 11

1

Подскажите примеры парсинга HTML страниц.
Пробовал через https://www.purebasic.fr/english/viewtopic.php?t=66256
И через регулярные выражения не находит.

Пример

StartPa.s = "<div class="+Chr(34)
  EndPA.s = "</div>"

  If d = 0
    pattern$ = "(?<=()"+StartPa+")\S(.*?)(?=()"+EndPA+")"
  Else
    pattern$ ="()"+StartPa+"\S(.*?)()"+EndPA
  EndIf

Когда встречаются такие куски через ReceiveHTTPMemory

пример

<option
                              value="created-ascending"
                             
                            >
                              Date, old To new
                            </option>

Страница https://greenroninstore.com/collections/m-m-pdfs

P.S. Вот составил регулярку, но она не доходит до конца.
А если заменить 0 на 1 в ReadRegular, то она останавливается на 99666 и дальше не идет,  если удалить часть текста что идет выше она идёт дальше.
Понял что проблема в Юникодных символах, пробовал через UTF8(), Ascii() но все равно не получается дойти до конца.

Код:
Код:
Procedure.s ReadHTML(sURL.s) 
  If InitNetwork()
    *Buffer = ReceiveHTTPMemory(sURL)
    If *Buffer
      Size = MemorySize(*Buffer)
      HTML_MEM.s = PeekS(*Buffer, Size, #PB_UTF8|#PB_ByteLength) 
      FreeMemory(*Buffer)
      ProcedureReturn HTML_MEM    
    Else
      ProcedureReturn "False"
    EndIf
    ProcedureReturn "False"
  EndIf
EndProcedure

Procedure ReadRegular(URL_Text.s,  Pattern.s, type.a = 0)
  If CreateRegularExpression(0, Pattern)    
    If type = 0 
      URL_Text_Result.S = ReplaceRegularExpression(0, URL_Text, "+")
      Debug URL_Text_Result
    ElseIf type = 1      
      If ExamineRegularExpression(0, URL_Text)
        While NextRegularExpressionMatch(0)       
          Debug t : t+1
          Debug RegularExpressionError()          
          Debug "Match: " + RegularExpressionMatchString(0)
          Debug "    Position: " + Str(RegularExpressionMatchPosition(0))
          Debug "    Length: " + Str(RegularExpressionMatchLength(0))
        Wend
      EndIf
    EndIf  
    FreeRegularExpression(0)
  Else
    Debug RegularExpressionError()
  EndIf
EndProcedure

sURL.s = "https://greenroninstore.com/collections/m-m-pdfs"
URL_Text.s = ReadHTML(sURL.s) 
type = 0
If Not URL_Text = "False"  
  ; Debug URL_Text
  Pattern.s = PeekS(?NumericalData, ?NumericalDataE-?NumericalData,  #PB_Ascii) 
  ReadRegular(URL_Text, Pattern, 0)
EndIf
End
 
DataSection
  NumericalData:   
  Data.a $28, $3C, $7C, $3C, $5C, $2F, $29, $28, $5B, $21, $2D, $30, $2D, $39, $61, $2D, $7A, $41, $2D, $5A, $5F, $5D, $2B, $29, $28, $5C, $73, $2B, $28, $3F, $3A, $28, $5B, $2D, $30, $2D, $39, $61, $2D, $7A, $41, $2D, $5A, $5F, $5D, $2B, $28, $3D, $22, $28, $28, $5B, $30, $2D, $39, $20, $61, $2D, $7A, $41, $2D, $5A, $2D, $5F, $2E, $2C, $3D, $3A, $3B, $27, $2B, $2F, $26, $23, $3F, $40, $24, $7B, $7D, $5C, $5B, $5C, $5D, $5D, $2B, $29, $7C, $29, $22, $7C, $29, $28, $5C, $73, $2B, $7C, $29, $29, $29, $2B, $28, $5B, $30, $2D, $39, $61, $2D, $7A, $41, $2D, $5A, $2F, $5D, $2B, $7C, $29, $3E, $7C, $3E, $29
  NumericalDataE: 
EndDataSection

Отредактировано @ZOLO@ (04.01.2025 20:46:28)

0

2

где то давно читал что нельзя использовать регулярку для этой цели, будут пропуски и ошибки
было сказано что читать строку нужно посимвольно, больше ни чего не помню
очень много безграмотного народу пишут безграмотный html, а потому задача сложная

0

3

Для каждого сайта надо писать свою регулярку или редактировать под сайт, как я понял.

Мне с час с кодировкой  разобраться а то на половине останавливается, удаляешь или заменяешь дальше идет до проблемы. 

А на последних версиях норм код запускается(у меня 5.70 )?

0

4

@ZOLO@
кодировка на странице  указывается в charset=UTF-8, то есть несложно понять, чтобы правильно прочитать файл.

0

5

AZJIO а это что HTML_MEM.s = PeekS(*Buffer, Size, #PB_UTF8|#PB_ByteLength) ?

0

6

@ZOLO@
это то как вы определяете формат в соответствии с определением его на странице. Если страница говорит вам что это формат UTF-8, а вы примените что-то другое, то и получите абракадабру. Если для файлов формат определяет функция ReadStringFormat(), то для страниц без метки BOM формат определяется содержимым в параметре charset. После определения остаётся только правильно прочитать в той же указанной кодировке. Применить  Select Format, если Case "UTF-8", то флаг flgFormat = #PB_UTF8 и т.д. соответственно прочитано из памяти будет правильно.

99% сайтов сейчас в UTF-8. Поэтому писать что "не работает кодировка" не корректно. Не работает регулярное выражение не учитывающее что-то, будет более соответствовать правильному описанию проблемы.

Как на счёт теста в программе RegExpPB
По регулярным выражениям могут помочь тут.

По поводу "регулярка идёт не до конца" - она всегда идёт до конца, но не будет захватывать то что не определено в регулярном выражении. Опять сказанное неправильно сформулировано. Конечно кроме специальных функций идущих не до конца - MatchRegularExpression() ищущей первое совпадение и не идущая дальше найденного.

@ZOLO@ написал(а):

А на последних версиях норм код запускается(у меня 5.70 )?

Смотря какой код. У выбранной вами версии нет C-Backend, которая делает приложение чуть быстрее. Последняя версия не поддерживает WindowsXP и минимальный размер файла 150-250кб. В данном случае 6.0.4 - последняя версия которая поддерживает старые возможности - компактный исполняемый файл и поддержка WindowsXP. Дальше выбор за вами.

Отредактировано AZJIO (06.01.2025 00:26:47)

0

7

AZJIO запусти код из первого сообщения, и посмотри.

0

8

@ZOLO@
Я не любитель скачивать в торопях что-то и запускать у себя на компе от человека которого я первый раз вижу.
Во первых регвыр скрыт бинарным кодом, определённо мне нужно конвертировать его в текст.
Скачивание показывает мой IP неизвестным людям, а если сделать ещё и заход на страницу, то можно отправить информацию о компе, местоположение и прочую инфу. Не помогая я ни чем не рискую и не напрягаюсь.

Вы можете выложить часть текста которая должна быть захвачена, а она не захватывается и дать текст регвыр, чтобы от меня было минимум телодвижений. Иначе я буду ждать пока кто нибудь поможет.

Я изначально знал что обработка html-страницы отнимет у меня сутки времени, я для себя то этого не хочу делать отлаживать пару десятков регвыр, а уж просто так не хочу ввязываться. Могу только морально помочь, подержать кулачки за тебя.

0

9

AZJIO написал(а):

Во первых регвыр скрыт бинарным кодом, определённо мне нужно конвертировать его в текст.

В коде есть строка  Pattern.s = PeekS(?NumericalData, ?NumericalDataE-?NumericalData,  #PB_Ascii)  которая достает это регулярное выражение.

Код:
(<|<\/)([!-0-9a-zA-Z_]+)(\s+(?:([-0-9a-zA-Z_]+(="(([0-9 a-zA-Z-_.,=:;'+/&#?@${}\[\]]+)|)"|)(\s+|)))+([0-9a-zA-Z/]+|)>|>)
AZJIO написал(а):

Скачивание показывает мой IP неизвестным людям, а если сделать ещё и заход на страницу, то можно отправить информацию о компе, местоположение и прочую инфу.

AZJIO написал(а):

Вы можете выложить часть текста которая должна быть захвачена, а она не захватывается и дать текст регвыр, чтобы от меня было минимум телодвижений.

Куда я выложу, если тебя беспокоит что другие узнают твой ИП адресс, и прочую фигню?
Ссылка на файль мейл ру

Вот скажи, как лучше сделать с нижнем текстом?
Но чтоб не было  костылей типа \ô?

Код:
([-0-9a-zA-Z_]+="(([0-9 a-zA-Z-_.,=:;'+’()\/&#?@${}\[\]]+)|)")

id="Åland Islands"
id="Cocos (Keeling) Islands"
id="Côte d’Ivoire"
id="Curaçao"
id="Myanmar (Burma)"
id="Réunion"
id="São Tomé &amp; Príncipe"
id="St. Barthélemy"
id="Türkiye"

0

10

@ZOLO@ написал(а):

типа \ô?

а зачем так сложно?

Код:
([-\w]+="(.*?)")

Это форма записи усложняет чтение

Код:
(\w+|)

Проще записать так

Код:
(\w*)

Эта комбинация

Код:
0-9a-zA-Z_

можно записать кратко

Код:
\w

Из чего следует

Код:
([0-9a-zA-Z]+|)

записывается как

Код:
(\w*)

а если учесть что скобки используются для символа ИЛИ и без него не имеют необходимости быть, то всё сводится к простому

Код:
\w*

А в чём смысл регулярного выражения? по началу открывающего и закрывающего тега (<|<\/) и по концовки >|>) создаётся впечатление что регулярка захватывает теги.

Тут видимо ошибка

Код:
([!-0-9a-zA-Z_]

тире используется как диапазон !-0 означает все символы между восклицательным знаком и нулём. То есть диапазон 0-9 игнорируется, так как 0 был взят за окончание первого диапазона. Тире либо экранируется \- либо ставится в конце диапазона, например [as-] если он стоит в конце, то не требует экранирования, так как воспринимается литерально. Нажми в моей проге RegExp.exe кнопку "[ ]", вставь диапазон и посмотри что он захватит, зелёным цветом пометятся захваченные символы и диапазона 0-9 там не будет.

Отредактировано AZJIO (06.01.2025 03:28:04)

0

11

Решил проблему с помощи \p{L}, буду переписывать.

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Парсинг HTML