python 解析html網址內容
阿新 • • 發佈:2019-06-27
首先,找到你希望獲取資料的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]: <Element html at 0xcc7ed68>
通過這個物件,你可以獲取特定型別的所有HTML標籤(tag),例如包含所需資料的table標籤。使用文件根節點findall方法以及一個XPath(對文件的“查詢“的一種表示手段):
links = doc.findall('.//a')
links[15:20]
Out[157]:
[<Element a at 0xcc52a48>,
<Element a at 0xcc52a98>,
<Element a at 0xcc52ae8>,
<Element a at 0xcc52b38>,
<Element a at 0xcc52b88>]
蛋這些事表示HTML元素的物件。要得到URL和連結文字,你必須使用個物件的get方法(針對URL)和text_context方法(針對現實文字):
lnk = links[28] lnk Out[159]: <Element a at 0xcc52e58> 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]: <Element table at 0xdbd6f98>
tables[1]
Out[171]: <Element table at 0xdbe1408>
每個表格都有一個標題行,然後才是資料行:
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]