如何在BeautifulSoup4中正确使用选择功能?

时间:2019-04-24 21:25:25

标签: python python-3.x web-scraping beautifulsoup

我正在使用BS4作为我的网络抓取简介来编写我的第一个脚本,但是遇到了麻烦。我将跟他一起使用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 个答案:

答案 0 :(得分:2)

这里有两个问题:

  • 您已将汤对象定义为page,然后尝试将其引用为soup。您应该做page.select('...')
  • 您正在尝试在CSS中选择特定的类,因此您的选择应为".Table2__th"(在CSS中,类名前面带有句点)。有关CSS选择器的更多信息,请参见https://facelessuser.github.io/soupsieve/

这是您代码的有效版本:

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 :(得分:1)

我假设您实际上想要表中的数据?该内容是使用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