1.綜述
偽代碼
可以參考《廿-爬URL以及分詞情緒分析初步設(shè)想》赋荆,才發(fā)現(xiàn)這個(gè)要做一整天才做得出來(lái)笋妥,不過(guò)大部分時(shí)間都是用來(lái) 部署
服務(wù)器。
代碼放在大型同性交友網(wǎng)站
其實(shí)根據(jù) 偽代碼
來(lái)寫(xiě)程序很簡(jiǎn)單窄潭,但主要有很多地方卡住春宣,需要現(xiàn)學(xué)現(xiàn)賣(mài),以下均為現(xiàn)學(xué)的點(diǎn)嫉你。
2.關(guān)鍵技術(shù)點(diǎn)
2.1 Python Class
關(guān)于 Python
的 類
月帝,對(duì)于其他 腳本語(yǔ)言
的類來(lái)說(shuō)并無(wú)太大差異,但不知道是不是習(xí)慣了 JS
的閉包幽污,寫(xiě)到 Python
上就會(huì)很多莫名其妙的錯(cuò)誤嚷辅。
而且其實(shí)本次并無(wú) 繼承
方面的需求,所以純粹是為了寫(xiě) 類
而寫(xiě)距误。
2.2 異步
異步
這東西用在 Python
上面簡(jiǎn)直是崩潰簸搞,所以我不懂為什么那么多人喜歡 Python
(還是因?yàn)樗翘焐?同步
的所以才那么多人喜歡么?還是純粹是因?yàn)樗泻芏喟盍龋浚?br>
Python
異步比較多的是 asyncio
攘乒。
關(guān)于 asyncio
,我覺(jué)得最絕望的是惋鹅,根本不知道怎么 列隊(duì)
则酝!就是如何啟動(dòng),我嘗試過(guò)兩種辦法:
# --------- 以下不懂闰集,失敗嘗試-------------
class classSpy():
def __init__(self, arrInProxy):
self.arrProxy = iter(arrInProxy)
def __aiter__(self):
return self
async def __anext__(self):
try:
eleProxy = next(self.arrProxy)
except StopIteration:
raise StopAsyncIteration
return eleProxy
arrTmp = []
arrTmp.append(1)
arrTmp.append(2)
arrTmp.append(3)
arrTmp.append(4)
arrTmp.append(5)
arrTmp.append(6)
async def run():
print('Begin : '+time.strftime('%Y-%m-%d %H:%M:%S'))
async for eleBe in classSpy(arrTmp):
await asyncio.sleep(random.randint(1, 3))
print(' Now : ' + str(eleBe) + ' , time: ' +
time.strftime('%Y-%m-%d %H:%M:%S'))
print('End : '+time.strftime('%Y-%m-%d %H:%M:%S'))
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
# ------------------------------------------
# --------- 以下為異步嘗試成功-------------
arrTmp = []
arrTmp.append(1)
arrTmp.append(2)
arrTmp.append(3)
arrTmp.append(4)
arrTmp.append(5)
arrTmp.append(6)
async def run(eleBe, inSemaphore):
async with inSemaphore:
await asyncio.sleep(random.randint(1, 3))
print(' Now : ' + str(eleBe) + ' , time: ' +
time.strftime('%Y-%m-%d %H:%M:%S'))
def funDone(waittask):
print('Callback End : '+time.strftime('%Y-%m-%d %H:%M:%S'))
print('Begin : '+time.strftime('%Y-%m-%d %H:%M:%S'))
# -------------調(diào)用方式1----------------
async def main():
semaphore = asyncio.Semaphore(2)
waittask = asyncio.gather(*([run(proxy, semaphore) for proxy in arrTmp]))
waittask.add_done_callback(funDone)
await asyncio.gather(waittask)
asyncio.run(main())
# -------------------------------------
# -------------調(diào)用方式2----------------
loop = asyncio.get_event_loop()
semaphore = asyncio.Semaphore(2)
waittask = asyncio.gather(*([run(proxy, semaphore) for proxy in arrTmp]))
waittask.add_done_callback(funDone)
loop.run_until_complete(waittask)
loop.close()
# -------------------------------------
print('Program End : '+time.strftime('%Y-%m-%d %H:%M:%S'))
# ------------------------------------------
其中我嘗試了很久沽讹,然后最終還是得去參考官方文檔。參考的文檔如下:
很艱難終于能 啟動(dòng)
真正的 異步
處理了爽雄,如上述方法2,但是在 多線程異步
的時(shí)候沐鼠,發(fā)現(xiàn) Loop
在同一程序中不支持 同時(shí)多次調(diào)用
挚瘟,找了好久終于找到以下方法:
2.2 Python 鏈接 MongoDB
這個(gè)真是一個(gè)大坑叹谁,例如
-
find()
函數(shù) 在Python
中還是find()
-
findOne()
函數(shù)在Python
中就是find_one()
-
deleteMany()
函數(shù)在Python
中就是delete_many()
- 因?yàn)?
Python
沒(méi)有JSON
,所以只能用字典
乘盖,如:{$lt:10} 要寫(xiě)成 {'$lt':10}
參考資料有:
某個(gè)資料
2.3 網(wǎng)頁(yè)請(qǐng)求及解析
這個(gè)倒比較方便焰檩,直接用人家寫(xiě)好的就行了,參考資料如下:
別人的資料
2.4 超時(shí)重復(fù)請(qǐng)求
當(dāng)有當(dāng)前引用的代理 超時(shí)
的時(shí)候订框,請(qǐng)求另外的 代理服務(wù)器
析苫,但好像沒(méi)有特定的處理辦法,所以只有參考材料穿扳,做一個(gè) While
做判斷是否超時(shí)衩侥,相關(guān)代碼如參考文章:
參考文章
3.部署Python程序
這個(gè)是真的是一個(gè)巨坑,我都不想弄了矛物,但沒(méi)辦法茫死,都已經(jīng)開(kāi)始了。
NodeJS
我是用 PM2
的泽谨,PM2
其實(shí)也有一些坑璧榄,例如在 Start
一個(gè)項(xiàng)目后,需要 Save
再 Startup
以達(dá)到 開(kāi)機(jī)啟動(dòng)
的環(huán)境吧雹,但是中間需要配置一個(gè) 環(huán)境配置
,不然開(kāi)機(jī)后仍然無(wú)法啟動(dòng)涂身。
而 Python
的程序管理軟件有一個(gè) Supervisord
雄卷,從很久之前就在用這個(gè),可是重新配置還是很麻煩的蛤售。
3.1 關(guān)于安裝
在裝這個(gè)軟件時(shí)丁鹉,我發(fā)現(xiàn) 騰訊云
服務(wù)器是沒(méi)有預(yù)裝 Pip
的,裝完 Pip
之后再裝 Supervisord
發(fā)現(xiàn)很多東西根本沒(méi)有配置悴能,直到找到這個(gè)文章:
centos7安裝supervisor詳細(xì)教程
可是我已經(jīng)裝好了揣钦,用了一個(gè)不推薦的方法,唉漠酿。
3.2 關(guān)于配置
沒(méi)關(guān)系冯凹,裝好之后,為什么 配置
那么麻煩炒嘲。因?yàn)槲沂窍肟纯次业某绦蜉敵鲇钜Γ员仨毎?托管程序
的輸出 輸出
到某個(gè)目錄下,配置好麻煩夫凸,以下是主要能實(shí)施我功能的配置
浑劳。
配置介紹
[program:spylink]
command=python3 /home/Berry/Repositories/SpyTheLink/run.py ; 這個(gè)就是我的路徑了,因?yàn)槲矣?Python3 寫(xiě)的夭拌,所以這個(gè)比較重要
directory=/home/Berry/Repositories/SpyTheLink ; directory to cwd to before exec (def no cwd)魔熏,這個(gè)需要配置衷咽,不然配置文件找不到路徑
autostart=true ; start at supervisord start (default: true) ,這個(gè)是當(dāng)然的
startsecs=10 ; number of secs prog must stay running (def. 1)
autorestart=true ; whether/when to restart (default: unexpected)
startretries=0 ; max # of serial start failures (default 3)
user=Berry ; setuid to this UNIX account to run the program蒜绽,用Root不能運(yùn)行我也不知道為什么镶骗,好像沒(méi)設(shè)可運(yùn)行?還是運(yùn)行環(huán)境問(wèn)題滓窍?
priority=999 ; the relative start priority (default 999)
redirect_stderr=false ; redirect proc stderr to stdout (default false)卖词,因?yàn)槲也恍枰磗tderr的,主要看輸出結(jié)果(錯(cuò)是很正常的這種趕出來(lái)的程序)
stdout_logfile_maxbytes=10MB ; max # logfile bytes b4 rotation (default 50MB)
stdout_logfile_backups = 10 ; # of stdout logfile backups (default 10)
stdout_logfile=/home/Berry/Repositories/SpyTheLink/logs/spylink.out
stderr_logfile=/home/Berry/Repositories/SpyTheLink/logs/spylink.err ; stderr log path, NONE for none; default AUTO
stderr_logfile_maxbytes=10MB ; max # logfile bytes b4 rotation (default 50MB)
stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)
loglevel=info ;(log level;default info; others: debug,warn,trace)吏夯,因?yàn)槲沂切枰敵鲂畔⒋蓑冢圆恍枰渌J(rèn)就好
4.后記
需要做一個(gè)以 Django
做為服務(wù)器端的人工判斷器并記錄噪生,我可能需要再思考一下我該怎么做下一步先裆赵。