Journey

The journey is the destination.

0%

MOMO購物網 網路爬蟲

最近梅雨季讓房間變得好潮濕,為了避免衣服發霉就決定要來採購一台除濕機,
但是除濕機的品牌又多又雜,在網站上總是看的頭昏眼花,不如就來寫個爬蟲程式自動幫我們整理出結構化的資料吧!(咦!這句話怎麼這麼熟悉?)

註:本篇文章僅供研究使用,請勿惡意大量爬取資料造成對方公司的負擔

MOMO購物網 爬蟲要點

  1. 如果電腦版的網頁不好爬怎麼辦…?那就改爬手機版的網頁吧!
  2. 資料的整理會需要使用一些正則表達式,但這比較瑣碎就不多說了

MOMO購物網 爬蟲流程

載入使用套件

1
2
3
4
5
import pandas as pd
from bs4 import BeautifulSoup
import json
import requests
import re

設定 request 參數

在這裡沒有設定 User-Agent 會被拒絕連線,因此當我們無法成功取回資料時的第一個步驟一定是加上 User-Agent 來進行測試!

1
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}

收集產品連結清單

為什麼前面說電腦版的網頁不好爬呢?我們看第一張圖,跟伺服器請求資料的方式是用 POST 的方式,而且 POST 過去的參數也相當複雜,我有嘗試 POST 這些資料過去但還是沒辦法正常請求到資料,估計還有其他的反爬蟲機制>”<

接著改成用手機版的網頁,請求資料的方式變成 GET,而且送的參數變得相當簡單,基本上就是查詢的關鍵詞和第一個分頁就可以了!所以…在這裡就可以改成抓簡單的手機版網頁就好 XDD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
keyword = '除濕機'
pages = 30
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
urls = []
for page in range(1, pages):
url = 'https://m.momoshop.com.tw/search.momo?_advFirst=N&_advCp=N&curPage={}&searchType=1&cateLevel=2&ent=k&searchKeyword={}&_advThreeHours=N&_isFuzzy=0&_imgSH=fourCardType'.format(page, keyword)
print(url)
resp = requests.get(url, headers=headers)
if resp.status_code == 200:
soup = BeautifulSoup(resp.text)
for item in soup.select('li.goodsItemLi > a'):
urls.append('https://m.momoshop.com.tw'+item['href'])
urls = list(set(urls))
print(len(urls))
# break

爬取產品資料

剩下就是單純的依照前面保存的網址送 request 請求資料,接著再自行定位一下需要資訊的位置,並且搭配正則表達式清理一下不需要的資料即可! 因為比較瑣碎在這裡就不多說了~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
df = []
for i, url in enumerate(urls):
columns = []
values = []

resp = requests.get(url, headers=headers)
soup = BeautifulSoup(resp.text)
# 標題
title = soup.find('meta',{'property':'og:title'})['content']
# 品牌
brand = soup.find('meta',{'property':'product:brand'})['content']
# 連結
link = soup.find('meta',{'property':'og:url'})['content']
# 原價
try:
price = re.sub(r'\r\n| ','',soup.find('del').text)
except:
price = ''
# 特價
amount = soup.find('meta',{'property':'product:price:amount'})['content']
# 類型
cate = ''.join([i.text for i in soup.findAll('article',{'class':'pathArea'})])
cate = re.sub('\n|\xa0',' ',cate)
# 描述
try:
desc = soup.find('div',{'class':'Area101'}).text
desc = re.sub('\r|\n| ', '', desc)
except:
desc = ''

print('================== {} =================='.format(i))
print(title)
print(brand)
print(link)
print(amount)
print(cate)

columns += ['title', 'brand', 'link', 'price', 'amount', 'cate', 'desc']
values += [title, brand, link, price, amount, cate, desc]

# 規格
for i in soup.select('div.attributesArea > table > tr'):
try:
column = i.find('th').text
column = re.sub('\n|\r| ','',column)
value = ''.join([j.text for j in i.findAll('li')])
value = re.sub('\n|\r| ','',value)
columns.append(column)
values.append(value)
except:
pass
ndf = pd.DataFrame(data=values, index=columns).T
df.append(ndf)
df=pd.concat(df, ignore_index=True)

爬取結果

最後總共抓取了 580 個產品的資訊,包含了商品名稱、品牌、描述、價格、類型、連結等等資訊,詳細資訊如下:

1
df.info()

保存資料

抓完資料記得保存結果,不然你會需要重新再抓一次>”<

1
df.to_excel('./MOMO.xlsx')

附件