использование Beautifulsoup для find_all в массиве, возвращая только первые несколько результатов - PullRequest
0 голосов
/ 09 января 2019

Я успешно использовал BeautifulSoup для просмотра нескольких сотен страниц веб-страницы bandstown, которую можно посмотреть здесь: https://www.bandsintown.com/?came_from=257&page=102

Я могу перебирать каждую страницу для создания массива всех дат событий, называемых «uniqueDatesBucket». Печать массива дает мне следующее, как показано ниже (есть много результатов, я включил образец ниже).

print uniqueDatesBucket

Результат:

  [[<div class="event-b58f7990"><div class="event-ad736269">JAN</div><div class="event-d7a00339">08</div></div>, <div class="event-b58f7990"><div class="event-ad736269">JAN</div><div class="event-d7a00339">08</div></div>, ............................<div class="event-b58f7990"><div class="event-ad736269">JAN</div><div class="event-d7a00339">31</div></div>]]

Это как и ожидалось. Затем я хочу поместить месяц и день в отдельные массивы, чтобы начать создание базы данных дат. Вот код:

#Build empty array for month/date
uniqueMonth = []
uniqueDay = []

for i in uniqueDatesBucket[0]:
    uniqueMonthDay = i.find_all('div')

    uniqueMonth.append(uniqueMonthDay[0].text)
    uniqueDay.append(uniqueMonthDay[1].text)

print uniqueDay

Результат:

[u'08', u'08', u'08', u'08', u'08', u'08', u'08', u'08', u'08', u'09', u'09', u'09', u'09', u'09', u'09', u'09', u'09', u'09']

У меня такой вопрос: почему это возвращает только 18 результатов (на целевой странице страницы bands есть 18 событий, но я решил, что решил эту проблему с помощью описанного выше итератора страницы)? В элементе uniqueDatesBucket, который является родителем массива uniqueMonth, явно показано более 18 результатов.

Кроме того, что означает "u" перед каждой датой в результатах?

Ответы [ 2 ]

0 голосов
/ 09 января 2019

насколько я понимаю, ваша проблема не в разборе html, а в обработке данных или списка.

из вашего кода:

for i in uniqueDatesBucket[0]:

кажется, что вы только первый цикл цикла, вы имели в виду, что хотите все цикл?

for udb in uniqueDatesBucket:
    for i in udb:
        uniqueMonthDay = i.find_all('div')

        uniqueMonth.append(uniqueMonthDay[0].text)
        uniqueDay.append(uniqueMonthDay[1].text)
0 голосов
/ 09 января 2019

Я старался изо всех сил копировать ваш код, но я не очень далеко. Ссылка, которую вы предоставили, не дает мне такой же вывод, поэтому я не могу попытаться ее идеально воспроизвести.

Используя ваш список, который вы предоставили, я не столкнулся с проблемами, когда запустил его сам:

x = '<div class="event-b58f7990"><div class="event-ad736269">JAN</div><div class="event-d7a00339">08</div></div>, <div class="event-b58f7990"><div class="event-ad736269">JAN</div><div class="event-d7a00339">08</div></div>, <div class="event-b58f7990"><div class="event-ad736269">JAN</div><div class="event-d7a00339">31</div></div>'.split(', ')
x

Это дает мне следующее:

['<div class="event-b58f7990"><div class="event-ad736269">JAN</div><div class="event-d7a00339">08</div></div>',
 '<div class="event-b58f7990"><div class="event-ad736269">JAN</div><div class="event-d7a00339">08</div></div>',
 '<div class="event-b58f7990"><div class="event-ad736269">JAN</div><div class="event-d7a00339">31</div></div>']

Вот что я сделал, чтобы повторить это:

uniqueDatesBucket = []
uniqueMonth = []
uniqueDay = []

for item in x:
    uniqueDatesBucket.append(BeautifulSoup(item, 'html.parser'))

for i in uniqueDatesBucket:
    uniqueMonthDay = i.find_all('div')
    print('Day:\t' + uniqueMonthDay[2].text + '\tMonth:\t', uniqueMonthDay[1].text)

Вот мой вывод:

Day:    08  Month:   JAN
Day:    08  Month:   JAN
Day:    31  Month:   JAN

Обратите внимание, что индексы отличаются от того, что вы использовали, чтобы получить то же самое, отсюда и путаница.

Однако, если вы отказываетесь от предоставленного вами сайта, все было встроено в раздел JavaScript, что значительно упрощает анализ и получение правильных значений. Вот мой код для кражи его из JSON, встроенного в скрипт:

import requests
from bs4 import BeautifulSoup
import json
import re # regular expression, I just use it to extract the JSON from the JavaScript

x = requests.get('https://www.bandsintown.com/?came_from=257&page=102')

soup = BeautifulSoup(x.content, 'html.parser')

json_text = soup.find_all('script')[2].text # Gives you a JSON set to the valirable window.__data
json_extracted = re.search(r'^window.__data=(.+)', json_text).group(1) # Collect the JSON without variable assigning
json_parsed = json.loads(json_extracted)

# The dates are being hidden in json.homeView.body.popularEvents.events
for item in json_parsed['homeView']['body']['popularEvents']['events']:
    print(item['artistName'])
    print('Playing on', item['dayOfWeek'], item['dayOfMonth'], item['month'], '\n')

Вот вывод:

Florence and The Machine 
Playing on FRI 18 JAN 

Maroon 5
Playing on FRI 22 FEB 

Shawn Mendes
Playing on TUE 29 OCT 

John Mayer
Playing on WED 27 MAR 

Amy Shark
Playing on SAT 11 MAY 

Post Malone
Playing on TUE 30 APR 

John Butler Trio
Playing on THU 07 FEB 

Florence and The Machine 
Playing on SAT 19 JAN 

Ocean Alley
Playing on THU 14 MAR 

Bring Me the Horizon
Playing on SAT 13 APR

Что касается строк u'xyz', то это потому, что BeautifulSoup может выводить строку в формате Unicode (что означает u). Вы можете исправить это, набрав u'xyz'.decode('utf-8').

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