Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 2, 2017 11:36:44

d00m
Зарегистрирован: 2016-07-19
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг сайта на JS

доброго времени суток.

хочу написать телеграм бот, который будет показывать данные с одного тематического сайта.
то есть основная задача - парсить этот сайт, чтобы получить нужные данные.
на сайте есть форма входа, то есть надо зарегистрироваться.
нашел статейку на хабре по парсингу - https://habrahabr.ru/post/280238/#comment_8824194
с ее помощью я уже научился на python3 + либа requests, передавать auth данные и скачивать страницу по нужному URL.
НО, похоже из-за того, что на сайте используется JS, та часть страницы, которая содержит нужные мне данные, судя по всему просто не скачивается в файл в виде html с помощью такого кода:

 def load_user_data():
........
r2 = session.get(DATAURL)
return r2.text
data = load_user_data()
with open('data.html', 'w', encoding='UTF-8') as output_file:
	output_file.write(data)
в итоге скачанный файл data.html содержит всю страницу но БЕЗ нужных мне данных - просто пустое белое поле на их месте.
но если логиниться в браузере и открывать эту же страницу - то на этом месте есть нужные мне данные - это набор картинок и графиков отображающих текущие метеоусловия в выбранном месте.
например скорость ветра и направление его - отображаются в виде GIF файлов с определенными именами.
вот, думаю, “считывание” имен этих файлов и будет парсингом в моем понимании.

но на выкачанной странице эти данные в Chrome Inspect выглядят как ПУСТЫЕ отдельные DIV блоки с другими блоками LI внутри:

 <ul id="meteo" class="ui-sortable">
                	                		<li id="record_1" class="li "></li>           ----------- место1                     
                                        		<li id="record_2" class="li "></li>       ------------ место2                         
                          
                                        </ul>

а на online сайте внутри каждого LI блока еще есть один DIV блок и внутри него и находятся нужные мне данные, которые почему-то не выкачиваются:
 <li id="record_1" class="li ">
    <li>
         <div class="station" style="display:block">
                 <div class="float_left">
                         <div class="gadget_text">
                                 <img src="http://site.com/images/gadget/digits/4.gif" align="2"> 
                         </div>
                 </div>
    </li>
</li>


вот например - “images/gadget/digits/4.gif” значит что скорость ветра в этом месте == 4м/c

мои вопросы такие:
- почему эти данные не выгружаются в html файл с помощью модуля request - метод get() ?
- каким образом можно все таки получить эти данные (те URL картинок, что находятся в блоках DIV среди нужных мне данных) в код python чтобы потом обработать нужным мне образом?

спасибо всем, кто хотябы дочитал этот лонгрид)

Офлайн

#2 Авг. 2, 2017 13:28:09

Vintets
Зарегистрирован: 2016-07-05
Сообщения: 41
Репутация: +  6  -
Профиль   Отправить e-mail  

парсинг сайта на JS

d00m
почему эти данные не выгружаются в html файл с помощью модуля request - метод get() ?
ты же сам ответил выше:
d00m
похоже из-за того, что на сайте используется JS, та часть страницы, которая содержит нужные мне данные, судя по всему просто не скачивается в файл в виде html

А что делать? Самое простое, проанализировать какие ещё запросы отправляются позже при работе JS и самому делать эти запросы. Основная страница может и не нужна вовсе, если из её кода не берутся ни какие параметры.
Там, скорее всего, выбирается регион для показа погоды или город или координаты… и отправляется в новом запросе. Если пользователь авторизован у него прописан свой, ранее выбранный регион.

Отредактировано Vintets (Авг. 2, 2017 13:31:40)

Офлайн

#3 Авг. 2, 2017 13:32:46

d00m
Зарегистрирован: 2016-07-19
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг сайта на JS

ok
допустим я получил нужные мне данные в скачанную страницу.
как мне их получить в код скрипта в виде переменной?

например в data.html моем есть вот такое:

  <li id="record_1" class="li ">
    <li>
         <div class="station" style="display:block">
                 <div class="float_left">
                         <div class="gadget_text">
                                 <img src="http://site.com/images/gadget/digits/4.gif" align="2"> 
                                 <img src="http://site.com/images/gadget/digits/dot.gif" align="2"> 
                                 <img src="http://site.com/images/gadget/digits/5.gif" align="2"> 
                         </div>
                 </div>
    </li>
</li>

как мне в скрипте произвести поиск ВСЕГО что есть в DIV блоке gadget_text и сохранить в какието переменные?

то есть в идеале скрипт должен найти все три картинки там, причем в том же порядке - сначала с цифрой 4, потом “точка”, потом цифра 5.
и в итоге выдать мне строку вида “4.5” которую бот и вернет пользователю.

Офлайн

#4 Авг. 2, 2017 15:28:32

krok64
Зарегистрирован: 2017-04-04
Сообщения: 75
Репутация: +  11  -
Профиль   Отправить e-mail  

парсинг сайта на JS

d00m
как мне в скрипте произвести поиск ВСЕГО что есть в DIV блоке gadget_text и сохранить в какието переменные?
Посмотри пакет Beautiful Soup он как раз умеет то что тебе надо

Офлайн

#5 Авг. 2, 2017 16:20:56

d00m
Зарегистрирован: 2016-07-19
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг сайта на JS

да, я читаю уже про этот BeautifulSoup.
правда пока не понятно все таки, как найти эти img именно в этом месте..

а потом же еще надо будет порядок соблюсти и получить цифру..

Офлайн

#6 Авг. 2, 2017 16:36:46

krok64
Зарегистрирован: 2017-04-04
Сообщения: 75
Репутация: +  11  -
Профиль   Отправить e-mail  

парсинг сайта на JS

Если я не забыл CSS то как то так:

 a = soup.select("div .gadget_text > img")
порядок будет соблюден

Офлайн

#7 Авг. 2, 2017 16:42:21

d00m
Зарегистрирован: 2016-07-19
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг сайта на JS

сделал вот так:

 def parse(html):
	soup = BeautifulSoup(html)
	wind = soup.find('div', class_='gadget_text') # выбираю нужный мне DIV с моими данными
	for img in wind.find_all('img'):
		print(img.get('src'))  # печать всех URL на GIF

теперь надо какойто регуляркой их обработать)

Офлайн

#8 Авг. 3, 2017 11:55:39

Vintets
Зарегистрирован: 2016-07-05
Сообщения: 41
Репутация: +  6  -
Профиль   Отправить e-mail  

парсинг сайта на JS

Можно и без регулярок

 import os
from bs4 import BeautifulSoup
def parse(html):
    soup = BeautifulSoup(html, 'html.parser')
    wind = soup.find('div', class_='gadget_text')
    data = []
    for img in wind.find_all('img'):
        url = img.get('src')
        d = os.path.split(url)[1][:-4]
        d = d.replace('dot', '.')
        data.append(d)
    result = ''.join(data)
    print (result)
    return result
parse(html)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version