【问题标题】:Web Scraping child classes or cleaning up html returnedWeb 抓取子类或清理返回的 html
【发布时间】:2021-06-02 02:21:37
【问题描述】:

我正在尝试从 rotowire 获取 MLB 比赛赔率和总得分。我尝试了两种方法,虽然我可以接近,但不能完全弄清楚我接下来需要做什么。第一种方法看起来我需要刮掉子类“复合隐藏”。我采取的另一种方法返回了一堆新行和其他额外字符,尽管我试图只获取文本并将它们删除。

from bs4 import BeautifulSoup
import requests

url = 'https://www.rotowire.com/baseball/daily-lineups.php'

r = requests.get(url)
soup = BeautifulSoup(r.text, "html.parser")

##First approach
oddsData = soup.find_all('div', {'class': 'lineup__odds-item'})
print(oddsData)

#Second approach
gameOdds = [g.text.strip() for g in oddsData]
print(gameOdds)
 

第一种方法返回以下内容。我只想要 CLE -165 和 7.0 运行。

[<div class="lineup__odds-item">
<b>LINE</b> 

                                                <span class="composite hide">CLE -165</span>
<span class="fanduel">–</span>
<span class="draftkings hide">–</span>
<span class="betmgm hide">–</span>
<span class="pointsbet hide">–</span>
</div>, <div class="lineup__odds-item">
<b>O/U</b> 

                                                <span class="composite hide">7.0 Runs</span>
<span class="fanduel">–</span>
<span class="draftkings hide">–</span>
<span class="betmgm hide">–</span>
<span class="pointsbet hide">–</span>

第二种方法返回以下内容。

['LINE\xa0\r\n                                                CLE -165\n–\n–\n–\n–', 'O/U\xa0\r\n                                                7.0 Runs\n–\n–\n–\n–'

【问题讨论】:

  • 我可以看到输出吗?比如举个例子说明缺少什么以及你想删除什么
  • @AstronomyComputing 我已经编辑了问题以显示返回的内容。
  • 您想在该 div 标签中查找什么文本或所有这些文本?

标签: python html web-scraping python-requests


【解决方案1】:

要获取LINEO/U 内容,您可以使用以下示例:

import requests
from bs4 import BeautifulSoup

url = "https://www.rotowire.com/baseball/daily-lineups.php"
soup = BeautifulSoup(requests.get(url).content, "html.parser")

for i in soup.select(".lineup__bottom"):
    visit = i.find_previous(class_="lineup__mteam is-visit").get_text(
        strip=True
    )
    home = i.find_previous(class_="lineup__mteam is-home").get_text(strip=True)
    line = i.select_one(
        '.lineup__odds-item b:contains("LINE") ~ span'
    ).text
    ou = i.select_one('.lineup__odds-item b:contains("O/U") ~ span').text

    print(
        "{:<25} {:<25} LINE: {:<10} O/U: {:<10}".format(visit, home, line, ou)
    )

打印:

White Sox(33-22)          Indians(30-24)            LINE: CLE -165   O/U: 7.0 Runs  
Twins(22-32)              Orioles(18-37)            LINE: MIN -170   O/U: 9.0 Runs  
Rays(35-21)               Yankees(30-25)            LINE: TB -135    O/U: 7.5 Runs  
Marlins(24-29)            Blue Jays(28-25)          LINE: TOR -160   O/U: 8.5 Runs  
Phillies(26-29)           Reds(24-29)               LINE: –          O/U: 7.5 Runs  
Nationals(22-29)          Braves(25-27)             LINE: ATL -140   O/U: 8.5 Runs  
Tigers(23-32)             Brewers(29-26)            LINE: MIL -180   O/U: 7.5 Runs  
Padres(34-22)             Cubs(31-23)               LINE: CHC -130   O/U: 8.5 Runs  
Pirates(20-34)            Royals(27-26)             LINE: KC -170    O/U: 8.5 Runs  
Red Sox(32-22)            Astros(30-24)             LINE: HOU -165   O/U: 9.0 Runs  
Rangers(22-34)            Rockies(21-34)            LINE: –          O/U: 9.5 Runs  
Mets(26-21)               Diamondbacks(20-36)       LINE: NYM -120   O/U: 9.0 Runs  
Angels(25-30)             Giants(34-21)             LINE: SF -160    O/U: 7.0 Runs  
Athletics(32-25)          Mariners(28-28)           LINE: OAK -160   O/U: 7.5 Runs  
Cardinals(31-24)          Dodgers(32-23)            LINE: LAD -200   O/U: 8.5 Runs  

【讨论】:

  • 这看起来很接近工作,但是当它刮线时出现以下错误 - NotImplementedError: ':-soup-contains' 伪类此时未实现。
  • 我需要什么版本的美汤?我刚刚升级到 4.9.3 仍然收到错误。我确实切换到包含,但它确实有效。您是否有任何指向此 select_one 和包含的更多信息的链接?我从来没有用过这个,想了解更多。
  • @ShawnSchreier 取决于 soupsieve 模块 bs4 正在使用。以下是有关伪类的信息:facelessuser.github.io/soupsieve/selectors/pseudo-classes/…
  • 感谢您的帮助。运气好的话,你也能帮我弄到雨和天气。我已经尝试按照您的方法返回属性错误 - rain = i.select_one('.lineup__weather-text b:contains("Rain") ~ span').text 我也尝试过 forecast = i.select_one(' .lineup__weather-text').text.strip() 这让我很接近,但仍然包括 \r\n 和每个元素之间的一堆空格。如果您愿意,我可以发布一个新问题。
  • @ShawnSchreier 不要弄乱我建议打开一个新问题的评论部分。我会试着看看。
【解决方案2】:

据我了解您想要清理数据的问题遵循以下一般方法:

def clean_page(html, pretty_print=False):
    """
    >>> junk = "some random HTML<P> for you to try to parse</p>"
    >>> clean_page(junk)
    '<div><p>some random HTML</p><p> for you to try to parse</p></div>'
    >>> print clean_page(junk, pretty_print=True)
    <div>
    <p>some random HTML</p>
    <p> for you to try to parse</p>
    </div>
    """
    from lxml.html import fromstring
    from lxml.html import tostring
    return tostring(fromstring(html), pretty_print=pretty_print)

如果需要,这里有一篇详细的文章: https://schoolofdata.org/handbook/recipes/cleaning-data-scraped-from-the-web/?__cf_chl_managed_tk

如果这就是你要找的,请告诉我!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-29
    • 2021-05-13
    • 2020-12-03
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    相关资源
    最近更新 更多