【问题标题】:BeautifulSoup and Regular Expressions - extracting text from tagsBeautifulSoup 和正则表达式 - 从标签中提取文本
【发布时间】:2013-01-24 17:54:23
【问题描述】:

我正在用 Python 编写一个小的文本抓取脚本。这是我的第一个更大的项目,所以我遇到了一些问题。我正在使用 urllib2 和 BeautifulSoup。我想从一个播放列表中抓取歌曲名称。我可以获得一首歌曲名称或所有歌曲名称+我不需要的其他字符串。我无法仅获得所有歌曲名称。我的代码可以获取所有歌曲名称 + 其他不需要的字符串:

import urllib2
from bs4 import BeautifulSoup
import re

response = urllib2.urlopen('http://guardsmanbob.com/media/playlist.php?char=a').read()
soup = BeautifulSoup(response)

for tr in soup.findAll('tr')[0]:
    for td in soup.findAll('a'):
        print td.contents[0]

还有给我一首歌的代码:

print soup.findAll('tr')[1].findAll('a')[0].contents[0]

它实际上不是一个循环,所以我只能得到一个,但如果我尝试让它循环,我会得到大约 10 个相同的歌曲名称。该代码:

for tr in soup.findAll('tr')[1]:
    for td in soup.findAll('td')[0]:
        print td.contents[0]

我现在卡了一天,我无法让它工作。我不明白这些东西是如何工作的。

【问题讨论】:

    标签: python web-scraping beautifulsoup urllib2


    【解决方案1】:
    for tr in soup.findAll('tr'):  # 1
        if not tr.find('td'): continue  # 2
        for td in tr.find('td').findAll('a'):  # 3
            print td.contents[0]
    
    1. 您想遍历所有 tr,因此是 findAll('tr') 而不是 findAll('tr') [0]
    2. 有些行不包含td,所以我们需要跳过它们以避免AttributeError(尝试删除此行)
    3. 与 1 一样,您希望第一个 td 中的所有 a,但也 “for td in tr.find”,而不是“for td in soup.find”,因为您想查看 tr 而不是整个文档 (soup)。

    【讨论】:

    • 在没有td 的情况下跳过行的想法非常好。如果该页面也使用tbody 标签会更容易..
    【解决方案2】:

    您应该在搜索中更具体一点,然后遍历表格行;通过 css 类获取特定表,循环遍历除第一个使用切片的 tr 元素,从第一个 td 获取 all 文本:

    table = soup.find('table', class_='data-table')
    for row in table.find_all('tr')[1:]:
        print ''.join(row.find('td').stripped_strings)
    

    除了切掉第一行之外,您还可以通过测试跳过thead

    for row in table.find_all('tr'):
        if row.parent.name == 'thead':
            continue
        print ''.join(row.find('td').stripped_strings)
    

    如果页面使用了正确的<tbody> 标签,一切都会更好。 :-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-11
      • 2018-05-08
      • 1970-01-01
      • 2017-02-25
      • 2013-02-08
      • 2011-01-10
      • 1970-01-01
      相关资源
      最近更新 更多