Проблема с возвратом вывода из Интернета как словаря - PullRequest
3 голосов
/ 22 января 2020

Итак, я пытаюсь очистить веб-сайт его списка сотрудников и хочу, чтобы конечным продуктом был словарь в формате {staff: position}. В настоящее время я застрял с ним, возвращая каждое штатное имя и должность в виде отдельной строки. Трудно четко опубликовать вывод, но он по существу идет вниз по списку имен, а затем по позиции. Так, например, первое имя в списке должно быть в паре с первой позицией, и так далее. Я определил, что каждое имя и должность class 'bs4.element.Tag. Я считаю, что мне нужно взять имена и позиции и составить список из каждого, а затем использовать zip, чтобы поместить элементы в словарь. Я пытался реализовать это, но пока ничего не получалось. Самое низкое, что я мог получить к нужному тексту, используя параметр class_, это индивидуальный div, в котором содержится p. Я все еще неопытен с python и новичком в изучении веб-страниц, но я относительность хорошо разбирается в html и css, поэтому помощь будет принята с благодарностью.

# Simple script attempting to scrape 
# the staff roster off of the 
# Greenville Drive website

import requests
from bs4 import BeautifulSoup

URL = 'https://www.milb.com/greenville/ballpark/frontoffice'

page = requests.get(URL)

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

staff = soup.find_all('div', class_='l-grid__col l-grid__col--xs-12 l-grid__col--sm-4 l-grid__col--md-3 l-grid__col--lg-3 l-grid__col--xl-3')

for staff in staff:
    data = staff.find('p')
    if data:
        print(data.text.strip())

position = soup.find_all('div', class_='l-grid__col l-grid__col--xs-12 l-grid__col--sm-4 l-grid__col--md-6 l-grid__col--lg-6 l-grid__col--xl-6')

for position in position:
    data = position.find('p')
    if data:
        print(data.text.strip())  

# This code so far provides the needed data, but need it in a dict()

Ответы [ 2 ]

3 голосов
/ 22 января 2020

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

import requests
from bs4 import BeautifulSoup

URL = 'https://www.milb.com/greenville/ballpark/frontoffice'
page = requests.get(URL)
soup = BeautifulSoup(page.content, 'html.parser')
staff_class = 'l-grid__col l-grid__col--xs-12 l-grid__col--sm-4 l-grid__col--md-3 l-grid__col--lg-3 l-grid__col--xl-3'
position_class = 'l-grid__col l-grid__col--xs-12 l-grid__col--sm-4 l-grid__col--md-6 l-grid__col--lg-6 l-grid__col--xl-6'
result = {}

for staff in soup.find_all('div', class_=staff_class):
    data = staff.find('p')
    if data:
        staff_name = data.text.strip()
        postion_div = staff.find_next('div', class_=position_class)
        postion_name = postion_div.text.strip()
        result[staff_name] = postion_name

print(result)

Выход

