2016年2月8日 星期一

Python筆記:Web crawler practice

最近練習了在Python3中如何使用爬蟲來抓取網頁的資料.
聽別人說爬蟲爬了半天終於找到時間可以做個簡單的練習. 並做了POST/GET的練習.

Urllib

一般網頁的原理如下圖所示, 當有使用者發出請求時, Server會響應請求並作出回應。

我們就是利用Python來模擬Client端發送請求給Server,然後將得到的html文件進行解析就能得到你想要的內容了.

enter image description here

第一步透過Chrome來觀察目標網頁是走POST 或是 GET

enter image description here

第二步

確認From data

enter image description here

第三步

透過Urllib這個library來模擬request.

urlopen方法是用來打開一個網頁的(其實是發送一個請求), 他也支援多個參數.
urllib.request.Request功能為封裝一個請求。你可以給該請求添加提交的數據、頭(header)和指定提交方法等。這在登錄某些網站時是必須的。

urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None) 

header則是請求信息的頭。有點像文章的標題,服務器一看頭就知道你的身份和目的。瀏覽器有時會以header中的User-Agent一項來判斷是不是爬​​蟲.

urllib.parse.urlencode主要將data轉換成url所接受的格式

ex. 下圖為抓取高鐵網站的範例

import urllib.request

url = "http://www.thsrc.com.tw/tw/TimeTable/SearchResult"
request = urllib.request.Request(url)
request.add_header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36")

form_data = {
    "StartStation": "977abb69-413a-4ccf-a109-0272c24fd490",
    "EndStation": "f2519629-5973-4d08-913b-479cce78a356",
    "SearchDate": "2016/02/05",
    "SearchTime": "17:00",
    "SearchWay":"DepartureInMandarin",
    "RestTime":"",
    "EarlyOrLater":""
}
form_data = urllib.parse.urlencode(form_data)
form_data = form_data.encode('utf-8')
response = urllib.request.urlopen(request,data=form_data)

在urllib.request.urlopen中, 如果沒有傳送data的話, 就會被默認是使用GET的方式傳送資料.

這裡的重點就是: url = url + "?" + form_data

url = "http://www.showtimes.com.tw/timetable.asp"
form_data = {
    'date':'2016-02-04',
    'sid':'8'
}
form_data = urllib.parse.urlencode(form_data)

url = url + "?" + form_data
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)

分析HTML

得到網頁資訊之後接下來就是分析了, 以下我會利用beautifulSoup來做介紹.

BeautifulSoup

功能強大的HTML Parser. Beautiful Soup將復雜HTML文檔轉換成一個複雜的樹形結構,每個節點都是Python對象,所有對象可以歸納為4種:
1. Tag
簡單來說title a 等等 HTML 標籤加上里麵包括的內容就是 Tag.

<title>The Dormouse's story</title>

Tag,它有兩個重要的屬性,是 name 和 attrs

print soup.p.attrs
#{'class': ['title'], 'name': 'dromouse'}
  1. NavigableString
    用 .string 即可獲得標籤內的資料.

  2. BeautifulSoup

  3. Comment

安裝

$ pip install beautifulsoup4

使用

from bs4 import BeautifulSoup

soup = BeautifulSoup(response, 'html.parser')

for time in soup.find_all('table', attrs={'class':"touch_table"}):
    print(time.text)

參考:
1. http://www.showtimes.com.tw/timetable.asp
2. http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#find-all
3. https://docs.python.org/3/library/urllib.html
4. http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#find-all
5. http://cuiqingcai.com/1319.html

沒有留言:

張貼留言