Гость
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Парсер / 25 сообщений из 30, страница 1 из 2
23.09.2018, 11:50
    #39706510
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Всем доброго времени суток!
Понимаю, что я не первый с таким вопросом, но ковыряюсь уже неделю, понимаю что истина где то рядом, но никак не могу ее найти.
Суть такая: есть определенная таблица с наименованием товара, допустим, есть в таблице ссылки на эти товары, нужно с двух-трех сайтов тянуть их цену, цены в коде представлены так: <span class="goldPrice" data-unit-price="385" data-default-price="385">385</span>.
Перебрал множество тем посвященных парсингу на vba, но так ничего путного не нашел.
В этой теме http://www.sql.ru/forum/360384-1/kak-vytashhit-dannye-s-web-stranicy есть код, но не пойму как его подкрутить под свою задачу.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
Sub oh()

Dim i, s, o As New MSXML2.XMLHTTP

For i = 1 To 20
o.Open "GET", Cells(i, 1).Hyperlinks(1).Address, False
o.send
s = o.responseText

MsgBox s

<здесь вытягиваем из строки s нужную инфу и записываем ее куда надо>

Next i

Set o = Nothing

End Sub
...
Рейтинг: 0 / 0
23.09.2018, 11:56
    #39706511
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Конечно, при серьезной работе следовало бы работать с DOM или использовать RegExp, но в данном простейшем случае, что именно вызывает затруднение? Нашел подстроку
<span class="goldPrice" data-unit-price="забрал все, что после нее и до следующей кавычки, да и все.
...
Рейтинг: 0 / 0
23.09.2018, 12:07
    #39706516
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Проблема в поверхностном знании vba, вот допустим взять код, который я выше дал,
понимаю что он перебирает ссылки в ячейках, а как сделать чтоб он находил то, что надо и записывал куда надо не пойму.
Пробовал ковырять методом webpagetext, получается весь текст со страницы тянет...
На DOMe немного проще было бы, но нужно именно в excel сделать ввиду некоторых обстоятельств.
Причем в гугл таблицах при помощи IMPORTXML все легко, но проблема что если больше 50 позиций то все помирает...
...
Рейтинг: 0 / 0
23.09.2018, 12:28
    #39706523
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
в переменной "s" находится нужный текст (?)

для того, чтобы найти в нем нужный фрагмент, понадобится функция Instr, вырезать из него нужный фрагмент - функция Mid. Описание этих функций и примеры их использования смотрите в справке, пишите код, если он не заработает - публикуйте - подправим.
...
Рейтинг: 0 / 0
23.09.2018, 17:41
    #39706584
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Спасибо, почитал, только не могу найти примеры с использованием этих функций для парсинга, везде в примерах показано как локально найти символ или строку.
Вот пример взят с сайта майкрософт:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Dim SearchString, SearchChar, MyPos
SearchString ="XXpXXpXXPXXP"    ' String to search in.
SearchChar = "P"    ' Search for "P".
' A textual comparison starting at position 4. Returns 6.
MyPos = Instr(4, SearchString, SearchChar, 1)    
' A binary comparison starting at position 1. Returns 9.
MyPos = Instr(1, SearchString, SearchChar, 0)
' Comparison is binary by default
' (last argument is omitted).
MyPos = Instr(SearchString, SearchChar)    ' Returns 9.
MyPos = Instr(1, SearchString, "W")    ' Returns 0.


Если я правильно понимаю, то в мое случае код должен выглядеть примерно так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Sub oh()

Dim i, s, o As New MSXML2.XMLHTTP

For i = 1 To 20
o.Open "GET", Cells(i, 1).Hyperlinks(1).Address, False
o.send
s = o.responseText
Dim SearchString, SearchChar, MyPos
SearchString ="XXpXXpXXPXXP"    ' String to search in. - здесь указать начало подстроки?
SearchChar = "P"    ' Search for "P". - здесь указать класс?
MyPos = Instr(1, SearchString, SearchChar, 0)
MsgBox s



Next i

Set o = Nothing

