Соскоб с помощью 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')
Другие вопросы по тегам