pyqt5=Python+ qt,这块的资料现在慢慢多起来了,这里给大家送一个小的demo用来练手。
里面技术点:
1)控件 Pushbutton的使用;
2)pyqt5线程的用法;
3)界面和逻辑分离;
4)pyqt5 控制台日志重定向到editText控件中;这块比较有意思,大家可以学学;
界面如下:
另外打个广告:这段时间闲着没事,自己弄了个淘客网站。领取天猫淘宝优惠券的,和一般的找券网不同,采集下来的天猫淘宝产品都是经过我的大数据模型筛选的,希望大家帮忙测试下,网页右上角有安卓app下载。
网站链接:http://www.0k8gj.cn/
接下来是正题:
一共四个文件,大家可以分别拷贝到自己工程里面调试一下,可以直接运行:
work.py
# -*- coding: utf-8 -*-
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
from ui_main import Ui_MainWindow
import threading
import time
import os
import inspect
import ctypes
import re
from tools import *
from douyin import *
gMaxThreadNum = 2 # 最大线程数目
gWorkingThreadNum = 0
gThreadsList = [] #存放线程ID
gThreadLock = threading.Lock() #获取发帖内容时,需要加锁
gTotalLink = []
gThreadCountLock = threading.Lock()
#@函数介绍:启动多个线程进行发帖
#@返回值: True/False
#@data: 20180803
def mainTask():
global gMaxThreadNum #最大线程个数
global gWorkingThreadNum #正在运行的工作线程的个数
global gThreadCountLock #全局锁
global gTotalLink
gWorkingThreadNum = 0
ipublishIndex = 1
while True:
if gWorkingThreadNum < gMaxThreadNum:
if ipublishIndex > len(gTotalLink):
printStr('所有任务完成,等待各个子线程完成后,退出........')
break;
ipublishIndex = ipublishIndex +1
#启动一个线程
t = threading.Thread(target=workThread)
t.start()
gThreadsList.append(t)
gThreadCountLock.acquire()
gWorkingThreadNum = gWorkingThreadNum +1
gThreadCountLock.release()
time.sleep(0.1)
return True
#@函数介绍: 退出线程
#@返回值: true/false, 成功/失败
#@data: 20180806
def stop_thread(thread):
tid = thread.ident
exctype = SystemExit
ret = True
"""raises the exception, performs cleanup if needed"""
tid = ctypes.c_long(tid)
if not inspect.isclass(exctype):
exctype = type(exctype)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
if res == 0:
ret = False
#raise ValueError("invalid thread id")
strs = '%s子线程已经退出'%tid
printStr(strs)
elif res != 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ret = False
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
else:
ret = True
strs = '%s 线程被Kill'%tid
printStr(strs)
return ret
def workThread():
global gTotalLink
global gThreadLock
global gWorkingThreadNum
gThreadCountLock.acquire()
video_url = gTotalLink.pop()
gThreadCountLock.release()
printStr('video_url:%s'%video_url)
#video_url = 'http://v.douyin.com/dU2Dsn/'
handle = douyin()
downloadUrl , name = handle.downloadUrlGet(video_url)
if True == os.path.exists(name+'.mp4'):
name = name + str(randomInt(2))+'.mp4'
handle.video_downloader(downloadUrl, name+'.mp4')
gThreadCountLock.acquire()
gWorkingThreadNum = gWorkingThreadNum +1
gThreadCountLock.release()
class EmittingStream(QObject):
textWritten = pyqtSignal(str) #定义一个发送str的信号
def write(self, text):
self.textWritten.emit(str(text))
#@类介绍:主类
#@返回值:
#@data: 20180801
class mainForm(QMainWindow, Ui_MainWindow):
def __init__(self):
super(mainForm, self).__init__()
self.setupUi(self)
#self.setWindowFlags(Qt.WindowMinimizeButtonHint)
#禁止调整窗口大小
self.setFixedWidth(848)
self.setFixedHeight(588)
#信号槽,点击开始会去连接startTask
self.pushButton_startRun.clicked.connect(self.startTask)
#信号槽,暂停
self.pushButton_stopRun.clicked.connect(self.stopTask)
self.spinBox_maxThreadNum.valueChanged['int'].connect(self.threadNumSet)
#编辑内容
#self.pushButton_editFileContent.clicked.connect(self.editContent)
#下面将输出重定向到textEdit中
sys.stdout = EmittingStream(textWritten=self.outputWritten)
sys.stderr = EmittingStream(textWritten=self.outputWritten)
self.initPara()
#编辑内容
def editContent(self):
dig = QFileDialog()
dig.getOpenFileName(self, 'Open file', '', "")
def initPara(self):
global gTotalLink
file = open('需要下载的的链接.txt', 'a+')
file.close()
#读取内容
file = open('需要下载的的链接.txt', 'r')
strContent = file.read()
file.close()
resultList = re.findall('(?<=###).+?(?=###)', strContent, re.S)
for item in resultList:
if '\n' == item:
pass
else:
p = item.find('http')
item = item[p: item.find(' 复', p)]
if item == '':
continue
gTotalLink.append(item)
printStr('gTotalLink:%s'%gTotalLink)
#@data: 20180801
def startTask(self):
global gThreadsList
if len(gThreadsList) != 0:
for t in gThreadsList:
stop_thread(t)
#运行主任务
printStr('开启工作任务...')
t = threading.Thread(target=mainTask)
t.start()
gThreadsList.append(t)
#@函数介绍: 主函数入口
#@返回值: 无
#@data: 20180801
def stopTask(self):
global gThreadsList
for t in gThreadsList:
stop_thread(t)
#清空gThreadsList
gThreadsList = []
def threadNumSet(self):
global gMaxThreadNum
gMaxThreadNum = self.spinBox_maxThreadNum.value()
printStr('设置参数->线程个数:%s'%gMaxThreadNum)
#@函数介绍:接收信号str的信号槽
#@返回值: 无
#@data: 20180803
def outputWritten(self, text):
self.textEditLog.setReadOnly(True)
cursor = self.textEditLog.textCursor()
cursor.movePosition(QTextCursor.End)
cursor.insertText(text)
self.textEditLog.setTextCursor(cursor)
self.textEditLog.ensureCursorVisible()
if __name__ =="__main__":
app = QApplication(sys.argv)
mainHandle = mainForm()
mainHandle.show()
sys.exit(app.exec())
ui_main.py:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'main.ui'
#
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(815, 588)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tabWidget_fullInterface = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget_fullInterface.setEnabled(True)
self.tabWidget_fullInterface.setGeometry(QtCore.QRect(20, 0, 841, 561))
self.tabWidget_fullInterface.setStyleSheet("font: 12pt \"Arial\";")
self.tabWidget_fullInterface.setObjectName("tabWidget_fullInterface")
self.tab_startInterface = QtWidgets.QWidget()
self.tab_startInterface.setObjectName("tab_startInterface")
self.pushButton_startRun = QtWidgets.QPushButton(self.tab_startInterface)
self.pushButton_startRun.setGeometry(QtCore.QRect(90, 430, 131, 51))
self.pushButton_startRun.setStyleSheet("font: 87 14pt \"Arial\";color: white;background-color: rgb(218,181,150)")
self.pushButton_startRun.setObjectName("pushButton_startRun")
self.label_37 = QtWidgets.QLabel(self.tab_startInterface)
self.label_37.setGeometry(QtCore.QRect(40, 395, 81, 21))
self.label_37.setStyleSheet("color:rgb(255, 0, 0)")
self.label_37.setObjectName("label_37")
self.line_5 = QtWidgets.QFrame(self.tab_startInterface)
self.line_5.setGeometry(QtCore.QRect(10, 485, 821, 41))
self.line_5.setFrameShape(QtWidgets.QFrame.HLine)
self.line_5.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_5.setObjectName("line_5")
self.line_7 = QtWidgets.QFrame(self.tab_startInterface)
self.line_7.setGeometry(QtCore.QRect(120, 390, 711, 31))
self.line_7.setFrameShape(QtWidgets.QFrame.HLine)
self.line_7.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_7.setObjectName("line_7")
self.pushButton_stopRun = QtWidgets.QPushButton(self.tab_startInterface)
self.pushButton_stopRun.setGeometry(QtCore.QRect(290, 430, 131, 51))
self.pushButton_stopRun.setStyleSheet("font: 87 14pt \"Arial\";color: white;background-color: rgb(218,181,150)")
self.pushButton_stopRun.setObjectName("pushButton_stopRun")
self.line_6 = QtWidgets.QFrame(self.tab_startInterface)
self.line_6.setGeometry(QtCore.QRect(-20, 405, 61, 101))
self.line_6.setFrameShape(QtWidgets.QFrame.VLine)
self.line_6.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_6.setObjectName("line_6")
self.line_8 = QtWidgets.QFrame(self.tab_startInterface)
self.line_8.setGeometry(QtCore.QRect(10, 395, 31, 20))
self.line_8.setFrameShape(QtWidgets.QFrame.HLine)
self.line_8.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_8.setObjectName("line_8")
self.line_11 = QtWidgets.QFrame(self.tab_startInterface)
self.line_11.setGeometry(QtCore.QRect(820, 410, 20, 101))
self.line_11.setFrameShape(QtWidgets.QFrame.VLine)
self.line_11.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_11.setObjectName("line_11")
self.spinBox_maxThreadNum = QtWidgets.QSpinBox(self.tab_startInterface)
self.spinBox_maxThreadNum.setGeometry(QtCore.QRect(670, 440, 61, 22))
self.spinBox_maxThreadNum.setMinimum(1)
self.spinBox_maxThreadNum.setMaximum(10)
self.spinBox_maxThreadNum.setProperty("value", 3)
self.spinBox_maxThreadNum.setObjectName("spinBox_maxThreadNum")
self.label_41 = QtWidgets.QLabel(self.tab_startInterface)
self.label_41.setGeometry(QtCore.QRect(580, 440, 81, 21))
self.label_41.setObjectName("label_41")
self.textEditLog = QtWidgets.QTextEdit(self.tab_startInterface)
self.textEditLog.setGeometry(QtCore.QRect(0, 10, 781, 371))
self.textEditLog.setObjectName("textEditLog")
self.tabWidget_fullInterface.addTab(self.tab_startInterface, "")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 815, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.tabWidget_fullInterface.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "抖音短视频下载"))
self.pushButton_startRun.setText(_translate("MainWindow", "开始运行"))
self.label_37.setText(_translate("MainWindow", "运行控制"))
self.pushButton_stopRun.setText(_translate("MainWindow", "停止运行"))
self.label_41.setText(_translate("MainWindow", "线程个数"))
self.tabWidget_fullInterface.setTabText(self.tabWidget_fullInterface.indexOf(self.tab_startInterface), _translate("MainWindow", "启动界面"))
douyin.py:
# -*- coding:utf-8 -*-
from splinter.driver.webdriver.chrome import Options, Chrome
from splinter.browser import Browser
from contextlib import closing
import requests, json, time, re, os, sys
class douyin():
def __init__(self):
pass
"""
视频下载
Parameters:
video_url: 带水印的视频地址
video_name: 视频名
Returns:
无
"""
def video_downloader(self, video_url, video_name=r'douyinsss.mp4'):
size = 0
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.3.2.1000 Chrome/30.0.1599.101 Safari/537.36"}
try:
with closing(requests.get(video_url, headers = headers, stream=True, verify = False)) as response:
chunk_size = 1024
#print(response.text)
content_size = int(response.headers['content-length'])
if response.status_code == 200:
sys.stdout.write(' [文件大小]:%0.2f MB\n' % (content_size / chunk_size / 1024))
"""
with open(video_name, 'ab') as file:
file.write(response.content)
file.flush()
print('receive data,file size : %d total size:%d' % (os.path.getsize(video_name), content_size))
"""
with open(video_name, "wb") as file:
for data in response.iter_content(chunk_size = chunk_size):
file.write(data)
size += len(data)
file.flush()
#sys.stdout.write(' [下载进度]:%.2f%%' % float(size / content_size * 100) + '\r')
#sys.stdout.flush()
print('视频下载完了...')
except Exception as e:
print(e)
print('下载出错啦.....')
"""
视频下载地址获取
Parameters:
video_url: 带水印的视频地址
Returns:
视频下载链接,视频名字
"""
def downloadUrlGet(self, video_url):
name = ''
downloadUrl = ''
headers = {
'Proxy-Connection':'keep-alive',
'Host': 'v.douyin.com',
'Upgrade-Insecure-Requests':'1',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'
}
req = requests.get(url = video_url, headers = headers, verify = False)
newUrl = req.url
#print(req.text)
print('newUrl:%s'%newUrl)
print(req.history)
#302重定向后的请求
headers = {
'Proxy-Connection':'keep-alive',
'Host': 'www.iesdouyin.com',
'Upgrade-Insecure-Requests':'1',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'
}
req = requests.get(url = newUrl, headers = headers, verify = False)
reply = req.text
#print(reply)
p = reply.find('playAddr: "') + len('playAddr: "')
downloadUrl = reply[p: reply.find('"', p)]
print('downloadUrl:%s'%downloadUrl)
p = reply.find('"name nowrap">') + len('"name nowrap">')
name = reply[p: reply.find('<', p)]
print(name)
return downloadUrl, name
url = 'http://v.douyin.com/dU2Dsn/'
handel = douyin()
downloadUrl, name = handel.downloadUrlGet(url)
handel.video_downloader(url, name)
"""
def do_load_media(url, path):
try:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.3.2.1000 Chrome/30.0.1599.101 Safari/537.36"}
pre_content_length = 0
# 循环接收视频数据
while True:
# 若文件已经存在,则断点续传,设置接收来需接收数据的位置
if os.path.exists(path):
headers['Range'] = 'bytes=%d-' % os.path.getsize(path)
res = requests.get(url, stream=True, headers=headers)
content_length = int(res.headers['content-length'])
print(content_length)
# 若当前报文长度小于前次报文长度,或者已接收文件等于当前报文长度,则可以认为视频接收完成
if content_length < pre_content_length or (
os.path.exists(path) and os.path.getsize(path) == content_length):
break
pre_content_length = content_length
# 写入收到的视频数据
with open(path, 'ab') as file:
file.write(res.content)
file.flush()
print('receive data,file size : %d total size:%d' % (os.path.getsize(path), content_length))
except Exception as e:
print(e)
downloadUrl = 'http://www.gifshow.com/s/mDg7eWq9'
path = r'test.mp4'
do_load_media(download_url, path)
"""
这是我自己写的一个工具库,tools.py:
# -*- coding:utf-8 -*-
import requests
import json
import random
import datetime
import os
import time
import hashlib
import string
import base64
import execjs
import re
gIpLink = ''
gDialName = ''
gDialAccount = ''
gDialPasswd =''
openDebug = False
gIpList = []
gStatusCode = ''
gUsername = ''
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/64.0.3282.186 Safari/537.36'}
def dict2proxy(dic):
url = dic['type'] + '://' + dic['ip'] + ':' + str(dic['port'])
return {'http':url, 'https':url}
#@函数介绍: 检验Ip是否是好的
#@返回值: ip是好的/坏的: True/false
#@data: 20180801
def check_ip(ipDict):
try:
proxie = dict2proxy(ipDict)
#printStr(proxie)
if ipDict['type'] == 'https':
url = 'https://www.ipip.net/'
else:
#url = "http://www.discuz.net/forum.php"
url = 'http://www.lvye.cn/'
r = requests.get(url, headers=header, proxies=proxie, timeout=15)
r.raise_for_status()
isOk = True
except Exception as e:
printStr('经过测试IP无效...')
isOk = False
else:
printStrDebug('经过测试,IP有效...')
#printStr(ipDict)
return isOk
#@函数介绍: 获取一个可用的代理Ip
#@返回值: 可用的代理Ip
#@data: 20180801
# freeProxieIpGet()
def getProxieIp():
cycleFlag = True
count = 0
#打开代理ip文件
with open('数据文件夹\proxies.json', 'r') as file:
jsonStr = file.read()
dataList = json.loads(jsonStr) #data 是个list
listLen = len(dataList)
maxCount = listLen + 5
if listLen == 0:
printStr('proxies.json文件中没有可用ip....')
return 'null'
printStr('可用ip个数:%d'%listLen)
#读取dict格式的ip
while cycleFlag == True:
index = random.randint(0, listLen-1) #随机生成一个Ip
printStr('随机生成第%d个ip'%index)
ipDict = dataList[index]
flag = check_ip(ipDict)
if flag == True:
cycleFlag = False
if count > maxCount: #如果循环次数超过maxCount次,则暂停循环
cycleFlag = False
ipDict = 'null'
count = count + 1
return ipDict
#@函数介绍: 格式化打印输出
#@返回值: 无
#@data: 20180807
def printStr(str):
nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')#现在
print('[%s]>>>>%s'%(nowTime, str))
def printStrDebug(str):
if openDebug == True:
nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')#现在
print('[%s]>>>>%s'%(nowTime, str))
else:
pass
#@函数介绍: 检测代理IP地址 全局变量是否已经设置
#@返回值: True/False
#@data: 20180810 stefan1240
def payPorxieIpSettingCheck():
global gIpLink
if gIpLink == '':
return False
else:
return True
#功能未完成
def payPorxieIpLinkMake(httpType):
if gIpLink == '':
printStr('IP代理链接为空...')
return 'null'
#@函数介绍: 付费代理Ip池清零
#@返回值:无
#@data: 20180813,stefan1240
def payProxieIpsClear():
global gIpList
gIpList = []
return
#@函数介绍: 付费代理Ip池设定
#@返回值:无
#@data: 20180809,stefan1240
def payProxieIpsUpdate(httpType):
global gIpList
global gIpLink
#初始值判断
if gIpLink == '':
return
#判断是哪个平台的代理IP
if 'zhimacangku' in gIpLink: #
#判断是需要哪种代理ip
if httpType == 'http':
if 'port=2' in gIpLink: #port 代表IP协议(1:HTTP 2:SOCK5 11:HTTPS )
gIpLink = gIpLink.replace('port=2', 'port=1')
if 'port=11' in gIpLink:
gIpLink.replace('port=3', 'port=1')
else: #https
if 'port=1' in gIpLink: #port 代表IP协议(1:HTTP 2:SOCK5 11:HTTPS )
gIpLink.replace('port=1', 'port=2')
if 'port=11' in gIpLink:
gIpLink.replace('port=11', 'port=2')
#修改返回IP的数据格式,这里使用txt
if 'type=2' in gIpLink: #type数据格式(1TXT 2JSON 3html)
gIpLink = gIpLink.replace('type=2', 'type=1')
if 'type=3' in gIpLink:
gIpLink.replace('type=3', 'type=1')
if 'num=1' in gIpLink: #一次性获取的IP个数设置为20
gIpLink = gIpLink.replace('num=1', 'num=20')
#获取一批量ip,并存于全局变量
r = requests.get(gIpLink)
ipStr = r.text
#IP数据处理
if 'false' in ipStr: #获取太频繁
printStr('代理平台返回结果:%s'%ipStr)
return
elif 'balde' in ipStr: #欠费了,直接返回False
printStr('代理IP欠费了,请到相应平台续费')
return
else:
tmpIpList = ipStr.splitlines() #按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
for strs in tmpIpList:
tmpIpDict = {}
if strs.count(':') >1:
printStr('IP代理格式设置不正确,请核对.')
return
if ":" not in strs:
printStr('可能是IP代理格式设置不正确,返回结果请设置为txt格式.')
return
ip, port = strs.split(':')
tmpIpDict['ip'] = ip
tmpIpDict['port'] = port
tmpIpDict['type'] = httpType
#printStrDebug(tmpIpDict)
gIpList.append(tmpIpDict)
elif 'xdaili' in gIpLink: #讯代理 可以直接按照以下格式组装所需的API链接:http://api.xdaili.cn/xdaili-api/greatRecharge/getGreatIp?spiderId=xx&orderno=xx&returnType=2&count=xx
if 'spiderId' in gIpLink:
p = gIpLink.find('spiderId') + len('spiderId=')
spiderId = gIpLink[p: gIpLink.find('&', p)]
if 'orderno' in gIpLink:
p = gIpLink.find('orderno') + len('orderno=')
orderno = gIpLink[p: gIpLink.find('&', p)]
fullLink = 'http://api.xdaili.cn/xdaili-api/greatRecharge/getGreatIp?spiderId='+spiderId+'&orderno='+ orderno+'&returnType=1&count=15'
#获取一批量ip,并存于全局变量
r = requests.get(fullLink)
ipStr = r.text
if 'ERRORCODE' in ipStr:
p = gIpLink.find('ERRORCODE') + len('ERRORCODE":"')
replyCode = gIpLink[p: gIpLink.find('"', p)]
if (replyCode == '10036' )| (replyCode == '10038') |(replyCode =='10055'):
printStr('提取代理IP太频繁,请按规定频率提取!')
if replyCode == '10032':
printStr('今日代理IP提取已达上限,请隔日提取或额外购买')
else:
tmpIpList = ipStr.splitlines() #按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
for strs in tmpIpList:
tmpIpDict = {}
if strs.count(':') >1:
printStr('IP代理格式设置不正确,请核对.')
return
if ":" not in strs:
printStr('可能是IP代理格式设置不正确,返回结果请设置为txt格式.')
return
ip, port = strs.split(':')
tmpIpDict['ip'] = ip
tmpIpDict['port'] = port
tmpIpDict['type'] = httpType
#printStrDebug(tmpIpDict)
gIpList.append(tmpIpDict)
else: #别的类型平台
#获取一批量ip,并存于全局变量
r = requests.get(gIpLink)
ipStr = r.text
printStr(ipStr)
#IP数据处理
if 'false' in ipStr: #获取太频繁
printStr('获取IP太过频繁,平台给予拒绝...')
time.sleep(2)
r = requests.get(gIpLink)
ipStr = r.text
elif 'balde' in ipStr: #欠费了,直接返回False
printStr('代理IP欠费了,请到相应平台续费')
return
else:
tmpIpDict = {}
tmpIpList = ipStr.splitlines() #按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
for strs in tmpIpList:
if ":" not in strs:
printStr('IP代理格式设置不正确,返回结果请设置为txt格式.')
return
ip, port = strs.split(':')
tmpIpDict['ip'] = ip
tmpIpDict['port'] = port
tmpIpDict['type'] = httpType
gIpList.append(tmpIpDict)
#printStrDebug('gIpList:%s'%gIpList)
return
#@函数介绍: 付费代理Ip获取
#@返回值: isGetIpSucess, tmpIpDict
#@data: 20180809,stefan1240
def payProxieIpGet(httpType):
isGetIpSucess = False
tmpIpDict = {}
ret = False
while ret == False:
if len(gIpList) == 0:
payProxieIpsUpdate(httpType)
if len(gIpList) == 0:
isGetIpSucess = False
break
tmpIpDict = gIpList.pop() #弹出一个IP,
ret = check_ip(tmpIpDict)
if ret == True:
isGetIpSucess = True
return isGetIpSucess, tmpIpDict
#@函数介绍: 付费代理Ip获取
#@返回值: 返回一个可用的dictIp
#@data: 20180809,stefan1240
def payProxieIpGet_old(httpType):
global gIpLink
isSucess = False
isGetIpSucess = True
iCirclMax = 50 #最多循环5次获取
circleIndex = 0
gIpLink = 'http://webapi.http.zhimacangku.com/getip?num=1&type=1&pro=&city=0&yys=0&port=1&pack=25657&ts=0&ys=0&cs=0&lb=1&sb=0&pb=4&mr=1®ions='
""" Ip的格式是这样的:
http://webapi.http.zhimacangku.com/getip?num=1&type=1&pro=&city=0&yys=0&port=1&time=1&ts=0&ys=0&cs=0&lb=1&sb=0&pb=4&mr=1®ions=
"""
ipDict = {}
while isSucess == False:
if circleIndex > iCirclMax:
isGetIpSucess = False
break;
circleIndex = circleIndex + 1
r = requests.get(gIpLink)
ipStr = r.text
printStr('get:%s'%ipStr)
if 'false' in ipStr: #获取太频繁
isSucess = False
time.sleep(1)
elif 'balde' in ipStr: #欠费了,直接返回False
isGetIpSucess = False
break
else:
ipStr = ipStr.strip('\r\n')
ip, port = ipStr.split(':')
ipDict['ip'] = ip
ipDict['port'] = port
ipDict['type'] = httpType
#ret = True
ret = check_ip(ipDict)
if ret == True:
isSucess = True
else:
isSucess = False
return isGetIpSucess, ipDict
#@函数介绍: 付费IP代理链接设置
#@返回值: 成功/失败: True/False
#@data: 20180809, stefan1240
def payPorxieIplinkSet(ipAddrsLink):
global gIpLink
if ipAddrsLink == '':
printStr('未输入代理IP链接,请输入有效的IP代理链接...')
return False
elif not ipAddrsLink.startswith(('http://', 'https://')):
printStr('你输入的IP代理链接格式不对,请检查一下格式...')
return False
else:
gIpLink = ipAddrsLink
return True
#@函数介绍: 宽带参数设置
#@返回值: 成功/失败: True/False
#@data: 20180809, stefan1240
def dialParaSet(dialName, dialAccount, dialPasswd):
global gDialName
global gDialAccount
global gDialPasswd
gDialName = dialName
gDialAccount = dialAccount
gDialPasswd = dialPasswd
return True
#@函数介绍: 宽带连接
#@返回值: 成功/失败: True/False
#@data: 20180809, stefan1240
def dialConnect():
global gDialName
global gDialAccount
global gDialPasswd
if gDialName == '':
return False
cmdStr = 'rasdial %s %s %s'%(gDialName, gDialAccount, gDialPasswd)
ret = os.system(cmdStr)
if ret == 0:
isSucess = True
else:
isSucess = False
printStr('拨号失败,错误代码:%s'%ret)
return isSucess
#@函数介绍: 宽带断开
#@返回值: 成功/失败: True/False
#@data: 20180809, stefan1240
def dialDisconnect():
global gDialName
cmdStr = 'rasdial %s /disconnect'%gDialName
ret = os.system(cmdStr)
if ret == 0:
isSucess = True
else:
isSucess = False
return isSucess
#@函数介绍: 宽带重连
#@返回值: 无
#@data: 20180809, stefan1240
def dialReconnect():
ret = dialDisconnect()
if ret == True:
time.sleep(3)
dialConnect()
time.sleep(1)
#@函数介绍: 随机生成n个中文字符
#@返回值: 中文字符串
#@data: 20180814, stefan1240
def randomChineseGet(num):
strs = ''
for i in range(num):
val = random.randint(0x4e00, 0x9fbf)
strs = strs + chr(val)
return strs
def randomChar(num):
return ''.join(random.choice(string.ascii_letters) for x in range(num))
def randomInt(num):
strs = ''
for i in range(num):
number = random.randint(1, 9)
strs = strs+ str(number)
return strs
#@函数介绍: md5加密
#@输入: 字符串型
#@返回值: md5加密后的字符串
def genearteMD5(strs):
# 创建md5对象
hl = hashlib.md5()
# Tips
# 此处必须声明encode
# 否则报错为:hl.update(str) Unicode-objects must be encoded before hashing
hl.update(strs.encode(encoding='utf-8'))
return hl.hexdigest()
#@函数介绍: sh256加密
#@输入: 字符串型
#@返回值: sh256加密后的字符串
def genearteSH256(strs):
sha256 = hashlib.sha256()
sha256.update(strs.encode('utf-8'))
return sha256.hexdigest()
#@函数介绍: base64加密
#@输入: 字符串型
#@返回值: base64加密后的字符
def genearteBase64(strs):
strEncode = base64.b64encode(strs.encode('utf-8'))
return strEncode.decode()
#@函数介绍: 新浪web加密某个字段需要调用JS代码
#@输入: servertime, nonce, passwd, pubkey
#@返回值: base64加密后的字符
def xinlanJsEcode(servertime, nonce, passwd, pubkey):
xinlanJsStr = xinlanJsStrGet()
handle = execjs.compile(xinlanJsStr)
ret = handle.call('Getsp', servertime, nonce, passwd, pubkey)
return ret
#@data: 20180814, stefan1240
#dic = {'ip':'182.244.109.222', 'port':'4230', 'type':'https'}
#check_ip(dic)
#------------------------易游对接相关API---------------------------------------------------------------
#@函数介绍:从配置文件获取登录用户信息相关
#@输入值:
#@返回值: gStatusCode, gUsername
#@data: 201808022
def loingAccountInfoGet():
global gStatusCode
global gUsername
file = open('系统文件(勿动)\para.ini', 'r')
for line in file.readlines():
line = line.strip('\n')
if '<registerInfo>' in line:
para = re.findall("<registerInfo>(.+?)<registerInfo>", line)
gUsername, passwd = para[0].split(':')
if '<retCodeInfo>' in line:
para = re.findall("<retCodeInfo>(.+?)<retCodeInfo>", line)
gStatusCode = para[0]
file.close()
#@函数介绍:获取用户状态
#@输入值: statusCode:登录成功后返回的状态码, userName:用户名
#@返回值: 成功的返回1或者错误代码,代码含义:http://dev.eydata.net/webapi/errorlist
#@data: 201808021
def checkUserStatus():
global gStatusCode
global gUsername
url = 'https://w.eydata.net/aec651134b90f1ab'
data = {
"StatusCode": gStatusCode,
"UserName": gUsername
}
r = requests.post(url, data)
return r.text
#@函数介绍:退出接口
#@输入值:
#@返回值: 成功的返回1或者错误代码,代码含义:http://dev.eydata.net/webapi/errorlist
#@data: 201808021
def logOut():
statusCode = ''
userName = ''
file = open('系统文件(勿动)\para.ini', 'r')
for line in file.readlines():
line = line.strip('\n')
if '<registerInfo>' in line:
para = re.findall("<registerInfo>(.+?)<registerInfo>", line)
userName, passwd = para[0].split(':')
if '<retCodeInfo>' in line:
para = re.findall("<retCodeInfo>(.+?)<retCodeInfo>", line)
statusCode = para[0]
file.close()
url = 'https://w.eydata.net/a8a66a6329265b37'
data = {
"StatusCode": statusCode,
"UserName": userName
}
r = requests.post(url, data)
return r.text
#-----------------------------------------------------------------------------------
#@函数介绍:把代理IP链接写入到配置文件
#@输入值: statusCode:登录成功后返回的状态码, userName:用户名
#@返回值: 成功的返回1或者错误代码,代码含义:http://dev.eydata.net/webapi/errorlist
#@data: 201808021
def writeIpLinkIntoFile():
global gIpLink
needWrite = True
if gIpLink == '':
printStr('代理IP链接为空,停止写入到配置文件...')
ipAddresLink = gIpLink
#写入配置文件
strs = '<IplinkInfo>%s<IplinkInfo>\n'%ipAddresLink
#使用w模式会将原本的文件清空/覆盖。可以先用读(r)的方式打开,写到内存中,然后再用写(w)的方式打开。
with open('系统文件(勿动)\para.ini', 'r' ,encoding="utf-8") as file:
lines = file.readlines()
with open('系统文件(勿动)\para.ini', 'w',encoding="utf-8") as file:
for line in lines: #替换
if '<IplinkInfo>' in line:
s = line.replace(line, strs)
file.write(s)
needWrite = False
else:
file.write(line)
printStrDebug('needWrite=%s'%needWrite)
if needWrite == True: #首次写入
with open('系统文件(勿动)\para.ini', 'a+',encoding="utf-8") as file:
file.write(strs)
"""
articleBody ='hello'
articleTitle = 'hello'
deviceid = 'ab56b4d92b40713acc5af89985d4b786'
uid = '6611942773'
str1 ="act=1&allow_comment=1&allow_repost=1&appid=2&appver=3.0.2&article_body=" + articleBody + "&article_title="+articleTitle
str2 = "&chno=515_112&class_id=0&deviceid=" + deviceid + "&is_secret=0&is_to_weibo=0&login_uid=" +uid
str3 = "&signkey=e3eb41c951f264a6daa16b6e4367e829&sort_id=117"
body = str1 + str2 + str3
sign = genearteSH256(body)
print(sign)
"""