首先,找到你希望获取数据的URL, 利用urllib.request将其打开,然后利用lxml解析得到的数据流:
from lxml.html import parse
from urllib.request import urlopen
parsed = parse(urlopen('http://finance.yahoo.com/q/op?s=AAPL+Options'))
doc = parsed.getroot()
doc
Out[155]:
通过这个对象,你可以获取特定类型的所有HTML标签(tag),例如包含所需数据的table标签。使用文档根节点findall方法以及一个XPath(对文档的“查询“的一种表示手段):
links = doc.findall('.//a')
links[15:20]
Out[157]:
[,
,
,
,
]
蛋这些事表示HTML元素的对象。要得到URL和链接文本,你必须使用个对象的get方法(针对URL)和text_context方法(针对现实文本):
lnk = links[28]
lnk
Out[159]:
lnk.get('href')
Out[160]: '/quote/AAPL190628C00160000?p=AAPL190628C00160000'
lnk.text_content()
Out[161]: 'AAPL190628C00160000'
因此,编写下面这条列表推导式即可获取文档中的全部URL:
urls = [lnk.get('href') for lnk in doc.findall('.//a')]
urls[-10:]
Out[163]:
['/',
'/watchlists',
'/portfolios',
'/screener',
'/calendar',
'/industries',
'/videos/',
'/news/',
'/personal-finance',
'/tech']
现在,从文档中找出正确表格的办法就是反复试验了,有些网站汇给目标表格嘉善给一个id属性。查看页面属性可以看到两个表格(看涨数据和看跌是乬)
tables = doc.findall('.//table')
len(tables)
Out[168]: 2
tables[0]
Out[169]:
tables[1]
Out[171]:
每个表格都有一个标题行,然后才是数据行:
calls = tables[0]
puts = tables[1]
rows = calls.findall('.//tr')
获取标题行和数据行的每个单元格内的文本:
def _unpack(row, kind='td'):
elts = row.findall('.//%s' % kind)
return [val.text_content() for val in elts]
_unpack(rows[0], kind ='th')
Out[178]:
['Contract Name',
'Last Trade Date',
'Strike',
'Last Price',
'Bid',
'Ask',
'Change',
'% Change',
'Volume',
'Open Interest',
'Implied Volatility']
_unpack(rows[1], kind='td')
Out[179]:
['AAPL190628C00130000',
'2019-06-25 3:22PM EDT',
'130.00',
'65.82',
'68.60',
'69.10',
'0.00',
'-',
'15',
'10',
'0.00%']
现在把所有步骤结合祁连,将数据转换为一个DataFrame。由于数值型数据仍然是字符串格式,所以我们希望将部分列转换为浮点数格式。利用Pandas的TextParser类可自动类型转换
from pandas.io.parsers import TextParser
def parse_options_data(table):
rows = table.findall('.//tr')
header = _unpack(rows[0], kind='th')
data = [_unpack(r) for r in rows[1:]]
return TextParser(data, names=header).get_chunk()
call_data = parse_options_data(calls)
put_data = parse_options_data(puts)
call_data[:10]
Out[186]:
Contract Name Last Trade Date ... Open Interest Implied Volatility
0 AAPL190628C00130000 2019-06-25 3:22PM EDT ... 10 0.00%
1 AAPL190628C00131000 2019-06-19 2:02PM EDT ... 32 368.36%
2 AAPL190628C00132000 2019-06-21 3:55PM EDT ... 0 0.00%
3 AAPL190628C00138000 2019-06-19 3:45PM EDT ... 5 327.15%
4 AAPL190628C00140000 2019-06-07 12:37PM EDT ... 5 316.80%
5 AAPL190628C00150000 2019-06-04 10:22AM EDT ... 21 268.85%
6 AAPL190628C00155000 2019-06-07 11:04AM EDT ... 12 244.14%
7 AAPL190628C00157500 2019-06-21 9:40AM EDT ... 5 229.39%
8 AAPL190628C00160000 2019-06-18 11:17AM EDT ... 99 217.48%
9 AAPL190628C00162500 2019-06-20 3:57PM EDT ... 62 0.00%
[10 rows x 11 columns]