開發函式計算的正確姿勢 —— 爬蟲
在 中,我們介紹了利用 Fun Local 本地執行、除錯函式的方法。但如果僅僅這樣簡單的介紹,並不能展現 Fun Local 對函式計算開發的巨大效率的提升。
這一次,我們拿一個簡單的場景來舉例子——開發一個簡單的爬蟲函式(程式碼參考函式計算 控制檯模板 ),介紹如何以正確姿勢,從零開始,開發一個自動伸縮、按呼叫次數收費的 serverless 爬蟲應用。
開發步驟
我們將這個完整的應用拆分成多步,並且在每一步完成後,我們都會進行相應的執行驗證。
1. 建立 Fun 專案
首先,我們建立一個名為 image-crawler 的目錄作為專案的根。然後在該目錄下建立一個名為 template.yml 的檔案,內容為:
ROSTemplateFormatVersion: '2015-09-01'Transform: 'Aliyun::Serverless-2018-04-03'Resources: localdemo: Type: 'Aliyun::Serverless::Service' Properties: Description: 'local invoke demo' image-crawler: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler CodeUri: code/ Description: 'Hello world with python2.7!' Runtime: python2.7
如果不瞭解 Fun 定義的 Serverless Application Model,可以參考 。
操作完成後,我們的專案目錄結構如下:
. └── template.yml
2. 編寫 helloworld 函式程式碼
在根目錄下建立一個名為 code 的目錄,並在該目錄下建立一個名為 index.py 的檔案,內容為一個簡單的 helloworld 函式:
def handler(event, context): return 'hello world!'
在專案根目錄下執行:
fun local invoke image-crawler
函式執行成功:
操作完成後,我們的專案目錄結構如下:
. ├── code│ └── index.py└── template.yml
3. 事件觸發函式執行
我們簡單修改第 2 步的程式碼,將 event 列印到 log 中。
import logging logger = logging.getLogger()def handler(event, context): logger.info("event: " + event) return 'hello world!'
透過觸發事件的方式執行函式,得到如下結果:
可以看到,我們的函式已經能正確接收到觸發事件了。
Fun Local 更多幫助資訊, 。
4. 獲取網頁原始碼內容
接下來,我們新增獲取網頁內容的程式碼。
import loggingimport jsonimport urllib logger = logging.getLogger()def handler(event, context): logger.info("event: " + event) evt = json.loads(event) url = evt['url'] html = get_html(url) logger.info("html content length: " + str(len(html))) return 'Done!'def get_html(url): page = urllib.urlopen(url) html = page.read() return html
程式碼邏輯比較簡單,我們這裡直接使用了 urllib 庫,讀取網頁內容。
執行函式,得到以下輸出:
5. 解析網頁中的圖片
我們打算透過正則解析網頁中包含的 jpg 圖片,因此這一步會比較繁瑣,因為涉及到正規表示式的微調。為了能快速的解決問題,我們決定利用 fun local 提供的 local debugging 解決問題。local debugging 方法參考: 。
首先,我們在下面這一行下個斷點:
logger.info("html content length: " + str(len(html)))
然後以 debug 的方式啟動,vscode 偵錯程式連線後,函式會繼續執行到我們斷點的這一行:
我們可以直接在 Locals 一欄看到本地變數,其中包含了
html
這個變數,也就是我們獲取到的 html 原始碼。我們可以將它的值複製出來,分析下,然後設計正規表示式。
我們可以先寫一個簡單的,比如可以是
http:\/\/[^\s,"]*\.jpg
。
怎麼快速校驗這段程式碼的正確性呢?我們可以利用偵錯程式提供的
Watch(監視)
功能。
建立一個 Watch 變數,將下面的值輸入進去:
re.findall(re.compile(r'http:\/\/[^\s,"]*\.jpg'), html)
回車後,即可看到程式碼的執行效果:
這裡一般不太容易一次寫對,可以反覆修改正則測試,直到正確為止。
我們得到的正確的圖片解析的邏輯新增到程式碼中:
reg = r'http:\/\/[^\s,"]*\.jpg'imgre = re.compile(reg)def get_img(html): return re.findall(imgre, html)
然後在 handler 方法中呼叫即可:
def handler(event, context): logger.info("event: " + event) evt = json.loads(event) url = evt['url'] html = get_html(url) img_list = get_img(html) logger.info(img_list) return 'Done!'
編寫完成後,可以繼續本地執行,驗證下結果:
echo '{"url": "https://image.baidu.com/search/index?tn=baiduimage&word=%E5%A3%81%E7%BA%B8"}' \ | fun local invoke image-crawler
可以看到,img_list 已經輸出到控制檯了:
6. 將圖片上傳到 oss
解析到的圖片,我們選擇使用 儲存。
首先,我們需要透過環境變數配置 OSS Endpoint 以及 OSS Bucket。
在 template 中配置環境變數(需提前建立好 oss bucket):
EnvironmentVariables: OSSEndpoint: oss-cn-hangzhou.aliyuncs.com BucketName: fun-local-test
然後就可以直接在函式中獲取到這兩個環境變數了:
endpoint = os.environ['OSSEndpoint'] bucket_name = os.environ['BucketName']
另外,fun local 執行函式時,還會提供一個額外的變數用來標識這是一個本地執行的函式。透過這個標識,我們可以用來做一些本地化的操作,比如我們可以線上上執行時連線 RDS,在本地執行時連線 Mysql。
這裡,我們用該標識以不同的的方式建立 oss client,原因是線上執行時,透過 credentials 獲取到的是扮演角色的臨時 ak,有有效期限制,而本地執行時,沒有該限制。oss 提供了這兩種方式的構造方法,我們直接使用即可:
creds = context.credentialsif (local): auth = oss2.Auth(creds.access_key_id, creds.access_key_secret)else: auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token) bucket = oss2.Bucket(auth, endpoint, bucket_name)
接著我們遍歷所有圖片,將所有的圖片上傳到 oss:
count = 0for item in img_list: count += 1 logging.info(item) # Get each picture pic = urllib.urlopen(item) # Store all the pictures in oss bucket, keyed by timestamp in microsecond unit bucket.put_object(str(datetime.datetime.now().microsecond) + '.png', pic)
再在本地執行一下函式:
echo '{"url": "https://image.baidu.com/search/index?tn=baiduimage&word=%E5%A3%81%E7%BA%B8"}' \ | fun local invoke image-crawler
可以從日誌看到,圖片被一張一張的解析出來,並被上傳到 oss 上了。
登陸 oss 控制檯,可以看到這些圖片。
部署
本地開發完成後,我們還需要將其釋出到線上,讓其成為一個可被呼叫的服務。以往,你可能覺得比較麻煩,比如要登陸控制檯,建立服務、建立函式、配置環境變數,建立角色等,現在有了 fun 後,這一切都不需要了。
不過,本地與線上還是有些區別的,那就是要授權函式計算能夠訪問 OSS,怎麼做呢?很簡單,在我們的 template 中加入一行配置即可(Polices 文件,可以 ):
Policies: AliyunOSSFullAccess
新增後的 template.yml 內容如下:
ROSTemplateFormatVersion: '2015-09-01'Transform: 'Aliyun::Serverless-2018-04-03'Resources: localdemo: Type: 'Aliyun::Serverless::Service' Properties: Description: 'local invoke demo' Policies: AliyunOSSFullAccess image-crawler: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler CodeUri: code/ Description: 'Hello world with python2.7!' Runtime: python2.7 EnvironmentVariables: OSSEndpoint: oss-cn-hangzhou.aliyuncs.com BucketName: fun-local-test
然後,使用
fun deploy
後,可以看到部署成功的日誌。
驗證
透過控制檯驗證
登陸 ,可以看到,我們的服務、函式、程式碼、環境變數等都已經就緒了。
在觸發事件中,寫入我們用來測試的 json,然後執行:
可以發現,會獲得與本地一致的效果:
透過 fcli 驗證
fcli 幫助文件 參考 。
在終端執行以下命令,可以獲取函式列表:
fcli function list --service-name localdemo
可以看到我們的 image-crawler 已經建立成功了。
{ "Functions": [ "image-crawler", "java8", "nodejs6", "nodejs8", "php72", "python27", "python3" ], "NextToken": null}
使用以下命令則可以呼叫函式執行:
fcli function invoke --service-name localdemo \ --function-name image-crawler \ --event-str '{"url": "https://image.baidu.com/search/index?tn=baiduimage&word=%E5%A3%81%E7%BA%B8"}'
執行成功後,會得到與控制檯與 fun local 一致的結果。
小結
至此,我們的開發就算告一段落。
本文利用 fun local 提供的本地執行、除錯的能力,做到了在本地開發函式,並且透過反覆的執行函式得到反饋以便於快速迭代程式碼。
在本地開發完成後,不需要對程式碼進行任何修改,透過 fun deploy 命令,一鍵部署到雲端,達到預期的效果。
本文介紹的方法,並不是開發函式計算的唯一方式。本文的目的,是能夠向開發者傳達一種訊號——開發函式計算時,只要身姿正確,就會非常享受,開發流程也會十分順暢。祝您使用愉快。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31551794/viewspace-2285143/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 開發函式計算的正確姿勢——OCR 服務函式
- 開發函式計算的正確姿勢——執行 Selenium Java函式Java
- 開發函式計算的正確姿勢 —— 排查超時問題函式
- 開發函式計算的正確姿勢——使用 brotli 壓縮大檔案函式
- 開發函式計算的正確姿勢 —— 依賴安裝方法一覽函式
- 開發函式計算的正確姿勢——使用互動模式安裝依賴函式模式
- 開發函式計算的正確姿勢———為 PHP 執行時新增自定義擴充套件函式PHP套件
- Python開發遊戲的正確姿勢Python開發遊戲
- 計算網路頻寬需求的正確姿勢
- 開啟Git的正確姿勢Git
- 學習軟體開發的正確姿勢
- 掌握Redis分散式鎖的正確姿勢Redis分散式
- BigDecimal 在資金計算時正確使用姿勢Decimal
- 「分散式」實現分散式鎖的正確姿勢?!分散式
- Redis的正確使用姿勢Redis
- vue多頁面開發和打包的正確姿勢Vue
- django開發時遇到問題的正確求助姿勢Django
- 區塊鏈的正確開啟姿勢區塊鏈
- Git和GitHub的正確開啟姿勢Github
- Postman 正確使用姿勢Postman
- Homestead 開啟mongodb正確姿勢MongoDB
- 前後端協同開發,使用 GraphQL 正確的姿勢後端
- 這才是實現分散式鎖的正確姿勢!分散式
- git commit 的正確姿勢GitMIT
- 玩轉 Ceph 的正確姿勢
- laravel 使用 es 的正確姿勢Laravel
- java關流的正確姿勢Java
- 使用快取的正確姿勢快取
- Fragment commit 的正確姿勢FragmentMIT
- 開源專案翻譯正確姿勢
- 翻譯 | 新手開始學習程式設計的正確姿勢程式設計
- Goland 開啟一個專案的正確姿勢GoLand
- Python爬蟲的N種姿勢Python爬蟲
- 原始碼|使用FutureTask的正確姿勢原始碼
- 相容iphone x劉海的正確姿勢iPhone
- npm run dev 的正確使用姿勢NPMdev
- 限制UITextField字數的正確姿勢UI
- 使用 Java 8 Optional 的正確姿勢Java