Соскоб с помощью Dryscrape и BeautifulSoup
Я пытаюсь очистить некоторые данные от Yahoo. Я написал сценарий, который работает - иногда. Иногда, когда я запускаю сценарий, я могу загрузить всю страницу - в других случаях страница загружается только частично - часть данных отсутствует.
Что еще больше удивляет, так это то, что при переходе на эту страницу в браузере отображается вся страница.
Вот суть моего кода:
import dryscrape
from bs4 import BeautifulSoup
url = 'http://finance.yahoo.com/quote/SPY/options?p=SPY&straddle=false'
sess = dryscrape.Session()
sess.set_header('user-agent', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0')
sess.set_attribute('auto_load_images', False)
sess.set_timeout(360)
sess.visit(url)
soup = BeautifulSoup(sess.body(), 'lxml')
# Related to memory leak issue in webkit
sess.reset()
# Barfs (sometimes!) at the line below
sel_list = soup.find('select', class_='Fz(s)')
if sel_list is None or len(sel_list) == 0:
print('element not found on page!')
Я приложил изображения страниц, выбранных ниже. Вот веб-страница при просмотре через Интернет через веб-браузер:
Теперь вот страница, которую я вытащил с помощью скрипта, подобного показанному выше, - и у него нет данных!:
Может кто-нибудь понять, почему элемент иногда отсутствует, когда данные выбираются моим сценарием? В равной степени (больше?) Важно, как я могу это исправить?
1 ответ
Возможно, вам придется подождать загрузки данных, прежде чем анализировать их BeautifulSoup
, В dryscrape
ожидание может быть сделано через wait_for()
функция:
sess.visit(url)
# waiting for the first data row in a table to be present
sess.wait_for(lambda: session.at_css("tr.data-row0"))
soup = BeautifulSoup(sess.body(), 'lxml')
Или выстрел в темноте: это также может быть временная (сетевая?) Проблема, и вы можете обойти ее, обновляя страницу в цикле, пока не увидите результат, что-то вроде этого:
from dryscrape.mixins import WaitTimeoutError
ATTEMPTS_COUNT = 5
attempts = 0
while attempts <= ATTEMPTS_COUNT:
sess.visit(url)
try:
# waiting for the first data row in a table to be present
sess.wait_for(lambda: session.at_css("tr.data-row0"))
break
except WaitTimeoutError:
print("Data row has not appeared, retrying...")
attempts += 1
soup = BeautifulSoup(sess.body(), 'lxml')