我尝试使用beautifulsoup从https://www.zacks.com/stock/research/MMM/earnings-announcements下载收入公告数据。当我查看表格时,我感兴趣的表格(earnings_announcements_earnings_table)仅显示"正在加载数据..."。但是,如果我打印汤的全部内容,我确实看到了我要找的信息。我可以将这些数据只是一个"脚本"元素,但包含许多其他不需要的信息。如何选择和解析我正在寻找的特定数据,这是" earnings_announcements_earnings_table"的内容。表,看起来像这样:
" var obj = { " earnings_announcements_earnings_table" : [[" 10/25/2016"," 9/2016"," $ 2.14"," - ",&#34 ; - ","开放之前" ],..."
这是我到目前为止所做的:
from urllib import request
from urllib import error
from bs4 import BeautifulSoup
def download_parse_earnings(symbol):
request_string = "https://www.zacks.com/stock/research/%s/earnings-announcements" % symbol
print(request_string)
try:
web = request.urlopen(request_string)
except error.HTTPError:
return
soup = BeautifulSoup(web.read(), 'lxml')
data = soup.find_all("script")[28].string
print(data)
答案 0 :(得分:1)
一种方法是启动Selenium并使用其Javascript引擎。这并不是很简单,我在这里提供了一个完全黑客的替代解决方案,但它应该适用于您感兴趣的页面。
假设页面是自动生成的,我们观察到您想要的数据(从您的程序继续):
import json
earnings = json.loads(data.split('var obj =')[1].splitlines()[2])
这是利用Javascript对象是JSON的事实,因此我们直接从源代码中读取。结果是像这样的列表列表:
[['10/25/2016', '9/2016', '.14', '--', '--', 'Before Open'],
['7/26/2016',
'6/2016',
'.08',
'.08',
'<div class=right pos_na showinline>0.00 (0.00%)</div>',
'Before Open'],
['4/26/2016',
'3/2016',
'.92',
'.05',
'<div class=right pos positive pos_icon showinline up>0.13 (6.77%)</div>',
'Before Open'],
['1/26/2016',
'12/2015',
'.62',
'.80',
'<div class=right pos positive pos_icon showinline up>0.18 (11.11%)</div>',
'Before Open'],
['10/22/2015',
'9/2015',
'.01',
'.05',
'<div class=right pos positive pos_icon showinline up>0.04 (1.99%)</div>',
'Before Open'],
...
]
第一个元素对应于表的第一行,即标题。你现在必须清理数据。
答案 1 :(得分:0)
不使用Selenium,但仍然使用json,如第一个答案,你可以用BS挖掘你需要的内容。
>>> from bs4 import BeautifulSoup
>>> from urllib import request
>>> URL='https://www.zacks.com/stock/research/MMM/earnings-announcements'
>>> HTML=request.urlopen(URL).read()
>>> soup=BeautifulSoup(HTML)
>>> import json
>>> scripts=soup.findAll('script')
>>> len(scripts)
36
>>> for script in scripts:
... if script.has_attr('type') and script.attrs['type']=='text/javascript' and script.text.strip().startswith('$(document).ready(function()'):
... break
有了这个,javascript就变成了script.text。你仍然需要做一些温和聪明的事情来提取Rubik's回答中显示的行。没什么不可能的。