1. 程式人生 > >python 解析html網址內容

python 解析html網址內容

首先,找到你希望獲取資料的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]