使用漂亮的汤解析嵌套的跨度标签



我正在尝试从以下网站提取公司信息:

http://www.theglobeandmail.com/globe-investor/markets/stocks/summary/?q=T-T

我从那里看到页面源代码中有嵌套的 span 语句,例如:

<li class="clearfix">
<span class="label">Low</span>
<span class="giw-a-t-sc-data">36.39</span>
</li>
<li class="clearfix">
<span class="label">Bid<span class="giw-a-t-sc-bidSize smallsize">x0</span></span>
<span class="giw-a-t-sc-data">36.88</span>
</li>

我编写的代码可以毫无问题地抓取(最低价,36.69)。 我花了几个小时阅读这个论坛和其他试图让 bs4 也爆发的人(Bid,36.88)。 问题是,由于嵌套的跨度标签,Bid 显示为"无"。

我是一个老的"c"程序员(GNU Cygwin),这个python,Beautifulsoup的东西对我来说是新的。 不过我喜欢它,有趣且省时的脚本潜力巨大。

任何人都可以帮助解决这个问题,我希望我已经提出了足够好。请保持简单,因为我绝对是新手。提前谢谢。

如果你想

从网站获取数据,我推荐PyQuery(https://pypi.python.org/pypi/pyquery)。就像BeautifulSoup一样,它使用lxml进行快速XML/HTML解析,您可以访问HTML元素jQuery类选择器。

import pyquery
root = pyquery.PyQuery("http://www.theglobeandmail.com/globe-investor/markets/stocks/summary/?q=T-T") # you can also pass the HTML-source, that you want to parse
spanlist = root("li.clearfix > span")
for span in spanlist: print span.text

输出:

Open
36.45
Previous Close
36.28
High
37.36
Low
36.39
Bid
36.88

(只是输出的前十行,但我想你明白我的意思:几行,很棒的结果......

与美丽汤几乎相同4

>>> import bs4
>>> text = "<li ..." # HTML-source-code from Question
>>> root = bs4.BeautifulSoup(text)
>>> [ span.text for span in root("li.clearfix > span") ]
[u'Low', u'36.39', u'Bidx0', u'36.88']

现在结构化:

>>> [ ( span.text, span.findNextSibling('span').text) for span in root.select("li.clearfix > span.label") ]
[(u'Low', u'36.39'), (u'Bidx0', u'36.88')]

在单独的列中打印:

>>> for span in root.select("li.clearfix > span.label"):
>>>    print "%st%s" % ( span.text, span.findNextSibling('span').text )
Low 36.39
Bidx0   36.88

所以它的工作方式比我工作的方式要好得多,但仍然存在一些问题。 我正在发布完整的脚本,以便您可以看到我在做什么。 我会花一些时间和精力来调查这些问题,但无论如何,这将帮助我更好地学习 python 和 beautifulsoup。

"""
This program imports a list of stock ticker symbols from "ca_stocks.txt"
It then goes to the Globe website and gets current company stock data
It then writes this data to a file to a CSV file in the form
index, ticker, date&time, dimension, measure
"""
import urllib2
import csv, os
import datetime 
import re #regular expressions library
import bs4
#from bs4 import BeautifulStoneSoup as bss
#from time import gmtime, strftime
#from lxml import etree
import pyquery
#import dataextract as tde
os.chdir('D:\02 - \003 INVESTMENTS\Yahoo Finance Data')

symbolfile = open('ca_stocks2.txt')
symbolslist = symbolfile.read().split('n')

def pairs(l,n):
# l = list
# n = number
    return zip(*[l[i::n] for i in range(n)])
def main():
    i=0
    while i<len(symbolslist):
        print symbolslist[i]
        url = urllib2.urlopen("http://www.theglobeandmail.com/globe-investor/markets/stocks/summary/?q=" +symbolslist[i])
        root = bs4.BeautifulSoup(url)
        [span.text for span in root("li.clearfix > span")]
        [(span.text, span.findNextSibling('span').text) for span in root.select("li.clearfix > span.label")]
        dims = [[]] *40
        mess = [[]] *40
        j=0
        for span in root.select("li.clearfix > span.label"):
            #print "%st%s" % ( span.text, span.findNextSibling('span').text)
            dims[j] = span.text
            mess[j] = span.findNextSibling('span').text
            j+=1
        nowtime = datetime.datetime.now().isoformat()
        with open('globecdndata.csv','ab') as f:
            fw = csv.writer(f, dialect='excel')
            for s in range(0,37):
                csvRow = s, symbolslist[i], nowtime, dims[s], mess[s]
                print csvRow
                fw.writerow(csvRow)    
        f.close()
        i+=1
if __name__ == "__main__":
    main()        

我知道这是丑陋的代码,但是嘿,我正在学习。 CSV 的输出现在如下所示:

(4, 'T-T', '

2013-11-09T19:32:32.416000', u'Bidx0', u'36.88')

(5, 'T-T', '

2013-11-09T19:32:32.416000', u'Askx0', u'36.93')

(6, 'T-T', '

2013-11-09T19:32:32.416000', u'52 周高点05/22', u'37.94')

日期"05/22"每次价格突破新高或低点时都会改变。 这对于维度(字段)的名称并不理想。

(7, 'T-T', '

2013-11-09T19:32:32.416000', u'52周低点06/27', u'29.52')

(35, 'T-T', '

2013-11-09T19:32:32.416000', u'Top 1000 排名:', u'利润: 28收入: 34资产: 36')

出于某种原因,它将这些维度(字段)和度量值(数据)混为一谈。 嗯。。。

这是一些问题的列表。 但是,就像我说的,我现在应该能够弄清楚这一点。 学到了很多东西,谢谢。 有一个知道自己在做什么的人,提供一些意见真是太棒了。

最新更新