End Sub


Пробовал экспериментировать, теперь код ругается на 4 строку, пишет out of range, в общем голова кругом...
...
Рейтинг: 0 / 0
23.09.2018, 17:54
    #39706587
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Ну так вам нужно искать не единственный символ, а строку (выше я выделил, какую именно)

eshkinkotтеперь код ругается на 4 строку, пишет out of rangeСкорее всего потому, что в ячейке А1 текущего листа у вас больше нет гиперссылки.
...
Рейтинг: 0 / 0
23.09.2018, 18:29
    #39706599
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
то есть SearchChar не нужна?
оставляю SearchString там прописываю начало строки?
Код: vbnet
1.
2.
3.
Dim SearchString, SearchChar, MyPos
SearchString ="<span class="goldPrice" data-unit-price=""    ' String to search in. - здесь указать начало подстроки?
MyPos = Instr(1, SearchString, SearchChar, 0)


так?
...
Рейтинг: 0 / 0
23.09.2018, 18:41
    #39706605
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Нет. SearchString - это ГДЕ искать, то есть s
Вместо SearchChar - ЧТО искать - то есть нужная подстрока.
И не забудьте, что когда записываете литеральную строку, заключенную в кавычки, кавычки входящие в нее должны удваиваться
...
Рейтинг: 0 / 0
23.09.2018, 19:07
    #39706626
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Немного начинаю понимать, но в приведенном выше коде S приравнена к o.responseText и в первоначальном коде она возвращает в msgbox, но мне не нужен он, мне нужно чтоб просто переходила по ссылке, находила заданную строчку, брала оттуда то что нужно и записывала в определенную ячейку...
Соответственно если я все правильно понимаю переменная s при выполнении кода выдает мне только текст, там нет того что мне нужно, соответственно должно наверное получиться так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Sub oh()

Dim i, s, o As New MSXML2.XMLHTTP

For i = 1 To 20
o.Open "GET", Cells(i, 1).Hyperlinks(1).Address, False
o.send
s = o.responseText
Dim SearchString, SearchChar, MyPos
SearchString ="s"   
SearchChar = ""<span class="goldPrice" data-unit-price=""    
MyPos = Instr(1, SearchString, SearchChar, 0)
MsgBox s



Next i

Set o = Nothing

End Sub
...
Рейтинг: 0 / 0
23.09.2018, 19:09
    #39706629
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Не получилось... все равно в msgbox выдает только текст
...
Рейтинг: 0 / 0
23.09.2018, 19:21
    #39706634
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
eshkinkotСоответственно если я все правильно понимаю переменная s при выполнении кода выдает мне только текст, там нет того что мне нужно,Я перестаю понимать. Я не могу знать, есть ли в переменной s нужный вам текст (<span....), так как у меня нет ваших ссылок. Если нужного текста там нет, то что мы тогда пытаемся искать?

Далее:
eshkinkot
Код: vbnet
1.
SearchString ="s" 

Тут вы пытаетесь присвоить переменной SearchString строку "s". Наверное это не то, что вы хотели. Вам вообще не нужна SearchString, у вас уже есть переменная s.

Далее, от того, что вы воспользовались Instr, сама переменная s никак не изменится, так что MsgBox вам ничего нового не даст. Вам требуется найти позицию начала нужного вам фрагмента, потом позицию конца фрагмента, а потом вырезать его из s с помощью функции Mid
...
Рейтинг: 0 / 0
23.09.2018, 20:05
    #39706651
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
ммм... для более полного понимания распишу все по полочкам.
Есть таблица в excel, в ней есть столбцы с наименованием товара, в соседнем столбце есть ссылка на сайт, в следующем столбце необходимо вывести цену с сайта, которая заключена здесь: <span class="goldPrice" data-unit-price="385" data-default-price="385">385</span>.
Код выше не мой, его нашел на этом сайте, мне показалось что он наиболее подходит. В переменной s исходя из того, что выводит msgbox цены товара нет.
тестирую по этой ссылке https://tver.petrovich.ru/catalog/17333/106958/
...
Рейтинг: 0 / 0
23.09.2018, 20:57
    #39706666
