Соскоб динамических обновлений данных датчика температуры с веб-сайта
Я написал следующий код 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.
Полный веб-браузер выполняет как минимум четыре вещи:
- Подключается к веб-серверам, получает данные
- Анализирует HTML-контент и CSS-форматирование и представляет веб-страницу
- Разбирает контент Javascript, запускает его.
- Обеспечивает взаимодействие с пользователем для таких вещей, как навигация в браузере, 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