理解BeautifulSoup过滤时遇到问题

时间:2015-11-26 18:09:45

标签: python html beautifulsoup

有人可以解释过滤如何与Beautiful Soup一起使用。我有以下HTML我试图过滤特定数据但我似乎无法访问它。我已经尝试了各种方法,从收集所有class=g到只抓取特定div中感兴趣的项目,但我得到无返回或没有打印。

每个网页都有一个<div class="srg"> div,其中包含多个<div class="g"> div,我想要使用的数据是带有<div class="g">的数据。每个都有 多个div,但我只对<cite><span class="st">数据感兴趣。我很难理解过滤是如何工作的,任何帮助都会受到赞赏。

我试图踩过div并抓住相关领域:

 soup = BeautifulSoup(response.text)   

 main = soup.find('div', {'class': 'srg'})
 result = main.find('div', {'class': 'g'})
 data = result.find('div', {'class': 's'})
 data2 = data.find('div')
 for item in data2:
     site = item.find('cite')
     comment = item.find('span', {'class': 'st'})

 print site
 print comment

我也试图踩到最初的div并找到所有;

 soup = BeautifulSoup(response.text) 

 s = soup.findAll('div', {'class': 's'})

 for result in s:
     site = result.find('cite')
     comment = result.find('span', {'class': 'st'})

 print site
 print comment

测试数据

<div class="srg">
    <div class="g">
    <div class="g">
    <div class="g">
    <div class="g">
        <!--m-->
        <div class="rc" data="30">
            <div class="s">
                <div>
                    <div class="f kv _SWb" style="white-space:nowrap">
                        <cite class="_Rm">http://www.url.com.stuff/here</cite>
                    <span class="st">http://www.url.com. Some info on url etc etc
                    </span>
                </div>
            </div>
        </div>
        <!--n-->
    </div>
    <div class="g">
    <div class="g">
    <div class="g">
</div>

更新

在Alecxe的解决方案之后,我又采取了另一种措施,但仍然没有得到任何印刷品。所以我决定再看看soup,看起来不一样。我之前正在查看response.text中的requests。我只能认为BeautifulSoup修改了response.text或者我不知何故第一次完全错误的样本(不确定如何)。然而,以下是基于我从soup打印件中看到的新样本。在我的下面尝试获取我追随的元素数据。

<li class="g">
<h3 class="r">
    <a href="/url?q=url">context</a>
</h3>
<div class="s">
    <div class="kv" style="margin-bottom:2px">
        <cite>www.url.com/index.html</cite> #Data I am looking to grab
        <div class="_nBb">‎
            <div style="display:inline"snipped">
                <span class="_O0"></span>
            </div>
            <div style="display:none" class="am-dropdown-menu" role="menu" tabindex="-1">
                <ul>
                    <li class="_Ykb">
                        <a class="_Zkb" href="/url?/search">Cached</a>
                    </li>
                </ul>
            </div>
        </div>
    </div>
    <span class="st">Details about URI </span> #Data I am looking to grab

更新尝试

到目前为止,我尝试采用Alecxe的方法没有成功,我是否正在走这条路?

soup = BeautifulSoup(response.text)

for cite in soup.select("li.g div.s div.kv cite"):
    span = cite.find_next_sibling("span", class_="st")

    print(cite.get_text(strip=True))
    print(span.get_text(strip=True))

2 个答案:

答案 0 :(得分:2)

首先获取类名为div的{​​{1}},然后在srg内找到类名为s的所有div,并获取srg和{{的文本1}}。以下是我的工作代码 -

site

输出 -

comment

编辑 -

为什么您的代码不起作用

试一试 -

您正在使用from bs4 import BeautifulSoup html = """<div class="srg"> <div class="g"> <div class="g"> <div class="g"> <div class="g"> <!--m--> <div class="rc" data="30"> <div class="s"> <div> <div class="f kv _SWb" style="white-space:nowrap"> <cite class="_Rm">http://www.url.com.stuff/here</cite> <span class="st">http://www.url.com. Some info on url etc etc </span> </div> </div> </div> <!--n--> </div> <div class="g"> <div class="g"> <div class="g"> </div>""" soup = BeautifulSoup(html , 'html.parser') labels = soup.find('div',{"class":"srg"}) spans = labels.findAll('div', {"class": 'g'}) sites = [] comments = [] for data in spans: site = data.find('cite',{'class':'_Rm'}) comment = data.find('span',{'class':'st'}) if site:#Check if site in not None if site.text.strip() not in sites: sites.append(site.text.strip()) else: pass if comment:#Check if comment in not None if comment.text.strip() not in comments: comments.append(comment.text.strip()) else: pass print sites print comments 它会抓取单个和第一个遇到的元素,但第一个元素没有[u'http://www.url.com.stuff/here'] [u'http://www.url.com. Some info on url etc etc'] 且类名为result = main.find('div', {'class': 'g'})。因此,此代码的下一部分将无效。

试试二 -

您正在打印不在打印范围内的divs。所以尝试在里面打印for循环。

site

答案 1 :(得分:1)

您不必手动处理层次结构 - 让BeautifulSoup担心。你的第二种方法接近于你应该尝试做的事情,但是一旦你得到div class="s"cite没有BeautifulSoup元素,它就会失败。

相反,您需要让cite知道您对包含特定元素的特定元素感兴趣。让div元素位于class="g"元素内的div元素位于class="srg"元素内div.srg div.g cite - for cite in soup.select("div.srg div.g cite"): span = cite.find_next_sibling("span", class_="st") print(cite.get_text(strip=True)) print(span.get_text(strip=True)) {{ 3}}会找到我们正在询问的内容:

cite

然后,一旦span被找到,我们就会“横行”#34;并使用class="st"抓取下一个http://www.url.com.stuff/here http://www.url.com. Some info on url etc etc 兄弟元素。虽然,是的,我们假设它存在。

对于提供的样本数据,它会打印:

for cite in soup.select("li.g div.s div.kv cite"):
    span = cite.find_next("span", class_="st")

    print(cite.get_text(strip=True))
    print(span.get_text(strip=True))

更新的输入数据的更新代码:

BeautifulSoup

另外,请确保您使用的是第4个pip install --upgrade beautifulsoup4 版本:

from bs4 import BeautifulSoup

导入声明应为:

awk 'NR==1 || NR==3 {print $0}' output.txt