利用 Python 寫 Selenium 爬蟲來爬取網站的商品狀態,其中使用到 Selenium 等待網頁載入完畢,BeautifulSoup 解析爬取資料,和 Smtplib 將結果寄信給我和同事,最後用 Linux 內建的 Crontab 排程於每日早上執行這件事情,就這樣每天進公司前就可以在信箱裡面看到這份資料了~
Table
第一步:Python Selenium自動開啟瀏覽器!
這部分原本是使用 implicitly_wait(): 隱式等待的方法,但因為 WebDriver 常常等到超出時間設定造成回拋異常,所以這邊改成先讓他沈睡 5 秒鐘,再進行爬取資料!
第二步:BeautifulSoup解析網頁
這部分嘗試了 findall() 但最後還是選擇用 selcet() 將 #buy 內都抓出來,因為網頁庫存會有三種不同的狀態,所以這邊也多寫了兩個狀態來判別庫存。
第三步:利用Smtplib將文件檔寄出
這部分花了一些時間,一直沒收到信件,最後發現問題是出在 gmail 權限設定部分。
第四步:利用Linux的Crontab進行每日排程
花了點時間在學習 Linux,剛開始 Crontab 一直會回拋出現錯誤,因為這台 Mac 裡有三個版本的 Python,最後將路徑全部修改成絕對路徑也終於解決問題了。
最後~
▍關於 Selenium 相關其他文章,可以參考:
- 【爬蟲教學】如何讓 Selenium 多線池執行時 driver 不會重複開啟
- 【爬蟲教學】如何在 GCP 上架設 selenium 爬蟲環境
- 【爬蟲教學】如何在 GCP 上架設運行 Python 爬蟲程式
▍關於與 Concurrency Programming 相關其他文章,可以參考:
- 【Python教學】淺談 Concurrency Programming
- 【Python教學】淺談 GIL & Thread-safe & Atomic
- 【Python教學】淺談 Multi-processing & Multi-threading 使用方法
- 【Python教學】淺談 Multi-processing pool 使用方法
▍關於 Async IO 相關其他文章,可以參考:
- 【Python教學】淺談 Coroutine 協程使用方法
- 【Python教學】Async IO Design Patterns 範例程式
- 【實戰篇】 解析 Python 之父寫的 web crawler 異步爬蟲
那 [爬蟲筆記] Python Selenium 爬蟲教學:實作商品庫存爬取 的介紹就到這邊告一個段落囉!有任何問題可以在以下留言~
有關 Max行銷誌的最新文章,都會發佈在 Max 的 Facebook 粉絲專頁,如果想看最新更新,還請您按讚或是追蹤唷!
附上完成程式碼:
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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# coding: utf-8 import pandas as pd import selenium from selenium import webdriver import time from bs4 import BeautifulSoup # 匯入資料 item = pd.read_csv('/Users/max/Desktop/Project_商品庫存/商品庫存.csv') pList = [] # 獲得爬取URL for data in item['url']: data_url = data.split('?utm')[0] print(data_url) # selenium開啟chrome等待網頁載入完成 driver = webdriver.Chrome('/Applications/chromedriver') driver.get(data_url) time.sleep(5) # 抓取網頁資料 soup = BeautifulSoup(driver.page_source,"html.parser") items = soup.select('#buy') print (soup.select('#buy')) for i in items: print (i.get('src').split('/').pop()) # 寫入pList pList.append([data_url, i.get('src').split('/').pop(), soup.select('#buy') ]) driver.close() print ('done!') # 儲存成csv df = pd.DataFrame(pList) df.columns = ['網址', '狀態1', '狀態2'] df.to_csv('/Users/max/Desktop/庫存測試.csv', index=False) pList # 發送信件 import os import sys import smtplib from email import encoders from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart COMMASPACE = ', ' def main(): sender = '信箱帳號' gmail_password = '信箱密碼' recipients = ['寄送人1','寄送人2'] # 建立郵件主題 outer = MIMEMultipart() outer['Subject'] = 'Test' outer['To'] = COMMASPACE.join(recipients) outer['From'] = sender outer.preamble = 'You will not see this in a MIME-aware mail reader.\n' # 檔案位置 attachments = ['/Users/max/Desktop/庫存測試.csv'] # 加入檔案到MAIL底下 for file in attachments: try: with open(file, 'rb') as fp: print ('can read faile') msg = MIMEBase('application', "octet-stream") msg.set_payload(fp.read()) encoders.encode_base64(msg) msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(file)) outer.attach(msg) except: print("Unable to open one of the attachments. Error: ", sys.exc_info()[0]) raise composed = outer.as_string() # 寄送EMAIL try: with smtplib.SMTP('smtp.gmail.com', 587) as s: s.ehlo() s.starttls() s.ehlo() s.login(sender, gmail_password) s.sendmail(sender, recipients, composed) s.close() print("Email sent!") except: print("Unable to send the email. Error: ", sys.exc_info()[0]) raise main() |