[Python] [爬蟲] 10.批量政府網站的招投標、中標資訊爬取和推送的自動化爬蟲——排程引擎
阿新 • • 發佈:2018-11-09
目錄
1.Intro
檔名:scheduleEngine.py
模組名:排程引擎
引用庫:
random | time | gc | os |
sys | datetime | retry |
自定義引用檔案:authentication、proxyPool、configManager、pageDownloader、dateDisposer、spiderLog、dataPusher、dataPusher_HTML、Console_Color、log_record
功能:構造代理引擎、獨立代理引擎、驗證引擎、網頁爬取引擎、資料推送引擎,然後統一排程,完成推送。
注:寫的有點冗餘,目前懶得改了,有空就改。
2.Source
#!/usr/bin/env Python
# -*- coding: utf-8 -*-
'''
# Author : YSW
# Time : 2018/6/7 15:47
# File : scheduleEngine.py
# Version : 2.0
# Describe: 排程引擎
# Update :
1.重構了排程引擎,可以實現全自動化爬取和推送。
'''
######## Import ########
import random
import time
import gc # 記憶體釋放
import os
import sys
import authentication # 驗證模組
import proxyPool # 代理池
import configManager # 配置管理器
import pageDownloader # 網頁下載器
import dataDisposer # 資料處理器
import spiderLog # 爬蟲日誌
import dataPusher # 資料推送
import dataPush_HTML
import datetime
from retry import retry
from Lib import Console_Color
import log_record
######## Global Parameters ########
# 動態請求報頭
HEADERS = {
"User-Agent": random.choice(configManager.headers)
}
# URL 列表
URL_LIST = configManager.urlData
URL_LIST_ZB = configManager.urlData_ZB
# 資料庫引數
DATABASE_PARAM = configManager.dataBaseParams
# 表的標題名
TABLE_TITLE = configManager.excel_table_title
# 全域性邏輯控制器
LOGIC_RESPONSE = False
LOGIC_EXECUTE = False
LOGIC_DB_DISPOSE = False
LOGIC_DATA_PUSH = False
LOGIC_PUSH_DONE = False
# 有效的 URL
VALID_URL = []
# 有效的 URL 和對應代理
VALID_URL_PROXY = {}
# 關鍵詞列表
KEY_WORD = []
# 獲取當前檔名
CURRENT_PY = os.path.basename(sys.argv[0]).split(".")[0]
# 建立日誌物件
LOG = spiderLog.SpiderLog(CURRENT_PY)
# 資料庫
TENDER_TABLE = dataDisposer.DataOperate.dataOperate()
# 獲取當前時間
DATE = dataDisposer.current_time()
TODAY_TIME = datetime.datetime(DATE.year, DATE.month, DATE.day, 0, 0, 0)
LOG_TIME = dataDisposer.current_time()
######## Engine Function ########
def proxy_engine(proxyOP):
'''
代理引擎
:return: 返回代理 IP 字典,包含 ip、protocol、port
'''
LOG.info("[*] 開始執行代理引擎")
try:
LOG.info("[+] 獲取代理")
proxyDict = proxyOP.auto_dispose()
print("-" * 25)
print("[+] 當前代理")
print("| Protocol: {0}".format(str(proxyDict["protocol"])))
print("| IP: {0}".format(str(proxyDict["ip"])))
print("| Port: {0}".format(str(proxyDict["port"])))
print("-" * 25)
return proxyDict
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
finally:
del proxyOP
gc.collect()
@retry(tries=5, delay=2)
def independent_proxy_engine(url):
'''
獨立代理引擎,用於重新獲取單個異常網頁的代理
:param url: 異常網頁的 url 連結
:return:
'''
LOG.info("[+] 開始重新獲取代理")
Console_Color.print_color(str="[*] 開始重新獲取代理", forecolor="洋紅")
global VALID_URL_PROXY
auth = authentication.Authentication(headers=HEADERS)
proxyOP = proxyPool.IPOperator(headers=HEADERS)
while True:
proxyDict = proxy_engine(proxyOP)
if auth.proxyVerify(url, proxyDict["protocol"], proxyDict["ip"], proxyDict["port"]):
global VALID_URL_PROXY
VALID_URL_PROXY[url] = proxyDict
break
@retry(tries=5, delay=2)
def authentication_engine():
'''
驗證引擎
:param proxyDict: 代理 IP 字典
:return: 通過驗證後,賦值給響應邏輯器LOGIC_RESPONSE
'''
LOG.info("[*] 開始執行驗證引擎")
auth = authentication.Authentication(headers=HEADERS)
# 避免每次建立物件都開闢塊記憶體,呼叫四個程序池,特別佔記憶體
proxyOP = proxyPool.IPOperator(headers=HEADERS)
global VALID_URL
try:
#### 驗證 HTTP ####
# 遍歷 url 列表進行 http 驗證請求,將有效的 url 儲存在 VALID_URL 中
LOG.info("[+] 驗證 HTTP") # 寫入日誌
for url in URL_LIST.values():
if auth.httpCodeVerify(url):
VALID_URL.append(url)
# 遍歷新加入的 url 列表
for url_zb in URL_LIST_ZB.values():
if auth.httpCodeVerify(url_zb):
VALID_URL.append(url_zb)
# 遍歷有效的 URL
print("-" * 40)
print("[+] 有效的 URL({0})".format(len(VALID_URL)))
for valid_url in VALID_URL:
print(str(valid_url))
print("-" * 40)
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
try:
#### 驗證代理 ####
# 遍歷有效的 url 列表
LOG.info("[+] 驗證代理") # 寫入日誌
for url in VALID_URL:
# 迴圈取出代理進行代理驗證,將有效的代理與對應的 url 儲存在字典中
while True:
proxyDict = proxy_engine(proxyOP)
if auth.proxyVerify(url, proxyDict["protocol"], proxyDict["ip"], proxyDict["port"]):
global VALID_URL_PROXY
VALID_URL_PROXY[url] = proxyDict
break
# 每進行一次 url 的代理驗證,釋放一次記憶體
gc.collect()
# 遍歷 VALID_URL_PROXY 字典
print("-" * 40)
print("[+] 有效網址和代理")
for valid_url in VALID_URL_PROXY:
protocol = VALID_URL_PROXY[valid_url]['protocol']
ip = VALID_URL_PROXY[valid_url]['ip']
port = VALID_URL_PROXY[valid_url]['port']
print("{0}--({1}:{2}:{3})".format(valid_url, protocol, ip, port))
print("-" * 40)
# 儲存完成,賦值全域性變數
global LOGIC_RESPONSE
LOGIC_RESPONSE = True
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
try:
#### 驗證資料庫 ####
LOG.info("[+] 驗證資料庫")
if LOGIC_RESPONSE:
global LOGIC_EXECUTE
LOGIC_EXECUTE = auth.dataBaseVerify(DATABASE_PARAM)
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.info("[+] 清理記憶體")
# 刪除 auth 和 proxyOP 物件
del auth, proxyOP
# 清理記憶體
gc.collect()
TRY_NUM_ynsggzxxt_gc = 1
TRY_NUM_ynsggzxxt_zf = 1
TRY_NUM_ynsggzzw_gc = 1
TRY_NUM_kmsgg_zf = 1
TRY_NUM_kmsgg_gc = 1
TRY_NUM_ynszfcgw = 1
TRY_NUM_ynsggzxxt_gc_zb = 1
TRY_NUM_ynsggzxxt_zf_zb = 1
TRY_NUM_ynsggzzw_gc_zb = 1
TRY_NUM_ynsggzzw_zf_zb = 1
TRY_NUM_kmsgg_gc_zb = 1
TRY_NUM_kmsgg_zf_zb = 1
TRY_NUM_kmsgg_gc_by = 1
TRY_NUM_kmsgg_zf_by = 1
TRY_NUM_ynszfcgw_cg = 1
def page_engine():
'''
網頁引擎
'''
LOG.info("[*] 開始執行網頁引擎")
downloader = pageDownloader.DownLoader(HEADERS)
#### 招投標資訊 ####
def ynsggzxxt_gc():
global TRY_NUM_ynsggzxxt_gc
try:
downloader.downloader_ynsggzxxt(
URL_LIST['雲南省公共資源交易中心電子服務系統_工程建設'],
VALID_URL_PROXY[URL_LIST['雲南省公共資源交易中心電子服務系統_工程建設']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_ynsggzxxt_gc)))) # 寫入日誌
time.sleep(10)
TRY_NUM_ynsggzxxt_gc += 1
if TRY_NUM_ynsggzxxt_gc > 5:
TRY_NUM_ynsggzxxt_gc = 1
independent_proxy_engine(URL_LIST['雲南省公共資源交易中心電子服務系統_工程建設'])
ynsggzxxt_gc()
def ynsggzxxt_zf():
global TRY_NUM_ynsggzxxt_zf
try:
downloader.downloader_ynsggzxxt_zf(
URL_LIST['雲南省公共資源交易中心電子服務系統_政府採購'],
VALID_URL_PROXY[URL_LIST['雲南省公共資源交易中心電子服務系統_政府採購']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_ynsggzxxt_zf)))) # 寫入日誌
time.sleep(10)
TRY_NUM_ynsggzxxt_zf += 1
if TRY_NUM_ynsggzxxt_zf > 5:
TRY_NUM_ynsggzxxt_zf = 1
independent_proxy_engine(URL_LIST['雲南省公共資源交易中心電子服務系統_政府採購'])
ynsggzxxt_zf()
def ynsggzzw_gc():
global TRY_NUM_ynsggzzw_gc
try:
downloader.downloader_ynsggzzw(
URL_LIST['雲南省公共資源交易中心網_工程建設'],
VALID_URL_PROXY[URL_LIST['雲南省公共資源交易中心網_工程建設']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_ynsggzzw_gc)))) # 寫入日誌
time.sleep(10)
TRY_NUM_ynsggzzw_gc += 1
if TRY_NUM_ynsggzzw_gc > 5:
TRY_NUM_ynsggzzw_gc = 1
independent_proxy_engine(URL_LIST['雲南省公共資源交易中心網_工程建設'])
ynsggzzw_gc()
def kmsgg_zf():
global TRY_NUM_kmsgg_zf
try:
downloader.downloader_kmsgg(
URL_LIST['昆明市公共資源交易中心網_政府採購'],
VALID_URL_PROXY[URL_LIST['昆明市公共資源交易中心網_政府採購']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_kmsgg_zf)))) # 寫入日誌
time.sleep(10)
TRY_NUM_kmsgg_zf += 1
if TRY_NUM_kmsgg_zf > 5:
TRY_NUM_kmsgg_zf = 1
independent_proxy_engine(URL_LIST['昆明市公共資源交易中心網_政府採購'])
kmsgg_zf()
def kmsgg_gc():
global TRY_NUM_kmsgg_gc
try:
downloader.downloader_kmsgg_gc(
URL_LIST['昆明市公共資源交易中心網_工程建設'],
VALID_URL_PROXY[URL_LIST['昆明市公共資源交易中心網_工程建設']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_kmsgg_gc)))) # 寫入日誌
time.sleep(10)
TRY_NUM_kmsgg_gc += 1
if TRY_NUM_kmsgg_gc > 5:
TRY_NUM_kmsgg_gc = 1
independent_proxy_engine(URL_LIST['昆明市公共資源交易中心網_工程建設'])
kmsgg_gc()
def ynszfcgw():
global TRY_NUM_ynszfcgw
try:
downloader.downloader_ynszfcgw(
URL_LIST['雲南省政府採購網'],
VALID_URL_PROXY[URL_LIST['雲南省政府採購網']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_ynszfcgw)))) # 寫入日誌
time.sleep(10)
TRY_NUM_ynszfcgw += 1
if TRY_NUM_ynszfcgw > 5:
TRY_NUM_ynszfcgw = 1
independent_proxy_engine(URL_LIST['雲南省政府採購網'])
ynszfcgw()
#### 中標資訊 ####
def ynsggzxxt_gc_zb():
global TRY_NUM_ynsggzxxt_gc_zb
try:
downloader.downloader_ynsggzxxt_gc_zb(
URL_LIST_ZB['雲南省公共資源交易資訊網_工程建設_中標公告'],
VALID_URL_PROXY[URL_LIST_ZB['雲南省公共資源交易資訊網_工程建設_中標公告']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_ynsggzxxt_gc_zb)))) # 寫入日誌
time.sleep(10)
TRY_NUM_ynsggzxxt_gc_zb += 1
if TRY_NUM_ynsggzxxt_gc_zb > 5:
TRY_NUM_ynsggzxxt_gc_zb = 1
independent_proxy_engine(URL_LIST['雲南省公共資源交易資訊網_工程建設_中標公告'])
ynsggzxxt_gc_zb()
def ynsggzxxt_zf_zb():
global TRY_NUM_ynsggzxxt_zf_zb
try:
downloader.downloader_ynsggzxxt_zf_zb(
URL_LIST_ZB['雲南省公共資源交易資訊網_政府採購_中標結果'],
VALID_URL_PROXY[URL_LIST_ZB['雲南省公共資源交易資訊網_政府採購_中標結果']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_ynsggzxxt_zf_zb)))) # 寫入日誌
time.sleep(10)
TRY_NUM_ynsggzxxt_zf_zb += 1
if TRY_NUM_ynsggzxxt_zf_zb > 5:
TRY_NUM_ynsggzxxt_zf_zb = 1
independent_proxy_engine(URL_LIST['雲南省公共資源交易資訊網_政府採購_中標結果'])
ynsggzxxt_zf_zb()
def ynsggzzw_gc_zb():
global TRY_NUM_ynsggzzw_gc_zb
try:
downloader.downloader_ynsggzzw_gc_zb(
URL_LIST_ZB['雲南省公共資源交易中心_工程建設_中標結果'],
VALID_URL_PROXY[URL_LIST_ZB['雲南省公共資源交易中心_工程建設_中標結果']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_ynsggzzw_gc_zb)))) # 寫入日誌
time.sleep(10)
TRY_NUM_ynsggzzw_gc_zb += 1
if TRY_NUM_ynsggzzw_gc_zb > 5:
TRY_NUM_ynsggzzw_gc_zb = 1
independent_proxy_engine(URL_LIST['雲南省公共資源交易中心_工程建設_中標結果'])
ynsggzzw_gc_zb()
def ynsggzzw_zf_zb():
global TRY_NUM_ynsggzzw_zf_zb
try:
downloader.downloader_ynsggzzw_zf_zb(
URL_LIST_ZB['雲南省公共資源交易中心_政府採購_結果公示'],
VALID_URL_PROXY[URL_LIST_ZB['雲南省公共資源交易中心_政府採購_結果公示']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_ynsggzzw_zf_zb)))) # 寫入日誌
time.sleep(10)
TRY_NUM_ynsggzzw_zf_zb += 1
if TRY_NUM_ynsggzzw_zf_zb > 5:
TRY_NUM_ynsggzzw_zf_zb = 1
independent_proxy_engine(URL_LIST['雲南省公共資源交易中心_政府採購_結果公示'])
ynsggzzw_zf_zb()
def kmsgg_gc_zb():
global TRY_NUM_kmsgg_gc_zb
try:
downloader.downloader_kmsgg_gc_zb(
URL_LIST_ZB['昆明市公共資源交易平臺公共服務系統_工程建設_中標結果公示'],
VALID_URL_PROXY[URL_LIST_ZB['昆明市公共資源交易平臺公共服務系統_工程建設_中標結果公示']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_kmsgg_gc_zb)))) # 寫入日誌
time.sleep(10)
TRY_NUM_kmsgg_gc_zb += 1
if TRY_NUM_kmsgg_gc_zb > 5:
TRY_NUM_kmsgg_gc_zb = 1
independent_proxy_engine(URL_LIST['昆明市公共資源交易平臺公共服務系統_工程建設_中標結果公示'])
kmsgg_gc_zb()
def kmsgg_zf_zb():
global TRY_NUM_kmsgg_zf_zb
try:
downloader.downloader_kmsgg_zf_zb(
URL_LIST_ZB['昆明市公共資源交易平臺公共服務系統_政府採購_結果公示'],
VALID_URL_PROXY[URL_LIST_ZB['昆明市公共資源交易平臺公共服務系統_政府採購_結果公示']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_kmsgg_zf_zb)))) # 寫入日誌
time.sleep(10)
TRY_NUM_kmsgg_zf_zb += 1
if TRY_NUM_kmsgg_zf_zb > 5:
TRY_NUM_kmsgg_zf_zb = 1
independent_proxy_engine(URL_LIST['昆明市公共資源交易平臺公共服務系統_政府採購_結果公示'])
kmsgg_zf_zb()
def kmsgg_gc_by():
global TRY_NUM_kmsgg_gc_by
try:
downloader.downloader_kmsgg_gc_by(
URL_LIST_ZB['昆明市公共資源交易平臺公共服務系統_工程建設_補遺通知'],
VALID_URL_PROXY[URL_LIST_ZB['昆明市公共資源交易平臺公共服務系統_工程建設_補遺通知']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_kmsgg_gc_by)))) # 寫入日誌
time.sleep(10)
TRY_NUM_kmsgg_gc_by += 1
if TRY_NUM_kmsgg_gc_by > 5:
TRY_NUM_kmsgg_gc_by = 1
independent_proxy_engine(URL_LIST['昆明市公共資源交易平臺公共服務系統_工程建設_補遺通知'])
kmsgg_gc_by()
def kmsgg_zf_by():
global TRY_NUM_kmsgg_zf_by
try:
downloader.downloader_kmsgg_zf_by(
URL_LIST_ZB['昆明市公共資源交易平臺公共服務系統_政府採購_補遺通知'],
VALID_URL_PROXY[URL_LIST_ZB['昆明市公共資源交易平臺公共服務系統_政府採購_補遺通知']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_kmsgg_zf_by)))) # 寫入日誌
time.sleep(10)
TRY_NUM_kmsgg_zf_by += 1
if TRY_NUM_kmsgg_zf_by > 5:
TRY_NUM_kmsgg_zf_by = 1
independent_proxy_engine(URL_LIST['昆明市公共資源交易平臺公共服務系統_政府採購_補遺通知'])
kmsgg_zf_by()
def ynszfcgw_cg():
global TRY_NUM_ynszfcgw_cg
try:
downloader.downloader_ynszfcgw_cg(
URL_LIST_ZB['雲南省政府採購網_採購結果'],
VALID_URL_PROXY[URL_LIST_ZB['雲南省政府採購網_採購結果']])
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOG.error("[-] {0}".format(str("Trying times: {0}".format(TRY_NUM_ynszfcgw_cg)))) # 寫入日誌
time.sleep(10)
TRY_NUM_ynszfcgw_cg += 1
if TRY_NUM_ynszfcgw_cg > 5:
TRY_NUM_ynszfcgw_cg = 1
independent_proxy_engine(URL_LIST['雲南省政府採購網_採購結果'])
ynszfcgw_cg()
global LOGIC_DB_DISPOSE
LOG.info("[+] 抓取資料")
print("[*] 開始抓取招投標資訊..")
#### 招投標資訊 ####
ynsggzxxt_gc()
ynsggzxxt_zf()
ynsggzzw_gc()
kmsgg_zf()
kmsgg_gc()
ynszfcgw()
print("[*] 開始抓取中標資訊..")
#### 中標資訊 ####
ynsggzxxt_gc_zb()
ynsggzxxt_zf_zb()
ynsggzzw_gc_zb()
ynsggzzw_zf_zb()
kmsgg_gc_zb()
kmsgg_zf_zb()
kmsgg_gc_by()
kmsgg_zf_by()
ynszfcgw_cg()
LOG.info("[+] 抓取完成")
# del downloader
gc.collect()
LOGIC_DB_DISPOSE = True
def db_engine():
'''
資料庫引擎
'''
LOG.info("[*] 開始執行資料庫引擎")
# 建立資料處理物件
#### 招投標資料 ####
ynsggzxxt = dataDisposer.DataStore('ynsggzxxt')
ynsggzzw = dataDisposer.DataStore('ynsggzzw')
kmsgg = dataDisposer.DataStore('kmsgg')
kmsgg_gc = dataDisposer.DataStore('kmsgg_gc')
ynsggzxxt_zf = dataDisposer.DataStore('ynsggzxxt_zf')
ynszfcgw = dataDisposer.DataStore('ynszfcgw')
#### 中標資料 ####
ynsggzxxt_gc_zb = dataDisposer.DataStore('ynsggzxxt_gc_zb')
ynsggzxxt_zf_zb = dataDisposer.DataStore('ynsggzxxt_zf_zb')
ynsggzzw_gc_zb = dataDisposer.DataStore('ynsggzzw_gc_zb')
ynsggzzw_zf_zb = dataDisposer.DataStore('ynsggzzw_zf_zb')
kmsgg_gc_zb = dataDisposer.DataStore('kmsgg_gc_zb')
kmsgg_zf_zb = dataDisposer.DataStore('kmsgg_zf_zb')
kmsgg_gc_by = dataDisposer.DataStore('kmsgg_gc_by')
kmsgg_zf_by = dataDisposer.DataStore('kmsgg_zf_by')
ynszfcgw_cg = dataDisposer.DataStore('ynszfcgw_cg')
global LOGIC_DATA_PUSH
try:
LOG.info("[+] 資料庫處理中")
#### 資料操作 ####
## 招投標資料 ##
## 雲南省公共資源交易中心電子服務系統
ynsggzxxt.clean_data(['公告標題', '專案編號']) # 資料清洗(去重)
ynsggzxxt.update_date_by_time('截止時間') # 資料更新(時間)
ynsggzxxt.delete_none_data()
## 雲南省公共資源交易中心網(舊)
ynsggzzw.clean_data(['公告標題', '專案編號']) # 資料清洗(去重)
ynsggzzw.delete_none_data()
## 昆明市公共資源交易中心網
kmsgg.clean_data(['編號', '工程名稱']) # 資料清洗(去重)
kmsgg.update_date_by_time("結束時間") # 資料更新(時間)
kmsgg.delete_none_data()
## 昆明市公共資源交易中心網_工程
kmsgg_gc.clean_data(['編號', '工程名稱']) # 資料清洗(去重)
kmsgg_gc.update_date_by_time("結束時間") # 資料更新(時間)
kmsgg_gc.delete_none_data()
## 雲南省公共資源交易中心電子服務系統_政府
ynsggzxxt_zf.clean_data(['公告標題', '專案編號']) # 資料清洗(去重)
ynsggzxxt_zf.update_date_by_time('截止時間') # 資料更新(時間)
ynsggzxxt_zf.delete_none_data()
## 雲南省政府採購網
ynszfcgw.clean_data(['編號', '工程名稱']) # 資料清洗(去重)
ynszfcgw.delete_none_data()
## 中標資料 ##
# 雲南省公共資源交易資訊網_工程建設_中標公告
ynsggzxxt_gc_zb.clean_data(['專案名稱', '釋出時間'])
ynsggzxxt_gc_zb.delete_none_data()
# 雲南省公共資源交易資訊網_政府採購_中標結果
ynsggzxxt_zf_zb.clean_data(['專案名稱', '釋出時間'])
ynsggzxxt_zf_zb.delete_none_data()
# 雲南省公共資源交易中心_工程建設_中標結果
ynsggzzw_gc_zb.clean_data(['公告標題', '釋出時間'])
ynsggzzw_gc_zb.delete_none_data()
# 雲南省公共資源交易中心_政府採購_結果公示
ynsggzzw_zf_zb.clean_data(['公告標題', '釋出時間'])
ynsggzzw_zf_zb.delete_none_data()
# 昆明市公共資源交易平臺公共服務系統_工程建設_中標結果公示
kmsgg_gc_zb.clean_data(['編號', '工程名稱'])
kmsgg_gc_zb.delete_none_data()
# 昆明市公共資源交易平臺公共服務系統_政府採購_結果公示
kmsgg_zf_zb.clean_data(['編號', '工程名稱'])
kmsgg_zf_zb.delete_none_data()
# 昆明市公共資源交易平臺公共服務系統_工程建設_補遺通知
kmsgg_gc_by.clean_data(['編號', '工程名稱'])
kmsgg_gc_by.delete_none_data()
# 昆明市公共資源交易平臺公共服務系統_政府採購_補遺通知
kmsgg_zf_by.clean_data(['編號', '工程名稱'])
kmsgg_zf_by.delete_none_data()
# 雲南省政府採購網_採購結果
ynszfcgw_cg.clean_data(['編號', '工程名稱'])
ynszfcgw_cg.delete_none_data()
##################
LOG.info("[+] 資料庫處理完成")
LOGIC_DATA_PUSH = True
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
LOGIC_DATA_PUSH = False
finally:
# 刪除物件,釋放記憶體
del ynsggzxxt, ynsggzzw, kmsgg #, ynsggzxxt_zb, ynsggzzw_zb, ynstz_zb, kmsgg_zb
gc.collect()
def data_push_engine():
'''
資料推送引擎
:return:
'''
LOG.info("[*] 開始執行資料推送引擎")
#### 初始化資料寫入模組 ####
writer = dataPusher.DataWrite()
html_push = dataPush_HTML.HTML_Content()
# 雲南省公共資源交易中心電子服務系統 'ynsggzxxt'
# 雲南省公共資源交易中心電子服務系統_政府採購 'ynsggzxxt_zf'
# 雲南省公共資源交易中心網 'ynsggzzw'
# 昆明市公共資源交易中心網 'kmsgg'
# 昆明市公共資源交易中心網_工程建設 'kmsgg_gc'
# 雲南省政府採購網 'ynszfcgw'
# table_name = ['ynsggzxxt', 'ynsggzzw', 'kmsgg', 'kmsgg_gc', 'ynsggzxxt_zf', 'ynszfcgw', ] #'ynsggzxxt_zb', 'ynsggzzw_zb', 'ynstz_zb', 'kmsgg_zb']
list_file_path = []
try:
#----------- 舊方法 -----------#
# # 遍歷表
# for table in table_name:
# list_data = get_data(table)
# header_data = configManager.excel_header_data[table]
# # header_data_zb = configManager.excel_header_data_zb[table]
#
# # 讀取關鍵詞檔案並生成關鍵字列表
# with open(r".\keyword_file\keyword.txt", 'r') as f:
# line = f.read()
# if line not in KEY_WORD:
# KEY_WORD.append(line)
# key_word = str(KEY_WORD[0]).split('\n')
#
# # 篩選關鍵詞資訊
# list_data_parse = []
# for data in list_data:
# for key in key_word:
# # 獲取每張表對應的標題欄位並判斷是否包含關鍵詞資訊
# if key in data[TABLE_TITLE[table]] and data not in list_data_parse:
# list_data_parse.append(data)
#
# # 判斷當天資料是否為空
# # 寫入兩個 excel 文字(招投標)
# if len(list_data) != 0:
# file_path = writer.excel_write(
# excel_sheet_name=configManager.excel_data_name[table],
# excel_head_data=header_data,
# excel_data=list_data,
# logic_file_type=0
# )
#
# if len(list_data_parse) != 0:
# file_path_parse = writer.excel_write_parse(
# excel_sheet_name=configManager.excel_data_name[table],
# excel_head_data=header_data,
# excel_data=list_data_parse,
# logic_file_type=1
# )
#
# # 寫入兩個 excel 文字(中標)
# # file_path_zb = writer.excel_write(excel_sheet_name=configManager.excel_data_name_zb[table], excel_head_data=header_data_zb, excel_data=dict_data, logic_file_type=2)
# # file_path_parse_zb = writer.excel_write(excel_sheet_name=configManager.excel_data_name_zb[table], excel_head_data=header_data_zb, excel_data=dict_data_parse, logic_file_type=3)
# ---------------------------#
LOG.info("[+] 正在寫入檔案...")
file_path = html_push.html_write(
title="招投標資訊",
name="今日份的招投標檔案",
dict_html_data_name=configManager.ztb_data_name,
logic_file_type=0
)
file_path_parse = html_push.html_write_keywords(
title="招投標資訊",
name="今日份的招投標檔案(關鍵詞篩選)",
dict_html_data_name=configManager.ztb_data_name,
logic_file_type=1
)
file_path_zb = html_push.html_write(
title="中標資訊",
name="今日份的中標檔案",
dict_html_data_name=configManager.zb_data_name,
logic_file_type=2
)
file_path_parse_zb = html_push.html_write_keywords(
title="中標資訊",
name="今日份的中標檔案(關鍵詞篩選)",
dict_html_data_name=configManager.zb_data_name,
logic_file_type=3
)
# 遍歷路徑新增到路徑列表中
if file_path != "":
if file_path not in list_file_path:
list_file_path.append(file_path)
if file_path_parse != "":
if file_path_parse not in list_file_path:
list_file_path.append(file_path_parse)
if file_path_zb != "":
if file_path_zb not in list_file_path:
list_file_path.append(file_path_zb)
if file_path_parse_zb != "":
if file_path_parse_zb not in list_file_path:
list_file_path.append(file_path_parse_zb)
LOG.info("[+] 寫入完成")
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
finally:
# 刪除物件,釋放記憶體
del writer
gc.collect()
#### 初始化資料推送模組 ####
LOG.info("[+] 正在推送資料...")
pusher = dataPusher.DataSend()
try:
if len(list_file_path) != 0:
content = """
自動化爬蟲
版本:5.1
當前時間:{0}
開發語言:Python 2.7
資料庫:MongoDB 3.6.5
平臺:Windows Server 2012 Data Center
版本更新:
1.優化了爬取演算法,提高了推送成功率,出現斷電的情況會進行補充推送。
如有任何問題和建議,請聯絡開發者: [email protected]
""".format(dataDisposer.current_time())
else:
content = """
爬蟲提示:今天沒有推送的資料哦
自動化爬蟲
版本:5.1
當前時間:{0}
開發語言:Python 2.7
資料庫:MongoDB 3.6.5
平臺:Windows Server 2012 Data Center
版本更新:
1.優化了爬取演算法,提高了推送成功率,出現斷電的情況會進行補充推送。
如有任何問題和建議,請聯絡開發者: [email protected]
""".format(dataDisposer.current_time())
global LOGIC_PUSH_DONE
# 將附件新增到文字中
if pusher.send_mail(content, list_file_path):
LOGIC_PUSH_DONE = True
else:
LOGIC_PUSH_DONE = False
LOG.info("[+] 推送完成")
log_record.log_recorder(LOG_TIME, "執行成功")
except Exception, e:
LOG.error("[-] {0}".format(str(e.message))) # 寫入日誌
log_record.log_recorder(LOG_TIME, "執行失敗")
finally:
# 刪除物件,釋放記憶體
del pusher
gc.collect()
def get_data(table_name):
'''
資料獲取函式
:param table_name: 表名
:return: 返回資料列表
'''
tenderTable = TENDER_TABLE[table_name]
# 獲取今日資料
list_data = list(tenderTable.find(
{
'釋出時間': {"$gte": TODAY_TIME},
'推送': False
})
)
tenderTable.update(
{'推送': False},
{'$set': {'推送': True}},
multi=True,
upsert=True
)
return list_data
def current_time_parse():
'''
獲取當前時間,返回小時和分鐘
:return: 當前小時和分鐘
'''
current_date = dataDisposer.current_time()
current_hour = current_date.hour
current_minute = current_date.minute
return current_hour, current_minute
######## Main Function ########
def main():
print("-" * 40)
print("[*] 開始執行爬蟲程式")
print("[+] 版本:5.1")
print("-" * 40)
time.sleep(2)
# 驗證代理和網頁請求返回值
authentication_engine()
# 如果驗證執行完畢,開始執行網頁引擎
if LOGIC_EXECUTE:
page_engine()
# 如果網頁引擎執行完畢,開始執行資料庫引擎
if LOGIC_DB_DISPOSE:
db_engine()
# 如果資料庫引擎執行完畢,開始執行資料推送引擎
if LOGIC_DATA_PUSH:
data_push_engine()
# 如果資料推送引擎執行完畢,則關閉整個引擎
if LOGIC_PUSH_DONE:
print("[+] 爬蟲執行完成,引擎關閉")
######## Start Execute ########
if __name__ == "__main__":
start = time.clock()
main()
end = time.clock()
print ("[+] 執行消耗時長:{0}".format(end - start))