Казанский
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
eshkinkot,
примерно так
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Sub oh()
Const KEY = "<span class=""goldPrice"" data-unit-price="""
Dim i&, j&, s$, o As New MSXML2.XMLHTTP
  On Error Resume Next
  For i = 1 To 20
    o.Open "GET", Cells(i, 1).Hyperlinks(1).Address, False
    o.send
    If Err Then
      Err.Clear
    Else
      s = o.responseText
      j = InStr(1, s, KEY, vbTextCompare)
      If j > 0 Then Cells(i, 2) = Val(Mid$(s, j + Len(KEY), 10))
    End If
  Next i
  Set o = Nothing 'необязательно
End Sub
...
Рейтинг: 0 / 0
23.09.2018, 21:11
    #39706672
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
спасибо большое! буду изучать и допиливать)))
...
Рейтинг: 0 / 0
24.09.2018, 10:53
    #39706825
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Казанский, все отлично работает, но как реализовать поддержку нескольких сайтов? сейчас он смотрит ссылку в А1, кладет в В1, как реализовать чтоб он смотрел потом С1 клал в D1 и т.д.? Дублировать модуль?
...
Рейтинг: 0 / 0
24.09.2018, 11:05
    #39706835
Казанский
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
eshkinkot,
код смотрит в А1:А20 - это в вашем исходном коде было - и кладет в В1:В20.
Если у Вас все в первой строке через одну ячейку, то так
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Sub oh1()
Const KEY = "<span class=""goldPrice"" data-unit-price="""
Dim i&, j&, s$, o As New MSXML2.XMLHTTP
  On Error Resume Next
  For i = 1 To 20 Step 2
    o.Open "GET", Cells(1, i).Hyperlinks(1).Address, False
    o.send
    If Err Then
      Err.Clear
    Else
      s = o.responseText
      j = InStr(1, s, KEY, vbTextCompare)
      If j > 0 Then Cells(1, i + 1) = Val(Mid$(s, j + Len(KEY), 10))
    End If
  Next i
  Set o = Nothing 'необязательно
End Sub
...
Рейтинг: 0 / 0
24.09.2018, 11:36
    #39706865
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Спасибо, но это если мы парсим один сайт, а если допустим А1 - один сайт, С1 - второй сайт, D1 - третий? соответственно строчка <span class="goldPrice" data-unit-price=" будет для каждого сайта своя.
Замучил наверно вас уже)
...
Рейтинг: 0 / 0
24.09.2018, 11:40
    #39706867
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
eshkinkotсоответственно строчка <span class="goldPrice" data-unit-price=" будет для каждого сайта своя.И много у вас еще тузов в рукаве?
Ну размещайте эту строчку в соседней ячейке со ссылкой
...
Рейтинг: 0 / 0
24.09.2018, 11:49
    #39706876
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Shocker.Proeshkinkotсоответственно строчка <span class="goldPrice" data-unit-price=" будет для каждого сайта своя.И много у вас еще тузов в рукаве?
Ну размещайте эту строчку в соседней ячейке со ссылкой
Нет) Тузы все вышли) просто на одном сайте цена прячется здесь: <span class="goldPrice" data-unit-price=" , в другом сайте <div class="price_wrap"><ins>455,00 <span class="rouble">⃏</span></ins><p>шт. (40 в упаковке)</p></div>, и в третьем сайте <span class="card-order-price-int" itemprop="price" content="385.00">385</span>
...
Рейтинг: 0 / 0
25.09.2018, 19:24
    #39707951
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Shocker.Pro,
суть понял, делаю так: в первой ячейке даю ссылку, во второй переменную которую надо искать.
Тогда, как мне подсказывает сайт майкрософт, я должен свой код привести к следующему виду:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Sub oh()

Const KEY = ActiveSheet.Range("C2:D10").Select

