Как правильно использовать функцию выбора в BeautifulSoup4? - PullRequest
2 голосов
/ 25 апреля 2019

Я пишу свой первый сценарий, используя BS4 в качестве вступления к поиску в Интернете, и у меня возникли проблемы.Я следую вместе с Automate The Boring Stuff с руководством Python, где он использует soup.select('insert class here') для выбора классов.Когда я запускаю код, показанный ниже, он говорит мне, что суп не является правильной командой AttributeError: 'Response' object has no attribute 'select'

import webbrowser
import selenium
import bs4
import requests

table = []

url = 'http://espn.com/mlb/team/stats/_/name/wsh'
r = requests.get(url)
page = bs4.BeautifulSoup(r.text)
table = soup.select("Table2__th")
print(str(table))

Ответы [ 2 ]

2 голосов
/ 25 апреля 2019

Две проблемы здесь:

  • вы определили свой суповой объект как page, но затем попытайтесь сослаться на него как soup. Вы должны делать page.select('...')
  • вы пытаетесь выбрать определенный класс в CSS, поэтому ваш выбор должен быть ".Table2__th" (в CSS имени класса предшествует точка). См. https://facelessuser.github.io/soupsieve/ для получения дополнительной информации о селекторах CSS.

Вот рабочая версия вашего кода:

import bs4
import requests

table = []
url = 'http://espn.com/mlb/team/stats/_/name/wsh'
r = requests.get(url)
page = bs4.BeautifulSoup(r.text)
table = page.select(".Table2__th")
print(str(table))
1 голос
/ 25 апреля 2019

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

Лучше было бы взять тег из скрипта, тогда вы получите всю актуальную статистику.Ниже я беру эту информацию и помещаю ее в аккуратный фрейм данных для просмотра.

import bs4
import requests
import re
import json
import pandas as pd

url = 'http://espn.com/mlb/team/stats/_/name/wsh'
r = requests.get(url)
page = bs4.BeautifulSoup(r.text, 'lxml')
r = re.compile(r'playerStats":(.*),"teamLeaders"' , re.DOTALL)
data = page.find('script', text=r).text
script = r.findall(data)[0]    
players_info = json.loads(script)
player_batting_stats = players_info[0]
expanded_player_batting_stats = players_info[1]

table1 = []
table2 = []
headers = ['Name', 'GP', 'AB', 'R', 'H', '2B', '3B', 'HR', 'RBI', 'TB', 'BB', 'K', 'SB', 'BA', 'OBP', 'SLG', 'OPS', 'WAR']

for player in player_batting_stats:
    name = player['athlete']['name']
    row = [stat['value'] for stat in player['statGroups']['stats']]
    row.insert(0, name)
    table1.append(row)

df1 = pd.DataFrame(table1, columns = headers)
print(df1.head())

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