#前言
如果說Java算我的主語言,那當了這麼久的程序猿,不學習一門副語言說不過去。近幾年趨勢下,Python和Go是目前最火的選擇。目前狀態下,我學習Go這種高併發語言可能沒有什麼使用場景,所以選了Python,入門簡單,可玩性很高。
17年(才)學習了Python,後面就一直尋找寫點什麼代碼的機會。
1.先是寫了些很簡單的腳本,配合正則表達式實現簡單修改裏面的文件內容。
2.爬蟲這麼好玩的東西怎麼能不玩,學習了python scrapy框架。爬了什麼值得買《python scrapy 入門爬蟲 「什麼值得買」關鍵字搜索》。可以根據關鍵字搜索和按照條件篩選出商品。
微博問題也是個好東西,裏面的問題是超過一定時間可以免費圍觀的。由於每次進入微博從幾百條問題中找到當前閱讀進度的那條問題很不容易,所以寫了份爬取問答列表的代碼。試過爬取裏面的內容,發現微博驗證機制很厲害。請了個前端大哥幫忙嘗試破解都搞不定所以放棄了。有這樣一份問題列表看起來就很方便了。
3.工作需要又用 Python 進行了很多數據統計,爲同事們提供了無數份 excel 數據統計。還爬了下某眼的票房和觀影人次數據,這數據對公司的參考意義實在是很大。
#項目實現
1.python scrapy爬蟲,爬什麼值得買。
2.使用 python flask 實現小型 web 服務。(後悔沒用 django,遇到很多問題搜索不到)
3.接入微信公衆號後臺,可以收到用戶向這個公衆號發送的消息,制定被動回覆用戶消息內容。主動發送客戶消息。
4.微信主動發送客服消息接口,只有在用戶發消息來的48小時內,才能發出客服消息。超過48小時候無法發送。所以引入釘釘機器人。
5.寫個前端項目——花不少時間,寫個Android應用——會懶得打開,所以還是在微信中發送特定指令,後臺識別指令來完成功能。但是正則表達式寫的我很難受。
6.簡單的使用 linux crontab 實現定時任務。
項目數據庫設計
列名 | 數據類型 | 字段類型 | 長度 | 是否爲空 | 默認值 | 備註 |
wx_user | 微信用戶表 | |||||
id | int(11) | int | NULL | NO | NULL | 自增id |
wx_openid | varchar(255) | varchar | 255 | NO | 微信openid | |
dd_webhook | varchar(255) | varchar | 255 | YES | NULL | 釘釘機器人webhook網址 |
create_time | datetime | datetime | NULL | NO | NULL | 創建時間 |
update_time | datetime | datetime | NULL | NO | NULL | 更新時間 |
status | tinyint(1) | tinyint | NULL | NO | 0 | 0默認 1關注 2取關 |
zdm_item | 商品表 | |||||
id | int(11) | int | NULL | NO | NULL | 商品id |
title | varchar(255) | varchar | 255 | NO | 商品標題 | |
price | varchar(255) | varchar | 255 | NO | 價格 | |
desc | text | text | 65535 | NO | NULL | 描述 |
zhi_yes | int(11) | int | NULL | NO | NULL | 點值數 |
zhi_no | int(11) | int | NULL | NO | NULL | 點不值數 |
star | int(11) | int | NULL | NO | NULL | 收藏數 |
comment | int(11) | int | NULL | NO | NULL | 評論數 |
time | datetime | datetime | NULL | NO | NULL | 商品發佈時間 |
channel | varchar(255) | varchar | 255 | NO | 商品渠道(淘寶、京東等) | |
detail_url | varchar(255) | varchar | 255 | NO | 值得買商品詳情連接 | |
url | varchar(255) | varchar | 255 | NO | 商品購買了鏈接 | |
img | varchar(255) | varchar | 255 | NO | 商品圖片 | |
scrapy_record | 搜索記錄 | |||||
id | int(11) | int | NULL | NO | NULL | 自增id |
wx_openid | varchar(255) | varchar | 255 | NO | 微信openid | |
params | varchar(255) | varchar | 255 | NO | 此次搜索參數 | |
type | tinyint(1) | tinyint | NULL | NO | 0 | 0主動搜索,1推送 |
result | text | text | 65535 | YES | NULL | 搜索結果商品id列表 |
send | text | text | 65535 | YES | NULL | 需要發送到用戶的商品id列表 |
time | datetime | datetime | NULL | NO | NULL | 爬取時間 |
wx_message | 微信消息記錄 | |||||
id | int(11) | int | NULL | NO | NULL | 自增id |
msg_id | bigint(20) unsigned | bigint | NULL | NO | NULL | 微信msg_id |
msg_type | varchar(11) | varchar | 11 | NO | 微信msg類型 | |
from_user | varchar(255) | varchar | 255 | NO | 發送者微信openid | |
to_user | varchar(255) | varchar | 255 | NO | 接受者微信openid | |
create_time | bigint(20) unsigned | bigint | NULL | NO | NULL | 創建時間 |
content | text | text | 65535 | NO | NULL | 消息內容 |
config |
存一直配置字段 比如微信access_token |
|||||
alembic_version | sqlalchemy創建的 |
#使用說明
關注公衆號發特定命令。
因爲微信的主動客服消息需要認證,需要公司營業執照之類的。搞不定只好用測試號。
1.主動搜索
h 表示help
『bind_webhook』{url} 和 『unbind_webhook』 表示綁定釘釘機器人
參照釘釘文檔《釘釘-自定義機器人》,畢竟微信客戶消息只有48小時內可以發出,而且釘釘支持md風格消息,所以可以看圖片。
「小米」「穀物」「80:10:-1:-1:-1」
第一個直角引號是搜索關鍵字
第二個直角引號是排除關鍵字
第三個直角引號是篩選條件,裏面分號分隔,分別是「點值比率需要≥x:點值數≥x:點不值數≤x:收藏數≥x:評論數≥x」-1表示不使用該篩選條件
2.設定推送
前3個命令就是操作 linux crontab 文件的增刪查功能。
『push_immediately』{筆記本} 這個的使用場景是,比如我設定了早10點-晚22點的整點推送,然後早上起來9點50分,目前剛好有時間看下商品推送,等下就要擠公交沒時間看了。就可以發送這條命令立即讓服務搜索+推送一遍。
#遇到的問題
1.flask中執行scrapy爬蟲方法會異步
改爲命令行執行,同步完成後去數據庫搜索該用戶的最新記錄(這方法有點山寨)
os.system('scrapy crawl concrete_search -a search_item=%s -a exclude=%s -o smzdm.json' % (search_item, exclude))
2.scrapy的pipelines.py中無法使用flask_alchemy操作數據庫,因爲不在flask上下文環境內。
使用原生pymysql進行添加數據操作
3.有外鍵關聯的,兩個表刪除一併刪除
改數據庫表實現級聯刪除
4.執行os.system('scrapy crawl concrete_search -a search_item=%s -a exclude=%s -o smzdm.json' % (search_item, exclude))時報錯,No module named _sqlite3
yum install sqlite-devel 然後重裝python(進入python安裝目錄,make,然後make install)
5.微信出現「該公衆號提供的服務出現故障,請稍後再試」
一開始以爲是5秒內未能返回,折騰多線程多進程,想臨時返回「爬取中...」。再使用微信客服客服消息發送。各種折騰搗鼓了大半天,後面發現其實是微信返回的消息長度過長。所以最後改成在微信中只返回7條商品信息。
6.使用 threading.Thread 新建線程,異步請求釘釘webhook發送機器人消息。發現一直卡住。
浪費了我兩天時間,期間還去找 python 程序員兄弟問了下,他說他也沒啥頭緒。持續摸索,發現flask框架對於一個請求返回後,這次請求啓動的線程全部都停止了,直到下一個請求過來纔會執行。
#項目源碼
非專業的寫的太爛,而且還不怎麼整理。不好意思放了。
還沒做輸入參數的驗證。如果破壞性的輸入各種奇奇怪怪的值,估計服務器還會報錯。
引用程序猿經典用語「先實現功能,其他的再慢慢迭代」