Python 使用beautifulsoup解析嵌套的span标记
我正试图从以下网站获取公司信息: 我从页面源代码中看到有嵌套的span语句,如:Python 使用beautifulsoup解析嵌套的span标记,python,beautifulsoup,Python,Beautifulsoup,我正试图从以下网站获取公司信息: 我从页面源代码中看到有嵌套的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 clas
<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.39
Bidx0
36.88
我写的代码将毫无问题地抓取(低,36.69)。我花了几个小时阅读这个论坛和其他试图让bs4也爆发(出价,36.88)。问题是,由于嵌套的span标记,Bid显示为“无”
我是一个老的“c”程序员(GNU Cygwin),这个python、Beautifulsoup的东西对我来说是新的。尽管如此,我还是很喜欢它,因为它具有有趣和省时的潜力
谁能帮我回答这个问题,我希望我已经提出得足够好了。
请保持简单,因为我绝对是个新手。
提前感谢。如果您想从网站获取数据,我建议您使用PyQuery()。正如BeautifulSoup一样,它使用lxml进行快速XML/HTML解析,您可以像选择器一样访问jQuery中的HTML元素
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
(只是输出的前十行,但我想你明白我的意思:几行,很好的结果…)
与BeautifulSoup4几乎相同
分列打印:
>>> for span in root.select("li.clearfix > span.label"):
>>> print "%s\t%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 "%s\t%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()
“”“
该程序从“ca_stocks.txt”导入股票代码列表
然后它进入全球网站,获取当前公司股票数据
然后,它将该数据写入一个文件,并以
索引、股票代码、日期和时间、维度、度量
"""
导入urllib2
导入csv,操作系统
导入日期时间
导入正则表达式库
进口bs4
#从bs4导入BeautifulstoneSoop作为bss
#从时间导入gmtime,strftime
#从lxml导入etree
导入pyquery
#将数据提取作为tde导入
os.chdir('D:\\02-\\003投资\\雅虎财务数据')
symbolfile=open('ca_stocks2.txt'))
symbolslist=symbolfile.read().split('\n')
def对(l,n):
#l=列表
#n=数量
返回zip(*[l[i::n]表示范围内的i(n)])
def main():
i=0
iAside:我很确定有一些API可以用来获取股票价格。欢迎来到SO!请张贴代码,你已经尝试。嗨,我不只是寻找价格,这将是很容易的。我正在查看一些已发布的比率,自己构建该工具将允许灵活地做其他事情。好建议。嗨,谢谢你的帖子。我已经下载了pyquery,它可以正确导入。我要试一试。我确实对你的建议有所保留,只是因为每个人似乎都坚持他们所知道的。我假设这些结果也可以在beautifulsoup、beautifulstonesoup和lxml中生成。我真的需要学习一种语言,任何一种语言,我想关于我应该学习什么,会有一些建议。pyquery只是python的另一个解析器插件吗?我仍然很想看看你们在bs4中是如何做到这一点的。我必须承认,BeautifulSoup在我看来更像蟒蛇。我检查BeautifulSoup4中是否有类似的方法来实现类似的结果。我的第一个猜测是PyQuery,因为它使用CSS选择器和多年来开发的选择器,所以我认为它是一个非常强大的工具。是的:PyQuery只是另一个解析器模块(或者我可以说是我所理解的lxml解析器模块的另一个API)。您好,很抱歉打扰您,但是您能否将代码包含在单独的“维度”和“度量”列中。对不起,我真的不知道我在做什么。我花了很长时间才弄明白我在C语言中能做的最基本的事情。好吧,我想就是这样:使用BeautifulSoup4,以元组结构。。。我是否应该重新安排我的答案,让BS4部分在开头,我的PyQuery备选方案在结尾?哇,谢谢,在花了这么多时间挣扎之后,我将从剖析这个问题中学到很多东西。非常感谢你的帮助。你太棒了!
>>> for span in root.select("li.clearfix > span.label"):
>>> print "%s\t%s" % ( span.text, span.findNextSibling('span').text )
Low 36.39
Bidx0 36.88
"""
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 "%s\t%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()