Dim i&, j&, s$, o As New MSXML2.XMLHTTP
  On Error Resume Next
  For i = 2 To 1000
    o.Open "GET", Cells(i, 1).Hyperlinks(1).Address, False
    o.send
    If Err Then
      Err.Clear
    Else
      s = o.responseText
      j = InStr(1, s, KEY, vbTextCompare)
      If j > 0 Then Cells(i, 2) = Val(Mid$(s, j + Len(KEY), 10))
    End If
  Next i
  Set o = Nothing '?????????????
End Sub


Но тогда получаю ошибку: Constant expression required, ругается на .select, что делаю не так?
...
Рейтинг: 0 / 0
25.09.2018, 19:39
    #39707957
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
eshkinkot
Код: vbnet
1.
Const KEY = ActiveSheet.Range("C2:D10").Select

метод тыка - плохой помощник.
Понимаете, либо мне сейчас понадобится изложить пару глав учебника, чтобы объяснить, что вы делаете не так и что надо делать, либо написать программу за вас, но тогда вы захотите этого постоянно и будете обращаться все за новыми и новыми задачами. Вам Казанский написал рабочую программу, но вы даже не удосужились досконально разобраться, как она работает. Начните с этого хотя бы.
...
Рейтинг: 0 / 0
25.09.2018, 20:40
    #39707982
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
В коде Казанского все логично:
Объявляем константу, в которой прописываем часть необходимой строки поиска,
дальше объявляем переменные,
в следующей строке задаем цикл(число ячеек для просмотра ссылок)
Дальше смотрим ячейку, берем гипер ссылку, открываем страницу, выдираем то, что нужно и переходим к следующей ссылке, возвращая в текстовом формате нужную инфу.
Это как я понимаю этот код, ибо являюсь самоучкой и к сожалению приходится учиться методом тыка.
Так же понимаю что в константе нужно задать не фрагмент кода, а диапазон ячеек... А как это сделать не могу понять, так как справка толком ничего не объясняет, а в инете примеров куча, но тяжело осмыслить как допилить под себя.
...
Рейтинг: 0 / 0
26.09.2018, 05:20
    #39708110
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
eshkinkotк сожалению приходится учиться методом тыка.Кто вас заставляет? Литературы полно - принципиально учебники не читаете?


eshkinkotТак же понимаю что в константе нужно задать не фрагмент кода, а диапазон ячеек..Плохо понимаете. Вообще неверно. Вы же ссылки, которые перебираете, в константу не запихиваете? Они у вас просто лежат в ячейках в столбце 2. Точно так же в столбце 3 будут лежать нужные строки для поиска. И обращаться вы будете к ним точно так же через Cells(i, 3) - не придумывайте лишнего.
...
Рейтинг: 0 / 0
26.09.2018, 08:59
    #39708159
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Shocker.ProКто вас заставляет? Литературы полно - принципиально учебники не читаете?

Вы будете смеяться, но учебники вроде читаю, вроде понятно, но информация не усваивается, быстрее учусь при разборе готового кода
...
Рейтинг: 0 / 0
26.09.2018, 09:55
    #39708197
eshkinkot
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсер
Shocker.Pro,

Поковырял немного код, вот что получилось:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Sub oh()

Dim i&, j&, s$, o As New MSXML2.XMLHTTP
  On Error Resume Next
  For i = 1 To 20
    o.Open "GET", Cells(i, 1).Hyperlinks(1).Address, False
    o.send
    If Err Then
      Err.Clear
    Else
      s = o.responseText
      j = InStr(1, s, Cells(i, 2), vbTextCompare)
      If j > 0 Then Cells(i, 3) = Val(Mid$(s, j + Len(Cells(i, 2)), 10))
    End If
  Next i
  Set o = Nothing '?????????????
End Sub


Все работает, перебирает))) Но будьте добры, подскажите из трех сайтов показывает только два, у одного сайта цена прячется здесь:
<div class="price_wrap"><ins>455,00 <span class="rouble">⃏</span></ins>
как мне из нее вытащить?
...
Рейтинг: 0 / 0
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Парсер / 25 сообщений из 30, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]