1. 設定目標: 網路上有許多同業公會的網站, 想要從這些網站去抓取會員的名單, 做為日後查詢用
以 台中市旅館商業同業公會 的網站為例子
2. 觀察網頁
網站的左側有選單可以選擇各個區的名單, 如下截圖
點選後發現, 每次的網址不同
查詢網頁的原始碼, 發現清單放在JavaScript的註解中
將整段COPY如下:
<script language="JavaScript" type="text/javascript"><!--
var demoMenu =[ ,[null,'中區旅館','./?mode=aG90ZWw==&class=NA==',null,'中區旅館'],,[null,'北屯區旅館','./?mode=aG90ZWw==&class=MQ==',null,'北屯區旅館'],,[null,'和平區旅館','./?mode=aG90ZWw==&class=MzM=',null,'和平區旅館'],,[null,'梧棲區','./?mode=aG90ZWw==&class=MzI=',null,'梧棲區'],,[null,'后里區旅館','./?mode=aG90ZWw==&class=MTU=',null,'后里區旅館'],,[null,'豐原區旅館','./?mode=aG90ZWw==&class=MTQ=',null,'豐原區旅館'],,[null,'大雅區','./?mode=aG90ZWw==&class=MzE=',null,'大雅區'],,[null,'大里區旅館','./?mode=aG90ZWw==&class=MTE=',null,'大里區旅館'],,[null,'太平區旅館','./?mode=aG90ZWw==&class=MTA=',null,'太平區旅館'],,[null,'東區旅館','./?mode=aG90ZWw==&class=OA==',null,'東區旅館'],,[null,'南區旅館','./?mode=aG90ZWw==&class=Nw==',null,'南區旅館'],,[null,'西區旅館','./?mode=aG90ZWw==&class=Ng==',null,'西區旅館'],,[null,'北區旅館','./?mode=aG90ZWw==&class=NQ==',null,'北區旅館'],,[null,'南屯區旅館','./?mode=aG90ZWw==&class=Mw==',null,'南屯區旅館'],,[null,'西屯區旅館','./?mode=aG90ZWw==&class=Mg==',null,'西屯區旅館'],,[null,'大安區旅館','./?mode=aG90ZWw==&class=MzA=',null,'大安區旅館'], ];
var prop = cmClone (cmThemeGray);prop.effect = new CMSlidingEffect (8);cmDraw ('cookmenu', demoMenu, 'vbr', prop, 'ThemeGray');
--></script>
利用 Python語法, 將文件轉換成 dict 的內容
hotel = "[ ,[null,'中區旅館','./?mode=aG90ZWw==&class=NA==',null,'中區旅館'],,[null,'北屯區旅館','./?mode=aG90ZWw==&class=MQ==',null,'北屯區旅館'],,[null,'和平區旅館','./?mode=aG90ZWw==&class=MzM=',null,'和平區旅館'],,[null,'梧棲區','./?mode=aG90ZWw==&class=MzI=',null,'梧棲區'],,[null,'后里區旅館','./?mode=aG90ZWw==&class=MTU=',null,'后里區旅館'],,[null,'豐原區旅館','./?mode=aG90ZWw==&class=MTQ=',null,'豐原區旅館'],,[null,'大雅區','./?mode=aG90ZWw==&class=MzE=',null,'大雅區'],,[null,'大里區旅館','./?mode=aG90ZWw==&class=MTE=',null,'大里區旅館'],,[null,'太平區旅館','./?mode=aG90ZWw==&class=MTA=',null,'太平區旅館'],,[null,'東區旅館','./?mode=aG90ZWw==&class=OA==',null,'東區旅館'],,[null,'南區旅館','./?mode=aG90ZWw==&class=Nw==',null,'南區旅館'],,[null,'西區旅館','./?mode=aG90ZWw==&class=Ng==',null,'西區旅館'],,[null,'北區旅館','./?mode=aG90ZWw==&class=NQ==',null,'北區旅館'],,[null,'南屯區旅館','./?mode=aG90ZWw==&class=Mw==',null,'南屯區旅館'],,[null,'西屯區旅館','./?mode=aG90ZWw==&class=Mg==',null,'西屯區旅館'],,[null,'大安區旅館','./?mode=aG90ZWw==&class=MzA=',null,'大安區旅館']"
hotel = hotel.replace('[','')
hotel = hotel.replace(']','')
hotel = hotel.replace(',null','')
hotel = hotel.replace(',,',',')
hotel = hotel.replace("'","")
hotel_list = hotel.split(',')
del hotel_list[0]
hotel_area = {}
for i in range(0,len(hotel_list),3):
hotel_area[hotel_list[i]] = hotel_list[i + 1].replace('./','http://www.thotel.org/')
print(hotel_area)
dict 如下:
{'中區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=NA==', '北屯區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=MQ==', '和平區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=MzM=', '梧棲區': 'http://www.thotel.org/?mode=aG90ZWw==&class=MzI=', '后里區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=MTU=', '豐原區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=MTQ=', '大雅區': 'http://www.thotel.org/?mode=aG90ZWw==&class=MzE=', '大里區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=MTE=', '太平區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=MTA=', '東區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=OA==', '南區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=Nw==', '西區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=Ng==', '北區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=NQ==', '南屯區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=Mw==', '西屯區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=Mg==', '大安區旅館': 'http://www.thotel.org/?mode=aG90ZWw==&class=MzA='}
3. 發出請求
利用其中一個 '中區旅館' 的網址, 來做網頁內容的分析
url = 'http://www.thotel.org/?mode=aG90ZWw==&class=NA=='
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'}
resp = requests.get(url, headers=headers)
# 設定編碼為 utf-8 避免中文亂碼問題
resp.encoding = 'utf-8'
# 根據 HTTP header 的編碼解碼後的內容資料(ex. UTF-8),若該網站沒設定可能會有中文亂碼問題。所以通常會使用 resp.encoding 設定
raw_html = resp.text
# 將 HTML 轉成 BeautifulSoup 物件,這裡使用 html.parser 內建解析器
soup = BeautifulSoup(raw_html, 'html.parser')
4. 解析內容
利用 css select 得到資料可以在 div.side 中解析出來
content_detail > div.side > div:nth-child(1)
soup.select('#content_detail > div.side > div:nth-child(1)')[0].text
'\n\n\n\n\n\n福爾摩沙中旅酒店\n\n\n電話:04-22262777\n傳真:04-22240808\n\n\n地址:台中市中區建國路173號\n\n\n'
只要變動 nth-child(1) 為 nth-child(2) 就是下一筆資料
soup.select('#content_detail > div.side > div:nth-child(2)')[0].text
'\n\n\n\n\n\n銀河別舘\n\n\n電話:04-22260467\n傳真:04-22262218\n\n\n地址:400台中市中區光復路151號11樓 \n\n\n'
而 div.p_page' 為 資料共幾頁的所在內容
soup.select('#content_detail > div.side > div.p_page')[0].text
'第1頁/共3頁(總共53筆) \n123'
每一頁最多20筆資料, 網址可以在加上 &page=2 來換成第2頁
url = 'http://www.thotel.org/?mode=aG90ZWw==&class=NA==&page=2'
5. 儲存資料
根據上述的規則, 就可以使用迴圈換頁及資料解析後, 將資料存成所需的格式, 供日後查詢使用
這裡用 .csv 來存檔, 方便 日後 EXCEL 可以使用