【问题标题】:Web Scraping - Get the 'blahblah' out from <td foo=blahblah>TEXT</td> using bs4?Web Scraping - 使用 bs4 从 <td foo=blahblah>TEXT</td> 中获取“blahblah”?
【发布时间】:2017-09-20 04:27:59
【问题描述】:

我正在尝试从 ESPN 抓取一些日程表:http://www.espn.com/nba/schedule/_/date/20171001

import requests
import bs4

response = requests.get('http://www.espn.com/nba/schedule/_/date/20171001')
soup = bs4.BeautifulSoup(response.text, 'lxml')
print soup.prettify()

table = soup.find_all('table')

data = []
for i in table:
    rows = i.find_all('tr')
    for row in rows:
        cols = row.find_all('td')
        cols = [col.text.strip() for col in cols]
        data.append([col for col in cols if col])

我的代码工作正常,只是输出缺少日期信息:

[
    "Phoenix PHX", 
    "Utah UTAH", 
    "394 tickets available from $6"
], 
[], 
[
    "Miami MIA", 
    "Orlando ORL", 
    "1,582 tickets available from $12"
]

经过一番调查,我意识到日期和时间信息包含在标签中,如下所示:

<td data-behavior="date_time" data-date="2017-10-07T23:00Z"><a data-dateformat="time1" href="/nba/game?gameId=400978807" name="&amp;lpos=nba:schedule:time"></a></td>

我也时常在其他网站上看到这一点,但从未真正理解他们为什么这样做。如何在打开的标签中提取文本以在输出中获取“2017-10-07T23:00Z”?

【问题讨论】:

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


    【解决方案1】:

    attrs 属性包含一个属性字典,您可以利用它来获取值,我添加了一个长度检查,因为存在一些空行。

    你可以尝试修改for循环如下:

    for i in table:
        rows = i.find_all('tr')
        for row in rows:
            cols = row.find_all('td')
            date_data = None
            if len(cols) > 2:
                date_data = cols[2].attrs['data-date']
            cols = [col.text.strip() for col in cols]
            dat = [col for col in cols if col]
            if date_data:
                dat.append(date_data)
            data.append(dat)
    

    PS:上面的sn-p可以优化:-)

    【讨论】:

      【解决方案2】:

      该表中的一些td 标记包含attributes。您可以通过调用attrs() 来访问td 的属性,这会返回dict

      >>> td = soup.select('tr')[1].select('td')[2]
      >>> td
      <td data-behavior="date_time" data-date="2017-10-01T22:00Z"><a data-dateformat="time1" href="/nba/game?gameId=400978817" name="&amp;lpos=nba:schedule:time"></a></td>
      >>> td.attrs
      {'data-date': '2017-10-01T22:00Z', 'data-behavior': 'date_time'}
      >>> td.attrs['data-date']
      '2017-10-01T22:00Z'
      

      为此,您可以创建一个函数,如果该属性存在则返回日期,或者只返回 td 的文本:

      import requests
      import bs4
      
      def date_or_text(td):
          if 'data-date' in td.attrs:
              return td.attrs['data-date']
          return td.text
      
      def extract_game_information(tr):
          tds_with_blanks = (date_or_text(td) for td in tr.select('td'))
          return [data for data in tds_with_blanks if data]
      
      response = requests.get('http://www.espn.com/nba/schedule/_/date/20171001')
      soup = bs4.BeautifulSoup(response.text, 'lxml')
      
      data = [extract_game_information(tr) for tr in soup.select('tr')]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-28
        • 2015-08-16
        • 1970-01-01
        • 2021-12-18
        相关资源
        最近更新 更多