Что нового

[Данные, интернет] Парсинг и сравнение

Nelsy

Знающий
Сообщения
35
Репутация
8
Здравствуйте! Столкнулся с проблемкой при написании программы парсинга сайта с целью поиска новинок и их дальнейшего сравнения с найдеными нами релизами на другом сайте.

Парсинг:

Страничка на кинопоеске
Код:
<div class="text">
      <span class="name"><a href="/level/1/film/279728/">Принцесса и лягушка</a></span>
      <span> Princess and the Frog, The  (2009)</span>
      <span style="margin: 0">
          США,
          <i>реж. <a class="lined" href="/level/4/people/38043/">Рон Клементс</a>...</i>
      </span>
      <span>(мультфильм, семейный, мюзикл...)</span>
      <span><a class="lined" href="/level/4/people/34127/">Аника Нони Роуз</a>, <a class="lined" href="/level/4/people/463109/">Бруно Кампос</a></span>
      
   </div>

   <div class="clear"></div>

</div><div class="premier_item" id="195718">

   <div class="prem_day">
   <div class="day">
      <div><img src="/images/dates/7.gif" width=28 height=40 />
<img src="/images/dates/month_01.gif" vspace=6 />
</div>
      <div class="my_mark" id="my_vote_195718" style="display: none" title="Моя оценка"></div>
      <div class="add_myfilms">
         <span id="mymovies_s_195718" class="ajax"></span>
         <a style="visibility: visible" class="add" href="#" id="mymovies_l_195718" onclick="addMyMoviesFilm('195718'); return false">Добавить в Мои фильмы</a>
         <a style="visibility: hidden" class="add remove" href="/level/78/movies/list/film/195718/" id="mymovies_u_195718">Перейти в Мои фильмы</a>
         <span id="ur_rating_195718" class="ajax_rating"></span>
      </div>
   </div>
   <a class="company" href="/level/8/view/prem/company/1/">Каскад</a>
   <b class="limited"></b>
   </div>

   <div class="image gray">
      <a href="/level/1/film/195718/"><img src="/images/sm_film/195718.jpg" style="width: 52px; border: 3px #f60 solid; display: block; margin: 5px 0" alt="Воины света" /></a>
      
   </div>

   <div class="text">
      <span class="name"><a href="/level/1/film/195718/">Воины света</a></span>
      <span> Daybreakers  (2009)</span>
      <span style="margin: 0">
          Австралия...
          <i>реж. <a class="lined" href="/level/4/people/483617/">Майкл Спириг</a>...</i>
      </span>
      <span>(триллер, боевик, ужасы)</span>
      <span><a class="lined" href="/level/4/people/4630/">Этан Хоук</a>, <a class="lined" href="/level/4/people/9274/">Уиллем Дефо</a></span>
      
   </div>

   <div class="clear"></div>

</div><div class="premier_item" id="395714">

Код:
<span class="name"><a href="/level/1/film/262765/">Название фильма</a></span>
;~________________________________________262765__ данные цифры - ID фильма и они имеют диапазон от 000000 до 999999

Из всех подобных строк имеющихся в выше представленном коде странички, нам надо вырезать название фильма. Проблема в том что ID фильма в строке каждого из фильмов - разный, и необходимо составить маску, в чем я испытываю сложность и обратился к вам за помошью. Еще одна не значительна проблема в том что в названиях фильмов встречаются что то вроде разделителей в таком виде , &laquo; , &raquo; собственно их необходимо тоже изьять при помощи фильтров и сделать это так чтоб исходное название фильма не постродало. К примеру было "Из Парижа с любовью" а стало "Из Парижаслюбовью".

Код:
Func CompMovName($sInput, $sInputName)
;~ 	If FileExists(@ScriptDir & @ScriptName & '.tmp') Then Local $sInput = FileRead(@ScriptDir & @ScriptName & '.tmp')
	If $sInput = '' Then Return 'Фильтр $sInput пустой'