{'Craig Brown': 'Owner/Team President', 'Eric Jarinko': 'General Manager', 'Nate Lipscomb': 'Special Advisor to the President', 'Phil Bargardi': 'Vice President of Sales', 'Jeff Brown': 'Vice President of Marketing', 'Greg Burgess, CSFM': 'Vice President of Operations/Grounds', 'Jordan Smith': 'Vice President of Finance', 'Ned Kennedy': 'Director of Inside Sales', 'Patrick Innes': 'Director of Ticket Operations', 'Micah Gold': 'Senior Account Executive', 'Molly Mains': 'Senior Account Executive', 'Houghton Flanagan': 'Account Executive', 'Jeb Maloney': 'Account Executive', 'Olivia Adams': 'Inside Sales Representative', 'Tyler Melson': 'Inside Sales Representative', 'Toby Sandblom': 'Inside Sales Representative', 'Katie Batista': 'Director of Sponsorships and Community Engagement', 'Matthew Tezza': 'Sponsor Services and Activations Manager', 'Melissa Welch': 'Sponsorship and Community Events Manager', 'Beth Rusch': 'Director of West End Events', 'Kristin Kipper': 'Events Manager', 'Grant Witham': 'Events Manager', 'Alex Guest': 'Director of Game Entertainment & Production', 'Lance Fowler': 'Director of Video Production', 'Davis Simpson': 'Director of Media and Creative Services', 'Cameron White': 'Media Relations Manager', 'Ed Jenson': 'Broadcaster', 'Adam Baird': 'Accountant', 'Mike Agostino': 'Director of Food and Beverage', 'Roger Campana': 'Assistant Director of Food and Beverage', 'Wilbert Sauceda': 'Executive Chef', 'Elise Parish': 'Premium Services Manager', 'Timmy Hinds': 'Director of Facility Operations', 'Zack Pagans': 'Assistant Groundskeeper', 'Amanda Medlin': 'Business and Team Operations Manager', 'Allison Roedell': 'Office Manager'}
1 голос
/ 22 января 2020

Решение с использованием CSS селекторов и zip():

import requests
from bs4 import BeautifulSoup

url = 'https://www.milb.com/greenville/ballpark/frontoffice'

soup = BeautifulSoup(requests.get(url).content, 'html.parser')

out = {}
for name, position in zip( soup.select('div:has(+ div p) b'),
                           soup.select('div:has(> div b) + div p')):
    out[name.text] = position.text

from pprint import pprint
pprint(out)

Отпечатки:

{'Adam Baird': 'Accountant',
 'Alex Guest': 'Director of Game Entertainment & Production',
 'Allison Roedell': 'Office Manager',
 'Amanda Medlin': 'Business and Team Operations Manager',
 'Beth Rusch': 'Director of West End Events',
 'Brady Andrews': 'Assistant Director of Facility Operations',
 'Brooks Henderson': 'Merchandise Manager',
 'Bryan Jones': 'Facilities Cleanliness Manager',
 'Cameron White': 'Media Relations Manager',
 'Craig Brown': 'Owner/Team President',
 'Davis Simpson': 'Director of Media and Creative Services',
 'Ed Jenson': 'Broadcaster',
 'Elise Parish': 'Premium Services Manager',
 'Eric Jarinko': 'General Manager',
 'Grant Witham': 'Events Manager',
 'Greg Burgess, CSFM': 'Vice President of Operations/Grounds',
 'Houghton Flanagan': 'Account Executive',
 'Jeb Maloney': 'Account Executive',
 'Jeff Brown': 'Vice President of Marketing',
 'Jenny Burgdorfer': 'Director of Merchandise',
 'Jordan Smith ': 'Vice President of Finance',
 'Katie Batista': 'Director of Sponsorships and Community Engagement',
 'Kristin Kipper': 'Events Manager',
 'Lance Fowler': 'Director of Video Production',
 'Matthew Tezza': 'Sponsor Services and Activations Manager',
 'Melissa Welch': 'Sponsorship and Community Events Manager',
 'Micah Gold': 'Senior Account Executive',
 'Mike Agostino': 'Director of Food and Beverage',
 'Molly Mains': 'Senior Account Executive',
 'Nate Lipscomb': 'Special Advisor to the President',
 'Ned Kennedy': 'Director of Inside Sales',
 'Olivia Adams': 'Inside Sales Representative',
 'Patrick Innes': 'Director of Ticket Operations',
 'Phil Bargardi': 'Vice President of Sales',
 'Roger Campana': 'Assistant Director of Food and Beverage',
 'Steve Seman': 'Merchandise / Ticketing Advisor',
 'Timmy Hinds': 'Director of Facility Operations',
 'Toby Sandblom': 'Inside Sales Representative',
 'Tyler Melson': 'Inside Sales Representative',
 'Wilbert Sauceda': 'Executive Chef',
 'Zack Pagans': 'Assistant Groundskeeper'}
...