從0到1的網頁爬蟲 - 04

Pyladies Taiwan

Speaker : Mars

2017/01

Roadmap

  • json 與 xml 的處理
  • 編碼轉換

json 與 xml 的處理

- 以Google Maps API 為例

建立 Google API 金鑰

API 管理員 > 憑證 > 建立專案 > 建立憑證 > API 金鑰 > 複製金鑰> 關閉

啟用 Google 各服務 API

資料庫 > Google Maps API > 更多 > Google Places API Web Service > 啟用

json 解析

  • json.loads(字串):json格式字串 -> python字典型態
  • json.dumps(字典):python字典型態 -> json格式字串

輔助工具:Json Parser Online

In [1]:
import requests
import json
rep = requests.get("https://maps.googleapis.com/maps/api/place/autocomplete/json?input=狄卡科技&key=你的金鑰")
html = rep.text
json_data = json.loads(html)
print (json_data['predictions'][0]['description'])
台灣台北市大安區光復南路狄卡科技股份有限公司

xml 解析

  • 使用 lxml 的 etree.fromstring(xml)
  • vs. html 是使用 etree.HTML(html)

! 注意

etree.fromstring(xml)xml是要為bytes型別

In [2]:
import requests
from lxml import etree
rep = requests.get("https://maps.googleapis.com/maps/api/place/autocomplete/xml?input=狄卡科技&key=你的金鑰")
xml = rep.content # !注意 要為 bytes型別
page = etree.fromstring(xml)
print (page.xpath("//prediction/description/text()")[0])
台灣台北市大安區光復南路狄卡科技股份有限公司

編碼轉換

字串str型別

  • Python 2.x : 字串str型別為bytes
  • Python 3.x : 字串str型別為unicode

bytes 與 unicode 轉換

  • unicode = bytes.decode('編碼格式')
  • bytes = unicode.encode('編碼格式')

! 常見實戰狀況

遇到編碼比較複雜,常無法轉成功時,可以加上參數 errors='ignore'
unicode = bytes.decode('編碼格式',errors='ignore')
bytes = unicode.encode('編碼格式',errors='ignore')

In [3]:
my_str = "你好"
print (type(my_str))
print (my_str[0])

my_str_b = my_str.encode('utf8')
print (type(my_str_b))
print (my_str_b[0])
<class 'str'>
你
<class 'bytes'>
228

常見的字串編碼轉換應用

  • 檔案讀寫字串:str型別
    • open(filename,'w')
    • open(filename,'r')
  • etree.fromstring(xml):bytes型別

requests 的編碼

rep = requests.get(url)

  • rep.content : bytes 型別
  • rep.text : unicode 型別
    • 是由 requests 以 rep.encoding 自動轉換的!
    • rep.encoding 是以 Reponse Headers 的 Content-Type 決定!
In [4]:
import requests
rep = requests.get("http://axe-level-1.herokuapp.com/")
print (rep.encoding)
ISO-8859-1

網頁正確的編碼格式

原始碼中的

  • <meta content='編碼格式' http-equiv='Content-Type'/>
  • <meta charset='編碼格式'>

! 常見實戰狀況

  • 大小寫-混雜
  • 順序不一
  • 根本沒有寫0rz