Python + selenium:在标题之间提取可变数量的段落

时间:2015-11-26 20:12:43

标签: python html selenium beautifulsoup urllib2

研究员,假设下面的html如何提取属于图块<p>的段落<h3>

<!DOCTYPE html>
    <html>
    <body>
    ...
        <div class="main-div">
            <h3>Title 1</h3>
            <p></p>

            <h3>Title 2</h3>
            <p></p>
            <p></p>
            <p></p>

            <h3>Title 3</h3>
            <p></p>
            <p></p>
            ...
        </div>
</body>

正如您所看到的,<h3><p>标记都是<div>代码的子代,但它们没有类或ID ,因此可以识别它们并且说“标题1”有1个段落,标题2有3个段落,标题3有两个段落,依此类推。我看不到将段落与标题联系起来的方法......

我正在尝试使用Python 2.7 + selenium 。但我不确定我是否正在使用合适的工具,也许你可以建议解决方案或任何不同的组合,如Beautifulsoup,urllib2 ......

任何建议/方向都将非常感谢!

更新

在@JustMe指出的出色解决方案后,我想出了下面的解决方案,希望它可以帮助其他人,或者如果有人可以将其改进为pythonic。我来自c / c ++ / java / perl世界所以我总是碰壁:)

import bs4

page = """ 
<!DOCTYPE html>
<html>
<body>
...
    <div class="maincontent-block">
        <h3>Title 1</h3>
        <p>1</p>
        <p>2</p>
        <p>3</p>

        <h3>Title 2</h3>
        <p>2</p>
        <p>3</p>
        <p>4</p>

        <h3>Title 3</h3>
        <p>7</p>
        <p>9</p>
        ...
    </div>
</body>
"""

page = bs4.BeautifulSoup(page, "html.parser")
div = page.find('div', {'class':"maincontent-block"})

mydict = {}

# write to the dictionary
for tag in div.findChildren():
    if (tag.name == "h3"):
        #print(tag.string)
        mydict[tag.string] = None
        nextTags = tag.findAllNext()
        arr = [];
        for nt in nextTags:
            if (nt.name == "p"):
                arr.append(nt.string)
                mydict[tag.string] = arr
            elif (nt.name == "h3"):
                arr = []
                break

# read from dictionary
arrKeys = []
for k in mydict:
    arrKeys.append(k)

arrKeys.sort()
for k in arrKeys:
    print k
    for v in mydict[k]:
        print v

1 个答案:

答案 0 :(得分:0)

使用BeautifulSoup

很容易完成
import bs4

page = """
<!DOCTYPE html>
    <html>
    <body>
    ...
        <div class="main-div">
            <h3>Title 1</h3>
            <p></p>

            <h3>Title 2</h3>
            <p></p>
            <p></p>
            <p></p>

            <h3>Title 3</h3>
            <p></p>
            <p></p>
            ...
        </div>
</body>
"""

page = bs4.BeautifulSoup(page)
h3_tag = page.div.find("h3").string
print(h3_tag)
>>> u'Title 1'

h3_tag.find_next_siblings("p")
>>> [<p></p>, <p></p>, <p></p>, <p></p>, <p></p>, <p></p>]
len(h3_tag.find_next_siblings("p"))/2
>>> 3

好的,既然你想要分开计数的段落,我想出了这个粗糙的东西。

 h_counters = []
 count = -1
 for child in page.div.findChildren():
     if "<h3>" in str(child):
         h_counters.append(count)
         count = 0
     else:
         count += 1
 h_counters.append(count)
 h_counters = h_counters[1:]
 print (h_counters)
 >> [1, 3, 2]