BeautifulSoup解析表格数据,不会立即加载

时间:2016-10-17 14:59:41

标签: python beautifulsoup

我尝试使用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)

2 个答案:

答案 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回答中显示的行。没什么不可能的。