Соскоб динамических обновлений данных датчика температуры с веб-сайта

Я написал следующий код Python:

from bs4 import BeautifulSoup
import urllib2

url= 'http://www.example.com'
page = urllib2.urlopen(url)
soup = BeautifulSoup(page.read(),"html.parser")
freq=soup.find('div', attrs={'id':'frequenz'})
print freq

Результат:

<div id="frequenz" style="font-size:500%; font-weight: bold; width: 100%; height: 10%; margin-top: 5px; text-align: center">tempsensor</div>

Когда я смотрю на этот сайт с помощью веб-браузера, на веб-странице отображается динамическое содержимое, а не строка "tempsensor". Значение температуры автоматически обновляется каждую секунду. Итак, что-то на веб-странице заменяет строку "tempsensor" на числовое значение автоматически.

Моя проблема сейчас: Как я могу заставить Python отображать обновленное числовое значение? Как я могу получить значение автоматического обновления для tempsensor в BeautifulSoup?

3 ответа

Извините, нет, невозможно только с BeautifulSoup.

Проблема в том, что BS4 не является полноценным веб-браузером. Это всего лишь анализатор HTML. Он не разбирает ни CSS, ни Javascript.

Полный веб-браузер выполняет как минимум четыре вещи:

  1. Подключается к веб-серверам, получает данные
  2. Анализирует HTML-контент и CSS-форматирование и представляет веб-страницу
  3. Разбирает контент Javascript, запускает его.
  4. Обеспечивает взаимодействие с пользователем для таких вещей, как навигация в браузере, HTML-формы и API событий для программы Javascript

Все еще не уверены? Теперь посмотрите на ваш код. BS4 даже не включает в себя первый шаг, получение веб-страницы, чтобы сделать то, что вам пришлось использовать urllib2,

Динамические сайты обычно включают Javascript для запуска в браузере и периодического обновления содержимого. BS4 этого не обеспечивает, и поэтому вы их не увидите, и, более того, никогда не увидите их, используя только BS4. Зачем? Поскольку пункт (3) выше, загрузка и выполнение программы Javascript не происходит. Это будет происходить в IE, Firefox или Chrome, и именно поэтому они работают, чтобы показать динамический контент, в то время как скребки только для BS4 не показывают его.

PhantomJS и CasperJS предоставляют более механизированный браузер, который часто может запускать JavaScript-коды для динамических веб-сайтов. Но CasperJS и PhantomJS запрограммированы на серверном Javascript, а не на Python.

По-видимому, некоторые люди используют встроенный в PyQt4 браузер для таких задач динамического скрининга экрана, изолируя часть DOM и отправляя его в BS4 для анализа. Это может позволить решение для Python.

В комментариях @Cyphase предполагает, что нужные вам данные могут быть доступны по другому URL-адресу, и в этом случае они могут быть получены и проанализированы с помощью urllib2/BS4. Это можно определить путем тщательного изучения Javascript, который работает на сайте, особенно вы можете искать setTimeout а также setInterval какие графики обновлений, или ajaxили JQuery's .load функция для извлечения данных из серверной части. Javascript-коды для обновления динамического содержимого обычно извлекают данные только из внутренних URL-адресов того же веб-сайта. Если они используют JQuery $('#frequenz') ссылается на div, и при поиске этого в JS вы можете найти код, который обновляет div. Без JQuery JS обновление, вероятно, будет использовать document.getElementById('frequenz'),

Это должно сделать это:

freq.text.strip()

Как в

>>> html = '<div id="frequenz" style="font-size:500%; font-weight: bold; width: 100%; height: 10%; margin-top: 5px; text-align: center">tempsensor</div>'
>>> soup = BeautifulSoup(html)
>>> soup.text.strip()
u'tempsensor'

Вам не хватает чуть-чуть кода:

from bs4 import BeautifulSoup
import urllib2

url= 'http://www.example.com'
page = urllib2.urlopen(url)
soup = BeautifulSoup(page.read(), 'html.parser')
freq = soup.find('div', attrs={'id':'frequenz'})
print freq.string  # Added .string
Другие вопросы по тегам