一.前置说明
周末的两个晚上草草写完,后续会有一些修改
1.只用于个人学习和简化过程,不可用于商用
2.侵删
3.打包的文件链接: https://pan.baidu.com/s/1TfvyIBK0DI0JG5Ae6C7dqw 提取码: 8bi4
二.过程
1.需求
刚开始是由于某番的更新时间比较特殊,又同时追几个番,一个个去翻网页看是否更新又比较麻烦,
如果只看某些弹幕网的推送也比较麻烦(原因多种)。
所以周末突然想起来用python跑个爬虫脚本,一次配置(待追番文件),每次启动后自动抓取更新,记录链接,写入文件,
个人直接看文本(待下载)即可。
2.分解步骤
读取配置
根据链接查询网站,处理标签内容(根据id class 正则等获取指定内容)
获取当前最新集数,比较配置内已下载的集数,决定是否更新。
如果番剧已更新,则将最新集数和上一集数,新的下载链接写入配置文件和待下载文件
(由于会开源使用,所以不连数据库,而是直接保存csv或txt)
结束后保存配置。如果已更新则用cmd指令弹出待下载的文档。
3.所需编译环境和资源
1.python3.7和自带的pip,同时pip还得更新一次
其他如下
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton,QLabel
from PyQt5.QtCore import QCoreApplication
import os
#from bs4 import BeautifulSoup
from urllib.request import urlopen
import requests
from lxml import etree
import urllib
import time
import socket
#import configparser
import pandas as pd
import datetime
4.部分代码说明
可以看到刚开始我用的是ConfigParser来解析配置文件,结果这个库是py2的,而在py3中已经更新成configparser,
在使用中还遇到了不同sections下的option相同,则报错的情况,比如:
[番剧1]:
url = *****
[番剧2]:
url = *****
则报错有重复url这个option。
想了下,用csv的格式存储,改用pandas来解析(踏入了另外一个坑)
先确定字段,其实就是把数据库的格式放到csv里:(对了 我看的番不是这个 这个只作为示例)
name url lastdown currdown downurl renewtime
五等分的花嫁 http://www.776dm.com/hougong/29204 7 8 https://www.776dm.com/v/29204/1_8.html 2019-03-06 22:47:38
规定了 名称、网址、最后一次下载集、当前下载集、当前下载集的连接、更新时间。
好了 下面是解析存储的txt文件(内部是csv)
#读配置文件
csv_data = pd.read_csv('down.txt',encoding='gbk',sep = '\t')
#print(csv_data.shape[0])#这里打印行数
#print(csv_data.columns)
row_count = csv_data.shape[0];#这里读取了有几行数据(来循环爬取是否更新)
因为可能在追多个番剧,所以需要循环读取:
其中在获得返回信息后,先用etree来格式化数据,在用xpath这个好工具来得到特定信息:
当div有id的时候,不是非常快乐吗~~更多详细用法 请查找xpath的说明
for i in range(0,row_count):
currurl = csv_data[i:i+1]['url'].iloc[0]
lastdown = csv_data[i:i+1]['lastdown'].iloc[0]
currdown = csv_data[i:i+1]['currdown'].iloc[0]
#print(currurl)
#print(str(lastdown))
#print(str(currdown))
response = requests.get(currurl,headers=headers).content
code = etree.HTML(response)
get_cur = code.xpath('//div[@id="playList"]/div[1]/div[2]/a[last()]//text()')
down_list = code.xpath('//div[@id="playList"]/div[1]/div[2]/a[last()]//@href')
if(currdown !=int(get_cur[0])):
print('有更新')
updFlag = 1
#'----------this is updData---------'
csv_data.loc[i:i,('lastdown','currdown','downurl','renewtime')]=[currdown,get_cur[0],''.join(['https://www.776dm.com',
down_list[0]]),datetime.datetime.now().strftime('%F %T')]
#'----------this is df bak---------'
df_bak = df_bak.append(csv_data.iloc[i], ignore_index=True)
#('----------this is updData end---------\n')
csv_data.to_csv('down.txt',encoding='gbk',sep = '\t',index=0)
#('----------next---------')
这里pandas内部是dataframe的格式,看了下方法,irow()之类不好用,所以直接用iloc这样的切片方法准确定位。
这里headers用的是伪装成firefox的请求头
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0'}
不伪装请求头的话,对方服务器直接返回错误码和“远程主机断开连接”。。。
df_bak是为了写去“待下载文件”的更新数据,所以每次循环中番剧如果更新,则把新的数据写入df_bak,写过java的看到append其实很想笑。
对了,df_bak在进入循环前要初始化,
df_bak = pd.DataFrame(columns=['name','url','lastdown','currdown','downurl','renewtime'])
在循环完成后我们还可以调用命令行来打开待下载文件:
if updFlag == 1 :
os.system('.\wait4downlist.txt')
else:
print("么得更新")
pandas的数据处理能力非常强大,但是同样需要大量的训练才能灵活使用。
之后是ui部分:
其实没得选,直接使用的是PyQt5,为了缩小打包后的大小,得注意引用包.
非常想吐槽关于pyqt方法的引用,一种connect(方法名还不能带括号) 一种就是(lambda:self.close_win()) 默认传参,用起来纠结地一笔,而且还不报错。。。
class Win_func(QWidget):
def pa_chong(self):
…………这里是上面的爬虫逻辑代码…………
…………下面是关于ui的代码…………
def __init__(self):
super().__init__()
self.initUI()
# 槽函数1
def btn_start(self):
self.label.setText('开始了')
# 槽函数2
def btn_end(self):
self.label.setText('结束啦')
def close_win(self):
qApp = QApplication.instance()
qApp.quit()
sys.exit(app.exec_())
def initUI(self):
# 窗体大小
self.resize(500, 500)
self.setWindowTitle('追更爬虫')
self.move(400, 400)
# 标签
self.label = QLabel(self)
self.label.setText('测试显示')
self.label.move(250, 100)
# 按钮1
self.btn1 = QPushButton(self)
self.btn1.setText('点击开始')
self.btn1.move(200, 200)
# 按钮2
self.btn2 = QPushButton(self)
self.btn2.setText('点击结束')
self.btn2.move(200, 300)
self.btn1.clicked.connect(lambda:self.btn_start()) # 信号与槽
self.btn1.clicked.connect(lambda:self.pa_chong())
self.btn2.clicked.connect(lambda:self.btn_end()) # 信号与槽
self.btn2.clicked.connect(lambda:self.close_win())
# 显示窗体
self.show()
#关闭应用
# btn.clicked.connect(QCoreApplication.instance().quit)
if __name__=='__main__':
app=QApplication(sys.argv)
example=Win_func()
sys.exit(app.exec())
最后打开cmd,在目录下用进行打包
pyinstaller -F -w pachong.py
部分坑:
字符串前的r,b,u代表的意思,os.system(str) 字符串前不加r 用you-get就会闪退
三.使用方法
这里主要给使用我打包好的文件,而不是源码。
解压后文件夹下有三个文件:
down.txt (用来填写所追番剧信息)
pc_qt.ext(我打包好的工具)
wait4downlist.txt(待下载文件信息 每次如果有更新,更新完后会自动弹出)
先从这个网站上搜到所追番的页面,比如jojo的https://www.776dm.com/maoxian/29143/
然后依次填写番剧名,网页,上一次看到,当前看到,需要用tab键来分隔(这很重要 不然无法识别)
示例如下
双击pc_qt.exe文件 点击开始,即运行数据更新。