BeautifulSoup выполняет find () на итераторе - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть страница, которую мне нужно проанализировать с BeautifulSoup, вот код:

from bs4 import BeautifulSoup

source_html = 'WFM1.html'
data = []

with open(source_html) as html_file:
    soup = BeautifulSoup(html_file, 'lxml')

for tr in soup.find('tbody'):
    name_div = tr.find('div', class_= 'person-name-text inline-block ng-binding ng-hide')
    name = name_div.text.strip()
    shift_span = tr.find('span', class_= 'inline-block ng-binding ng-scope')
    shift = shift_span.text.strip()
    data.append((name, shift))

Когда я запускаю это, он возвращает «TypeError: find () не принимает аргументы ключевого слова».Можно ли выполнить find () на итераторе?Как мне извлечь только определенный контент из итератора?

Чтобы было понятнее, вот как выглядит итератор:

<tr class="ng-scope" role="button" style="" tabindex="0">
    <td class="person-name-column">
        <div aria-hidden="false" class="wfm-checkbox">
            <label><input aria-invalid="false" class="ng-pristine ng-untouched ng-valid ng-empty" type="checkbox"> <span class="wfm-checkbox-toggle"></span> <span class="wfm-checkbox-label person-name-text inline-block ng-binding">FirstName LastName <!-- ngIf: vm.toggles.ViewScheduleOnTimezoneEnabled && vm.selectedTimezone && personSchedule.Timezone.IanaId !== vm.selectedTimezone --></span></label> <!-- ngIf: vm.toggles.ViewScheduleOnTimezoneEnabled && vm.selectedTimezone && personSchedule.Timezone.IanaId !== vm.selectedTimezone -->
        </div>
        <div aria-hidden="true" class="person-name-text inline-block ng-binding ng-hide">
            FirstName LastName
        </div><!-- ngIf: vm.showWarnings -->
    </td><!-- ngIf: ::vm.toggles.ViewShiftCategoryEnabled -->
    <td class="shift-category-cell ng-scope" role="button" style="cursor: pointer;" tabindex="0"><!-- ngIf: ::personSchedule.ShiftCategory.Name --> <span class="inline-block ng-binding ng-scope" id="name" style="background: rgb(255, 99, 71); color: black;">EX</span> <!-- end ngIf: ::personSchedule.ShiftCategory.Name -->
    <!-- ngIf: ::personSchedule.ShiftCategory.Name --><!-- end ngIf: ::personSchedule.ShiftCategory.Name --></td><!-- end ngIf: ::vm.toggles.ViewShiftCategoryEnabled -->
    <td class="schedule schedule-column">
        <div class="relative time-line-for">
            <!-- ngRepeat: dayOff in ::personSchedule.DayOffs -->
            <!-- ngRepeat: shift in ::personSchedule.Shifts -->
            <div class="shift ng-scope">
                <!-- ngRepeat: projection in ::shift.Projections -->
                <div aria-label="Phone 04:00 - 08:00" class="layer absolute floatleft selectable projection-layer ng-scope noneSelected" role="button" style="left: 3.7037%; width: 14.8148%; background-color: rgb(255, 255, 0);" tabindex="0"></div><!-- end ngRepeat: projection in ::shift.Projections -->
                <div aria-label="Lunch 08:00 - 08:30" class="layer absolute floatleft selectable projection-layer ng-scope noneSelected" role="button" style="left: 18.5185%; width: 1.85185%; background-color: rgb(0, 255, 0);" tabindex="0"></div><!-- end ngRepeat: projection in ::shift.Projections -->
                <div aria-label="Coffee 08:30 - 08:45" class="layer absolute floatleft selectable projection-layer ng-scope noneSelected" role="button" style="left: 20.3704%; width: 0.925926%; background-color: rgb(224, 224, 224);" tabindex="0"></div><!-- end ngRepeat: projection in ::shift.Projections -->
                <div aria-label="Phone 08:45 - 10:30" class="layer absolute floatleft selectable projection-layer ng-scope noneSelected" role="button" style="left: 21.2963%; width: 6.48148%; background-color: rgb(255, 255, 0);" tabindex="0"></div><!-- end ngRepeat: projection in ::shift.Projections -->
                <div aria-label="FL 10:30 - 12:30" class="layer absolute floatleft selectable projection-layer ng-scope noneSelected" role="button" style="left: 27.7778%; width: 7.40741%; background-color: rgb(255, 140, 0);" tabindex="0"></div><!-- end ngRepeat: projection in ::shift.Projections -->
            </div><!-- end ngRepeat: shift in ::personSchedule.Shifts -->
            <!-- ngIf: vm.hasHiddenScheduleAtStart(personSchedule) -->
            <!-- ngIf: vm.hasHiddenScheduleAtEnd(personSchedule) -->
        </div>
    </td><!-- ngIf: ::!vm.toggles.EditAndViewInternalNoteEnabled -->
    <!-- ngIf: ::vm.toggles.EditAndViewInternalNoteEnabled -->
    <td class="schedule-note-column ng-scope" role="button" tabindex="0"><span class="noComment"><i class="mdi mdi-comment"></i></span> <!-- ngIf: vm.getScheduleNoteForPerson(personSchedule.PersonId) && vm.getScheduleNoteForPerson(personSchedule.PersonId).length > 0 --></td><!-- end ngIf: ::vm.toggles.EditAndViewInternalNoteEnabled -->
    <!-- ngIf: ::vm.toggles.ShowContractTimeEnabled -->
    <td class="contract-time contract-time-column ng-binding ng-scope">8:00</td><!-- end ngIf: ::vm.toggles.ShowContractTimeEnabled -->
</tr>

1 Ответ

0 голосов
/ 27 февраля 2019

Ваш тип супа <class 'bs4.BeautifulSoup'>, поэтому вам не нужно выполнять итерацию с использованием for.

name_div = soup.find('div', class_= 'person-name-text inline-block ng-binding ng-hide')
name = name_div.text.strip()
shift_span = soup.find('span', class_= 'inline-block ng-binding ng-scope')
shift = shift_span.text.strip()
data.append((name, shift))
print(data)

ВЫХОД:

[('FirstName LastName', 'EX')]

ОБНОВЛЕНИЕ:

Если выиметь более одного класса person-name-text inline-block ng-binding ng-hide. И предположим, что это ваш html в файле hmtl:

<div aria-hidden="true" class="person-name-text inline-block ng-binding ng-hide">
        FirstName LastName
    </div>
    <div aria-hidden="true" class="person-name-text inline-block ng-binding ng-hide">
        FirstName LastName
    </div>
    <div aria-hidden="true" class="person-name-text inline-block ng-binding ng-hide">
        FirstName LastName
    </div>
    <div aria-hidden="true" class="person-name-text inline-block ng-binding ng-hide">
        FirstName LastName
    </div>

Вы можете получить все с помощью find_all (), например:

name_div = soup.find_all('div', class_= 'person-name-text inline-block ng-binding ng-hide')
for all in name_div:
    print(all.text.strip())

OUTPUT:

FirstName LastName
FirstName LastName
FirstName LastName
FirstName LastName
...