如何使用Beautiful Soup选择div文本内容?

时间:2013-11-29 21:47:34

标签: html web-scraping beautifulsoup

试图从这样的东西中抓取一些HTML。有时我需要的数据是div [0],有时是div [1]等等。

想象一下每个人需要3-5节课。其中之一就是生物学。他们的成绩单总是按字母顺序排列。我想要每个人的生物学等级。

我已经把所有这些HTML写成了一个文本,现在如何剔除生物学成绩?

<div class = "student">
    <div class = "score">Algebra C-</div>
    <div class = "score">Biology A+</div>
    <div class = "score">Chemistry B</div>
</div>
<div class = "student">
    <div class = "score">Biology B</div>
    <div class = "score">Chemistry A</div>
</div>
<div class = "student">
    <div class = "score">Alchemy D</div>
    <div class = "score">Algebra A</div>
    <div class = "score">Biology B</div>
</div>
<div class = "student">
    <div class = "score">Algebra A</div>
    <div class = "score">Biology B</div>
    <div class = "score">Chemistry C+</div>
</div>
<div class = "student">
    <div class = "score">Alchemy D</div>
    <div class = "score">Algebra A</div>
    <div class = "score">Bangladeshi History C</div>
    <div class = "score">Biology B</div>
</div>

我正在使用漂亮的汤,我想我将不得不找到文本包含“生物学”的div?

这只是为了快速刮,我愿意在Excel或其他东西中进行硬编码和摆弄。是的,这是一个伪劣的网站!是的,他们确实有一个API,我对WDSL一无所知。

简短版本:http://www.legis.ga.gov/Legislation/en-US/Search.aspx,查找每张帐单上的最后一次操作日期,FWIW。这很麻烦,因为如果一个法案在第二个议案中没有赞助者,而不是一个不包含任何内容的div,那么他们根本就没有一个div。所以有时时间轴是div 3,有时是2,等等。

3 个答案:

答案 0 :(得分:8)

(1)仅仅获得生物学等级,它几乎是一个班轮。

import bs4, re
soup = bs4.BeautifulSoup(html)
scores_string = soup.find_all(text=re.compile('Biology')) 
scores = [score_string.split()[-1] for score_string in scores_string]
print scores_string
print scores

输出如下:

[u'Biology A+', u'Biology B', u'Biology B', u'Biology B', u'Biology B']
[u'A+', u'B', u'B', u'B', u'B']

(2)您找到了标签,也许还有其他任务,您需要找到parent

import bs4, re
soup = bs4.BeautifulSoup(html)
scores = soup.find_all(text=re.compile('Biology'))
divs = [score.parent for score in scores]
print divs

输出如下:

[<div class="score">Biology A+</div>, 
<div class="score">Biology B</div>, 
<div class="score">Biology B</div>, 
<div class="score">Biology B</div>, 
<div class="score">Biology B</div>]

* 总之,您可以使用find_siblings / parent / ...等来移动HTML树。*

有关如何navigate the tree的更多信息。 祝你工作顺利。

答案 1 :(得分:3)

您可以提取它们,搜索<div>作为score属性值的任何class元素,并使用正则表达式提取其生物学得分:

from bs4 import BeautifulSoup 
import sys
import re

soup = BeautifulSoup(open(sys.argv[1], 'r'), 'html')

for div in soup.find_all('div', attrs={'class': 'score'}):
    t = re.search(r'Biology\s+(\S+)', div.string)
    if t: print(t.group(1))

像以下一样运行:

python3 script.py htmlfile

产量:

A+
B
B
B
B

答案 2 :(得分:1)

另一种方法(使用CSS选择器)是:

divs = soup.select('div:contains("Biology")')

编辑:

BeautifulSoup4 4.7.0 + (SoupSieve)是必需的