;~	FileWrite(@ScriptDir & 'test.txt',$sOutput)
	Local $sOutput = ''
	Local $a[3] = ['( )','(&laquo;)','(&raquo;)']
	Local $i
	Do
		If $sOutput <> '' Then $sInput = $sOutput
		$sOutput = StringRegExpReplace($sInput, $a[$i], " ")
		$i += 1
	Until $i = 3
;~ 	FileWrite(@ScriptDir & 'test1.txt',$sOutput)
	Local $aMovieNames = _StringBetween($sOutput, '<span class="name"><a href="/level/1/film/', '</a>', 1)
;~ 	_ArrayDisplay($aMovieNames, "")
	Local $sMovieNames = ''
	Local $sTrimTmp = ''
	$a = UBound($aMovieNames)-1
	$i = 0
	While 1
		$sTrimTmp = StringTrimLeft($aMovieNames[$i], 9)  ; Сдвигаем(удоляем) 9 лишних сиволов(xxxxxx/">) с лево
		$sMovieNames &= $sTrimTmp & ' | '
		If $i = $a Then ExitLoop
		$i += 1
	WEnd
;~ 	FileWrite(@ScriptDir & 'test2.txt',$sMovieNames)
;~ 	stringlen($sInputName)
;~ 	Local $Ret = StringInStr($sMovieNames, $sInputName, 0, 1, 1, 8)
;~ 	If $Ret = 0 Or @error = 1 Then
;~ 		Return 'Совпадений не найдено or @error = 1'
;~ 	Else
;~ 		Return 'Найдено совпадение.'
;~ 	EndIf
EndFunc
Одной строкой!
Код:
Bon Jovi: The Circle Tour | Прости, хочу на тебе жениться | Жизнь за гранью | Чудаки 3D | Путь воина | Клуб счастья | Зайцев, жги! История шоумена | Санта на продажу | О Богах и людях | Особые отношения | The Doors. When you're strange | Хроники Нарнии: Покоритель Зари | Убойные каникулы | Принцесса де Монпансье | А мама лучше! | Толстяки | Бугай | Жить | Валькирия | Иллюзионист | Ёлки | Норвежский лес | Человек у окна | Тэтсуо: Человек-пуля | Символ | Трон: Наследие | Знакомство с Факерами 2 | Три богатыря и Шамаханская царица | Медведь Йоги | Выходные! | За козла ответишь 3D | Двенадцать | Щелкунчик и Крысиный король 3D | Турист | Время ведьм | Путешествия Гулливера | Отчаянная домохозяйка | Прошлой ночью в Нью-Йорке | Доброе утро | Заложник смерти | Неадекватные люди | Самый лучший фильм 3-ДЭ | Ты встретишь таинственного незнакомца | Не бойся темноты | Аморе | Ариэти из страны лилипутов | Кроличья нора | Сатисфакция | Спящая красавица | Чрево | Механик | Потустороннее | Любовь и другие лекарства | Поцелуй сквозь стену | Я плюю на ваши могилы | Скелеты Железного острова | Все в порядке, мама! | Мужчина в поисках эротики | Зеленый Шершень | Не отпускай меня | Ты и я | Санктум | Путь домой | Дилемма |

Сравнение:

Итак, теперь у нас есть база данных(новинок), и далее мы якобы проводим мониторинг сайта на котором выходят новинки в виде торрент раздач, и все найденые новые раздачи будем сравнивать с базой данных на наличие совпадений с целью выявления новинка это или нет.

Названия найденых мониторингом раздач будут выглядеть примерно так.
Код:
В Филадельфии всегда солнечно / It's Always Sunny in Philadelphia (3 сезон, 3 серия) (2007) HDTVRip
Пятницкий (8 серия из 10) (2010) SATRip
Контракт / The Job (2009) DVDRip
Смерть шпионам! (1-8 серии из 8) (2007) DVDRip
Смерть шпионам 2 (1-8 серии из 8) (2008) DVDRip
Отличница лёгкого поведения / Easy A (2010) HDRip
Отличница лёгкого поведения / Easy A (2010) BDRip 720p
Один дома / Home Alone (1990) Blu-ray
Один дома 2: Затерянный в Нью-Йорке / Home Alone 2: Lost in New York (1992) Blu-ray
Универ (серия 210) (2010) SATRip
Винтаж - Роман (2010) SATRip
Телепорт / Jumper (2008) HDRip
Реальные пацаны (9 серия) (2010) SATRip
Выжившие / Survivors (1 сезон, 2 серия) (2008) WEB-DLRip
Толстяки / Gordos (2009) DVDRip
За 10000 лет до нашей эры / Journey to 10000 BC (2008) TVRip
ПоцелуйчИК / Love at First Hiccup (2009) BDRip 720p
ПоцелуйчИК / Love at First Hiccup (2009) HDRip
Тяжелый / The Heavy (2010) BDRip 1080p
Псевдоним Албанец - 3 (1 серия из 16) (2010) SATRip
Псевдоним Албанец - 3 (2 серия из 16) (2010) SATRip
VA - Fresh Trance #1-7 (2010)
Башня (10 серия из 12) (2010) SATRip
День и Ночь / Day & Night (2010) BDRip 720p
Копы в глубоком запасе / The Other Guys [EXTENDED] (2010) HDRip
Побег (11 серия из 22) (2010) SATRip
Маргоша-3 (56 серия из 60) (2010) IPTVRip
Нанолюбовь (20 серия из 40) (2010) IPTVRip
Хитрый вор / Кодекс вора / Thick as Thieves / The Code (2009) BDRip 720p
Фанатка / Groupie (2010)
Фанатка / Groupie (2010) DVDRip
Рестлинг WWE Survivor Series / Эфир 21.11.2010 (2010) SATRip
Футбол Чемпионат Италии 13-й тур / Обзор тура (2010) SATRip
Три дня на побег / The Next Three Days (2010) CAMRip
Обитель зла 4: Жизнь после смерти / Resident Evil: Afterlife (2010) HDRip
Обитель зла 4: Жизнь после смерти / Resident Evil: Afterlife (2010) BDRip 720p
Воздушные змеи / Kites (2010) BDRip
Футбол Чемпионат Испании 12-й тур / Обзор тура (2010) SATRip
Касл / Castle (3 сезон, 9 серия) (2010) WEB-DLRip
Сваты 4 (4 серия из 16) (2010) SATRip
Футбол Чемпионат Германии 13-й тур / Обзор тура (2010) SATRip
Зверобой - 2 (29 серия из 32) (2010) SATRip
Агент особого назначения (1-12 серии из 12) (2010) DVDRip
Сравнивать весь список нам не обязательно, просто для примера составил как можно больше вариантов названий раздач. Предположим что мониторинг засек создание раздачи под названием "Обитель зла 4: Жизнь после смерти / Resident Evil: Afterlife (2010) HDRip" и нам необходимо обработать это название раздачи, и сделать поиск по базе данных ожидаемых нами новинок.

Для успешного сравнения нам необходимо подготовить название фильма, чтоб не было ничего лишнего.
Исходное название: Обитель зла 4: Жизнь после смерти / Resident Evil: Afterlife (2010) HDRip
Необходимое название: Обитель зла 4: Жизнь после смерти

Из выше представленного списка фильмов видно, как правило всё лишнее находится за символами / или ( .

Код:
$1 = 'Фильм / movie (2010) DVDRip'
$len = stringlen($1)
$i = 0
$co = StringInStr($1,'/',2)
$Tmp = StringTrimLeft($1, $co - 2)
$filter = '(' & $Tmp & ')'
$str = StringRegExpReplace($1,$filter,'')
MsgBox(0,0,$filter)
MsgBox(0,0,$str)
$len = stringlen($str)
MsgBox(0,0,$len)
$result = stringinstr('Фильм',$str,2)
MsgBox(0, "result:", $result)
Данный пример не работает.

В выше представленном примере, я пытался удалить все что находится после символов / и ( .
Но код $str = StringRegExpReplace($1,$filter,'') должен был по сути удалить из строки "Фильм / movie (2010) DVDRip" все лишнее - " / movie (2010) DVDRip" .
Код:
$str = StringRegExpReplace('Фильм / movie (2010) DVDRip','( / movie (2010) DVDRip)','')


Так и не смог понять почему это не работает, вот и обратился за помошью.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Так :? (Только названия фильмов )
Код:
#include<Array.au3>

$sText=ClipGet()

$sPattern='film/\d+/">([А-Яа-я\s]+?)<'
$aFilmNames=StringRegExp($sText,$sPattern,3)
_ArrayDisplay($aFilmNames)

$sString=_ArrayToString($aFilmNames, "|")
MsgBox(0,'$sString',$sString)

Что еще надо не понял
 
Автор
N

Nelsy

Знающий
Сообщения
35
Репутация
8
Твой вариант в принципе работает, но с потерей латинских букв, цифр, и символов.

Код:
$sInput = ClipGet()
CompMovName($sInput)
Func CompMovName($sInput)
	Local $sOutput = ''
	Local $a[3] = ['( )','(&laquo;)','(&raquo;)']
	Dim $i
	Do
		If $sOutput <> '' Then $sInput = $sOutput
		$sOutput = StringRegExpReplace($sInput, $a[$i], " ")
		$i += 1
	Until $i = 3
	Local $aMovieNames = _StringBetween($sOutput, '<span class="name"><a href="/level/1/film/', '</a>', 1)
	_ArrayDisplay($aMovieNames, "")
	Local $sMovieNames = ''
	Local $sTrimTmp = ''
	$a = UBound($aMovieNames)-1
	$i = 0
	While 1
		$sTrimTmp = StringTrimLeft($aMovieNames[$i], 9)  ; Сдвигаем(удоляем) 9 лишних сиволов(xxxxxx/">) с лево
		$sMovieNames &= $sTrimTmp & ' | '
		If $i = $a Then ExitLoop
		$i += 1
	WEnd
	MsgBox(0,'$sString',$sMovieNames)
EndFunc
С маленькой поправкой:
Код:
Local $aMovieNames = _StringBetween($sOutput, '<span class="name"><a href="/level/1/film/', '</a>', 1)

Которая предпочтительно должна выглядеть так:
Код:
Local $aMovieNames = _StringBetween($sOutput, '<span class="name"><a href="/level/1/film/279728/">', '</a>', 1)

Вместо цифр 279728 должна стоять "Маска" которая будет указывать на то что там могут распологаться 6 цифр в диапазаоне от 000000 до 999999
В принципе это все не обязательно ибо и так все работает, и выдвинул я это как придеслове к основнуму вопросу.
Чтоб не заморачиватся всякими обьяснениеми которые только запустают вас еще больше, поставлю вопрос конкретней.

Предисловие:
У нас есть строка - название фильма
Код:
В Филадельфии всегда солнечно / It's Always Sunny in Philadelphia (3 сезон, 3 серия) (2007) HDTVRip
Мы знаем, что нам необходимо удалить все что идет после символа " / " в названии фильма. С целью получения точного названия фильма в виде строки:
Код:
В Филадельфии всегда солнечно
Учтем что вид строки может менятся:
Код:
В Филадельфии всегда солнечно / It's Always Sunny in Philadelphia (3 сезон, 3 серия) (2007) HDTVRip
Пятницкий (8 серия из 10) (2010) SATRip
Контракт / The Job (2009) DVDRip
Смерть шпионам! (1-8 серии из 8) (2007) DVDRip
Смерть шпионам 2 (1-8 серии из 8) (2008) DVDRip
Отличница лёгкого поведения / Easy A (2010) HDRip
Отличница лёгкого поведения / Easy A (2010) BDRip 720p
Один дома / Home Alone (1990) Blu-ray
Один дома 2: Затерянный в Нью-Йорке / Home Alone 2: Lost in New York (1992) Blu-ray
Универ (серия 210) (2010) SATRip
Винтаж - Роман (2010) SATRip
Телепорт / Jumper (2008) HDRip
Реальные пацаны (9 серия) (2010) SATRip
Выжившие / Survivors (1 сезон, 2 серия) (2008) WEB-DLRip
Толстяки / Gordos (2009) DVDRip
За 10000 лет до нашей эры / Journey to 10000 BC (2008) TVRip
ПоцелуйчИК / Love at First Hiccup (2009) BDRip 720p
ПоцелуйчИК / Love at First Hiccup (2009) HDRip
Тяжелый / The Heavy (2010) BDRip 1080p
Псевдоним Албанец - 3 (1 серия из 16) (2010) SATRip
Псевдоним Албанец - 3 (2 серия из 16) (2010) SATRip
VA - Fresh Trance #1-7 (2010)
Башня (10 серия из 12) (2010) SATRip
День и Ночь / Day & Night (2010) BDRip 720p
Копы в глубоком запасе / The Other Guys [EXTENDED] (2010) HDRip
Побег (11 серия из 22) (2010) SATRip
Маргоша-3 (56 серия из 60) (2010) IPTVRip
Нанолюбовь (20 серия из 40) (2010) IPTVRip
Хитрый вор / Кодекс вора / Thick as Thieves / The Code (2009) BDRip 720p
Фанатка / Groupie (2010)
Фанатка / Groupie (2010) DVDRip
Рестлинг WWE Survivor Series / Эфир 21.11.2010 (2010) SATRip
Футбол Чемпионат Италии 13-й тур / Обзор тура (2010) SATRip
Три дня на побег / The Next Three Days (2010) CAMRip
Обитель зла 4: Жизнь после смерти / Resident Evil: Afterlife (2010) HDRip
Обитель зла 4: Жизнь после смерти / Resident Evil: Afterlife (2010) BDRip 720p
Воздушные змеи / Kites (2010) BDRip
Футбол Чемпионат Испании 12-й тур / Обзор тура (2010) SATRip
Касл / Castle (3 сезон, 9 серия) (2010) WEB-DLRip
Сваты 4 (4 серия из 16) (2010) SATRip
Футбол Чемпионат Германии 13-й тур / Обзор тура (2010) SATRip
Зверобой - 2 (29 серия из 32) (2010) SATRip
Агент особого назначения (1-12 серии из 12) (2010) DVDRip

Вопрос: Как удалить в названии фильма все лишнее после символа " / " или " ( "

Предпочтительно: Методом определения в какой колонке находится символ " / " или " ( ", и удалением всего после него без использования StringRegExpReplace.
Всеже если решение будет с использованием StringRegExpReplace, желательно пояснить ваш ($sPattern='film/\d+/">([А-Яа-я\s]+?)<') Ибо в этих каракулях ничего не понятно, тоесть да.. вы помогли мне и у меня есть решение.. но знаний мне это не прибавит.

Код:
$1 = 'Фильм / Movie (2009) HDRip' ; Название фильма
$len = stringlen($1) ; узнаем длинну строки $1
$i = 0
$co = StringInStr($1,'/',2) ;находим символ " / " в строке $1 и возврощаем колонку в которой он находится
$Tmp = StringTrimLeft($1, $co - 2) ; помещаем в переменную все что идет после символа / с поправкой на пробел до него. Выходит " / Movie (2009) HDRip"
$sPattern = '(' & $Tmp & ')' ; создаем наш фильтр " / Movie (2009) HDRip"
$str = StringRegExpReplace($1,$sPattern,'') ; ищем " / Movie (2009) HDRip" в строке $1 = 'Фильм / Movie (2009) HDRip' и заменяем на "" - пустоту
MsgBox(0,0,$sPattern)
MsgBox(0,0,$str)
$len = stringlen($str)
MsgBox(0,0,$len)
$result = stringinstr('Фильм',$str,2)
MsgBox(0, "Search result:", $result)

Данный пример не работает: потому что фильтр $sPattern не правильно составлен, но надеюсь саму идею примера вы поняли и сможете подсказать как исправить ошибку.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Nelsy [?]
Твой вариант в принципе работает, но с потерей латинских букв, цифр, и символов.

Да это я не подумал .
Это устраняется просто :
надо изменить $sPattern в моем примере
на
Код:
$sPattern='film/\d+/">([^<]+?)<'
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Почти то же, но корректнее:
Код:
$Str = "Обитель зла 4: Жизнь после смерти! (/ Resident Evil: Afterlife (2010) BDRip 720p"

$number1 = StringInStr($Str, "/")
$number2 = StringInStr($Str, "(")

Select
    Case $number1 = 0
        str($number2)
    Case $number2 = 0
	str($number1)
    Case $number1 < $number2
	str($number1)
    Case $number1 > $number2
	str($number2)
EndSelect

Func str($number)
$Film = StringMid($Str, 1, $number-1)
MsgBox(64, "Film", $Film)
EndFunc
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Насчет алгоритма задачи.
На мой взгляд достаточно найти массив ИМЕН ФИЛЬМОВ
с помощью моего примера с исправленным шаблоном ($sPattern)

И не надо преобразовывать в строку и т.д.

Для поиска достаточно использовать ф-ию :
Код:
 _ArraySearch
,
которая при успехе поиска дает индекс строки массива , где найдено совпадение.




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

Nelsy [?]
желательно пояснить ваш ($sPattern

Код:
$sPattern='film/\d+/">([^<]+?)<'


Выбрать в массив фрагменты текста , следующие за :

фрагментом : film
символом : /
цифрами : \d в кол-ве 1 или более +?
cимволами : /">

и состоящие из любых символов ,
кроме < : [^<] в кол-ве 1 или более +?

если за ним непосредственно следует
символ : <

в массив попадает только то,что находится внутри скобок ([^<]+?)
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Дл корректности следуе удалить все пробелы перед названием фмльма и после,
поставив перед скобками и после \s?
 
Автор
N

Nelsy

Знающий
Сообщения
35
Репутация
8
Yuriy, Спасибо большое, все работает замечательно!
gregaz, Вам тоже спасибо огромное! Но к сожалению есть 1 нюанс:
Nelsy сказал(а):
В названиях фильмов встречаются что то вроде разделителей в таком виде , &laquo; , &raquo;
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Забыл.
Еще на всякий случай надо после обработки удалить все пробелы
окончания строки.
Код:
Func str($number)
$Film = StringMid($Str, 1, $number-1)
$Film = StringStripWS( $Film, 2) ;удалить все пробелы
окончания строки
MsgBox(64, "Film", $Film)
EndFunc
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Nelsy [?]
Но к сожалению есть 1 нюанс:
Цитата: Nelsy от Сегодня в 10:49:32
В названиях фильмов встречаются что то вроде разделителей в таком виде , &laquo; , &raquo;

Это какая-то форма пробела.

Может заменить ее на обычный пробел :
Код:
$sString=StringRegExpReplace($sString,"&.+?;"," "); Заменить все фрагменты,начинающиеся с "&" и оканчивающиеся  ";" , на обычный  пробел  ( " " )


или учесть его наличие в шаблоне ($sPattern) , в зависимости от его возможного местонахождения
( установив \s? или "(?:&.+?;)?" , где надо. )

Приведи пример строк с ними.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
А нашел на приведенной тобой странице по ссылке.

Это разделители между названием фильма и номером серии

Можно учесть таким шаблоном :
Код:
$sPattern='film/\d+/">\s?([^<]+?)(?:&.+?;\d+?)?\s?<'

но тогда номер серии не попадает в массив.

Надо в массиве уже делать замену в элементах:
Код:
$sString=StringRegExpReplace($sString,"&.+?;"," "); Заменить все фрагменты,начинающиеся с "&" и оканчивающиеся  ";" , на обычный  пробел  ( " " )


или то же самое сразу во всем тексте до нахождения массива , но это займет некоторое время (несколько секунд)

А может вообще не надо заменять ведь при повторном поиске этот пробел вместе с номером серии опять будет присутствовать значит и найдется
 
Верх