Как получить дочерние теги span с помощью BeautifulSoup / MechanicalSoup - выбор значений раскрывающихся полей - PullRequest
0 голосов
/ 27 марта 2019

Я пытаюсь заполнить форму на веб-странице (http://supermag.jhuapl.edu/mag/?) с помощью MechanicalSoup. Перед отправкой необходимо указать дату в той же форме, используя выпадающие списки для дня начала, месяца, года, время и т. д. Это можно сделать с помощью функции set_select() MechanicalSoup, но я не могу получить доступ к соответствующему тегу select для каждого поля. Небольшой отказ от ответственности, хотя у меня есть опыт научного программирования, я новичок в HTML и Pythonбиблиотеки, упомянутые выше.

Хотя я не уверен, какую библиотеку лучше использовать для выбора даты, я не могу получить доступ к соответствующему тегу select, который является дочерним элементом соответствующих тегов span в формес атрибутами имени, такими как 'start_day', 'start_month'.

У меня есть оба объекта mechanicalsoup.Form(form) и mechanicalsoup.StatefulBrowser(*args, **kwargs) (последний соответствует объекту bs4.BeautifulSoup), и я попытался:

  • Установка тегов select с помощью MechanicalSoup's set_select
  • Поиск соответствующего тега span и использование BeautifulSoup to получить доступ к элементам ниже (в частности, к тегам select), чтобы каким-то образом затем выбрать значение, изменив URL (?)

Показан фрагмент соответствующего HTML-кода;отметьте теги div и последующие теги select как дочерние.

Тег формы:

<form name="theForm" class="form-horizontal" onsubmit="return false;">

Соответствующий диапазон и выберите теги в форме:

<span name="start_time">
  <div>
    <select name="start_day">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>...
    </select>
    <select style="width: 4em;" name="start_month">
      <option value="1">January</option>
      <option...
    </select>
  </div>
</span>

Код находится ниже:

# Opening browser and URL
url = "http://supermag.jhuapl.edu/mag/?"
browser = ms.StatefulBrowser()
browser.open(url)

# Assigning bs4.BeautifulSoup object
html = browser.get_current_page()

# Assigning relevant form
form = browser.select_form('form[name="theForm"]')

# Assign correct span tag for e.g start_time
start_time_span = html.find_all('span')[2]

# Attempt to set start day value - returns
# 'InvalidFormMethod: No select named start_day'
form.set_select({'start_day': 1})

# Attempt to find select tags with bs4
html.find('select', {'start_day': 1})
start_time_span.find('select', {'start_day': 1})

# and eg looking for contents returns empty list
start_time_span.contents

Я ожидал, что теги select будут перечислены в попытках bs4 find(), или для механического суппорта set_select() для доступа и установки заданного selectтег при вызове на правильной форме.

Тег span находится в HTML-файле BeautifulSoup, но, похоже, не имеет дочерних тегов select, которые присутствуют в исходном HTML и необходимы для выбора даты.Вызов set_select() возвращает ошибку, в которой говорится, что тег не найден.

Заранее спасибо;это мой первый вопрос по StackOverflow, и я надеюсь, что он достаточно хорошо соответствует правилам!

1 Ответ

0 голосов
/ 27 марта 2019

Для меня ваш код выглядит нормально!Когда я запускаю ваш фрагмент кода Python для HTML-кода, который вы цитируете здесь, он не вызывает исключение InvalidFormMethod.Однако, когда я запускаю его по указанному вами URL-адресу, я вижу эту ошибку (потому что, глядя на исходный HTML, нет элемента с именем start_day).

Я подозреваю, что это потому, чтоконкретное действие JavaScript генерирует HTML-код, включающий поле start_day.На это намекает форма с атрибутом onsubmit и без action, а также с большим количеством файлов JavaScript (которые могут или не могут быть необходимы для взаимодействия с формой).В зависимости от того, что именно вы хотите сделать с этой формой, вам, вероятно, потребуется использовать инструмент, поддерживающий JavaScript, например Selenium (MechanicalSoup этого не делает - см. этот FAQ ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...