【寫在前面】
其實簡單的爬蟲,只要自己親手編寫過一次代碼,基本就能上手,如果有不懂的可以私聊我。因爲爬蟲流程和解析都是有流程可依,那麼爲什麼今天我還敢再發一次爬蟲的文章呢?哈哈,那自然是因爲除了爬蟲外,還有新知識,比如預測下一期雙色球的“十殺九取”紅(藍)球技戰法,再加上我最想記錄的python-GUI製作。GUI製作,GUI製作,GUI製作,重要的內容說三次!
越是學習python,越是覺得萬能,就像王者榮耀裏的亞瑟。可上單,可輔助,可打野;進可取後排ADC狗頭,退可守己方大哥carry。咳咳,說的有點遠了,下面開始正文。
【示例代碼】
本次代碼其實有4個py,一個是模擬request請求的getheader,一個是雙色球爬取歷史各期的中獎紅藍球號,一個是根據歷史紅藍球的算法預測同,最後一個是GUI製作。由於getheader()方法我本身就是參考了其他大神的內容,而且在第一篇《獲取杭州天氣》的文章中應當附了代碼,因此我就不再重複浪費大家的時間。
1、雙色球 爬取歷史號碼的代碼如下,虛假的“主函數”:
# coding=utf-8
# @Auther : "鵬哥賊優秀"
# @Date : 2019/7/31
# @Software : PyCharm
import requests
from bs4 import BeautifulSoup
import getheader
import my_GUI
import sys
def getballs():
url = "http://datachart.500.com/ssq/?expect=100&from=&to=&sort=1"
headers = getheader.getheaders()
r = requests.get(url, headers=headers)
r.encoding = 'utf-8'
soup = BeautifulSoup(r.text, "lxml")
periods = soup.find_all('td', align="center")
redballs = soup.find_all('td', class_="chartBall01")
blueballs = soup.find_all('td', class_="chartBall02")
periodlist = [i.string for i in periods if i.string]
redballlist = [int(i.string) for i in redballs]
blueballlist = [int(i.string) for i in blueballs]
periodnum = len(blueballlist)
return periodlist[:periodnum], redballlist, blueballlist, periodnum
if __name__ == "__main__":
periodlist, redballlist, blueballlist, periodnum = getballs()
nextperiodnum = int(periodlist[-1]) + 1
# 以下GUI顯示的代碼
app = my_GUI.QtWidgets.QApplication(sys.argv)
Dialog = my_GUI.QtWidgets.QDialog()
ui = my_GUI.Ui_Dialog(redballlist,blueballlist,periodlist)
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec())
2、GUI製作 ,敲黑板,本次文章的重點!
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '1.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import method
class Ui_Dialog(object):
def __init__(self,redballlist,blueballlist,periodlist):
self.redballlist = redballlist
self.blueballlist = blueballlist
self.periodlist = periodlist
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(502, 383)
self.comboBox = QtWidgets.QComboBox(Dialog)
self.comboBox.setGeometry(QtCore.QRect(60, 70, 161, 31))
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
for i in self.periodlist:
self.comboBox.addItem(i)
self.plainTextEdit = QtWidgets.QPlainTextEdit(Dialog)
self.plainTextEdit.setGeometry(QtCore.QRect(50, 170, 421, 41))
self.plainTextEdit.setStyleSheet("font: 12pt \"黑體\";")
self.plainTextEdit.setObjectName("plainTextEdit")
self.plainTextEdit_2 = QtWidgets.QPlainTextEdit(Dialog)
self.plainTextEdit_2.setGeometry(QtCore.QRect(50, 270, 421, 41))
self.plainTextEdit_2.setStyleSheet("font: 12pt \"黑體\";")
self.plainTextEdit_2.setObjectName("plainTextEdit_2")
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setGeometry(QtCore.QRect(60, 140, 181, 21))
self.label_2.setStyleSheet("font: 12pt \"黑體\";\n"
"background-color: rgb(0, 255, 127);\n"
"color: rgb(85, 0, 255);")
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setGeometry(QtCore.QRect(60, 35, 131, 21))
self.label_3.setStyleSheet("font: 12pt \"黑體\";\n"
"font: 75 14pt \"Aharoni\";\n"
"background-color: rgb(255, 0, 0);\n"
"color: rgb(0, 0, 0);")
self.label_3.setObjectName("label_3")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(380, 70, 75, 31))
self.pushButton.setStyleSheet("font: 14pt \"黑體\";\n"
"background-color: rgb(0, 255, 0);")
self.pushButton.setObjectName("pushButton")
self.label_4 = QtWidgets.QLabel(Dialog)
self.label_4.setGeometry(QtCore.QRect(60, 230, 181, 21))
self.label_4.setStyleSheet("font: 12pt \"黑體\";\n"
"background-color: rgb(0, 255, 127);\n"
"color: rgb(85, 0, 255);")
self.label_4.setObjectName("label_4")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "雙色球預期GUI"))
self.label_2.setText(_translate("Dialog", "下一期殺掉的紅球數字是:"))
self.label_3.setText(_translate("Dialog", "雙色球期數:"))
self.pushButton.setText(_translate("Dialog", "確認"))
self.label_4.setText(_translate("Dialog", "下一期殺掉的藍球數字是:"))
self.pushButton.clicked.connect(self.clickok)
def clickok(self):
periodnum = self.comboBox.currentText()
num = self.periodlist.index(periodnum)+1
delrednum = method.DelRedNum(self.redballlist[:6*num], self.blueballlist[:num])
delbullnum = method.DelBlueNum(self.blueballlist[:num])
redresult = ",".join([str(i) for i in delrednum])
blueresult = ",".join([str(i) for i in delbullnum])
self.plainTextEdit.setPlainText(redresult)
self.plainTextEdit_2.setPlainText(blueresult)
【效果如下】
也就是說本週末19090期雙色球,將不會開出“6,10,14,15,18,19,20”的紅球,“2,4,8,10,13”的藍球。
【知識點】
1、python爬蟲。
就像開篇說的,如果是那些簡單的網站,即沒反爬蟲的話,我們處理數據是很簡單,但是如果網站做了反爬蟲,那就麻煩了,需要反解碼。另外,反爬蟲是什麼樣的呢?下面請聽我細細道來。
正常容易爬蟲的網站,響應是這樣的:
通過網頁F12抓包,就能在響應中找到你想要的內容,這就說明這個網站容易爬取,也說明這個網站 的開發技術不怎麼樣,估計是個實習生開發的。
那反爬蟲的網站是怎麼樣的?下面以哪兒網爲例,我在界面明確能搜索到杭州到銀川的航班呢(爲什麼是銀川呢?因爲那有個小夥)
剛開始爬蟲去哪兒時,我就不理解,爲什麼會看找不到航班信息。然後突然想到不會是遇到反爬蟲了吧?仔細看以上響應,會發現有些內容很像base64編碼過的樣子,如下:
<script>var _0x4d88=['Gi3DlRTCiw==','wrDDucOUUio=','w7cKw5xxJg==','XMOowr3Dg8OZ','wocVAzAJ','L8OdB8OTfQ==','wqbCmz5vaw==','asOxw4xsYQ==','w57CpXPDqjU=','WiBMwoIv','Kgj
然後再仔細看,發現這些信息後有一句return _0x3a5b12?decodeURIComponent(_0x3a5b12[0x1]):undefined;}}。這就證明了網站的確進行了對信息的加密。這也是有效防止各類搶票軟件的方法之一。由於本人當前學藝不精,對這種加密代碼完全不知道怎麼解碼(應該是和最後一串八進制有關,而不是簡單的base64加密),因此就放棄了。
2、GUI製作
以前我以爲GUI這種界面應該是JAVA之外的語言才能玩的,沒想到python用起來也是如此方便。
下面簡單講下python GUI製作的幾個學習過程:
(1)砍柴前必須有把柴刀,所以你要下載GUI製作的python庫。我這 邊 用的是pyqt5、pyqt5-tools這兩個庫。下完後還需要在pycharm平臺上配置。what!?還 要配置?是的,因爲這兩個庫不同於其他wordcloud、request等,裝了直接用。
具體配置pycharm和pyqt5的方法,百度下就有很多帖子,可參考:
https://www.cnblogs.com/BlueSkyyj/p/8398277.html
(2)用python實現GUI界面有兩種方法,一種是依賴於Qt Designer圖形化界面,一種當然是大神類的直接敲代碼了。
Qt Designer界面如下:
其實,在玩QT時,我就覺得又在學習一個新的軟件了。是的,新的界面,新的功能,的確在python學習成長之路上每遇到新技巧,都是需要重新學習,但不要因此打退堂鼓。以不退的痛苦,換有所成長。
關於圖形化界面,我就不介紹了,每個按鈕、選項多點點,拖拖,玩着玩着就知道是幹嘛用的了。
(3)在用QT打好GUI的控件佈局後,開始真正的python GUI代碼編寫了。
示例代碼中主要用到4個控件,comboBox(下拉條)、plainTextEdit(文本框)、label(標籤)、pushButton(點擊按鈕),當然還有列表框、線條、撥號按鈕等。因爲示例代碼中沒用到,我就不引申了,用到了再學唄。
針對以上控件,方法如下:
setObjectName:設置控件名稱,通用
setGeometry:設置座標,通用
setStyleSheet:設置控件樣式、字體,通用
setWindowTitle:設置主窗口標題
setTips:設置Tips提示,通用
setText、setHtml:設置控件內容,但 是對plainTextEdit無用
setplainText:是針對plainTextEdit控件的設置內容方法
clicked:針對pushbutton控件的點擊方法
currentText:獲取下拉條的當前內容
(4)程序顯示GUI界面:
# GUI顯示
app = my_GUI.QtWidgets.QApplication(sys.argv)
Dialog = my_GUI.QtWidgets.QDialog()
ui = my_GUI.Ui_Dialog(redballlist,blueballlist,periodlist)
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec())
先聲明一個app實例,用於系統執行app.exec();再把GUI製作的類以ui實例化進行展示。不懂也沒事,按流程走就行,反正我也不是很懂,哈哈!
【寫在最後】
咦,是不是漏了一個章節,就是標題中霸氣側漏的“十殺九取”技戰法介紹?哈哈,是的,我故意不寫的,這麼寶貴的方法怎能輕易共享?因爲我花了十分鐘從百度裏搜出來的。沒有天才之資,想輕鬆寫個代碼就預測準確下一期的號碼,未免有點癡人說夢了。歷來那麼多的數學家都無法預測的東西,我肯定是沒那個本事了。不過說實話,我統計了代碼中的算法,準確率大概是70%左右,因此就寫了個文章,記錄下python GUI製作的方法,同時博大家一笑。
【自我推薦】
如果大家覺得有所幫助或者想一起學習,可以關注我的公衆號“鵬哥賊優秀”,謝謝大家!