This commit is contained in:
xw_y_am@rmbp 2018-04-22 18:48:48 +08:00
parent 1c944d5a47
commit 10a07dc626
12 changed files with 1035 additions and 0 deletions

28
README.md Normal file
View File

@ -0,0 +1,28 @@
# BTSearcher
我通过浏览器访问各种BT搜索网站时总会有乱七八糟的弹窗和广告很是烦人。于是自己写了这么个小工具通过`PyQt`爬取一些网站获得磁力链接。
## 软件信赖
- python 3.4+
- requests
- beautifulsoup 4
- lxml
## 使用方法
```shell
python run.py
```
## 支持网站
- Bobobt
- BTcerise
- Cililianc
- BTdao
- BTrabbit
- BTanw
- Ciliba

1
gen_ui.sh Executable file
View File

@ -0,0 +1 @@
pyuic5 -o window.py ./qt/mainwindow.ui

34
qt/BTSearcher.pro Normal file
View File

@ -0,0 +1,34 @@
#-------------------------------------------------
#
# Project created by QtCreator 2018-02-13T15:52:30
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = BtSearch
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui

336
qt/BTSearcher.pro.user Normal file
View File

@ -0,0 +1,336 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.5.1, 2018-04-22T18:37:44. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{cfe5db96-a239-44a1-89bc-6e1d2df6822d}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.10.1 clang 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.10.1 clang 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5101.clang_64_kit</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/xwy/TODO/python/BTSearcher/build-BTSearcher-Desktop_Qt_5_10_1_clang_64bit-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清理</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/xwy/TODO/python/BTSearcher/build-BTSearcher-Desktop_Qt_5_10_1_clang_64bit-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清理</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/xwy/TODO/python/BTSearcher/build-BTSearcher-Desktop_Qt_5_10_1_clang_64bit-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
<value type="QString">-w</value>
<value type="QString">-r</value>
</valuelist>
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清理</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">在本地部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">BTSearcher</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/Users/xwy/TODO/python/BTSearcher/qt/BTSearcher.pro</value>
<value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">BTSearcher.pro</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/Users/xwy/TODO/python/BTSearcher/build-BTSearcher-Desktop_Qt_5_10_1_clang_64bit-Debug/BtSearch.app/Contents/MacOS</value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">18</value>
</data>
<data>
<variable>Version</variable>
<value type="int">18</value>
</data>
</qtcreator>

11
qt/main.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

34
qt/mainwindow.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
class MyThread: QThread {
Q_OBJECT
public:
void run();
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btn_search_clicked(bool checked)
{
}
void MainWindow::on_ln_key_returnPressed()
{
}
void MainWindow::on_cb_source_currentIndexChanged(int index)
{
}

28
qt/mainwindow.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_btn_search_clicked(bool checked);
void on_ln_key_returnPressed();
void on_cb_source_currentIndexChanged(int index);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

90
qt/mainwindow.ui Normal file
View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>750</width>
<height>600</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>750</width>
<height>600</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>750</width>
<height>600</height>
</size>
</property>
<property name="windowTitle">
<string>BTSearcher</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0" colspan="3">
<widget class="QTableWidget" name="tb_result">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<column>
<property name="text">
<string>热度</string>
</property>
</column>
<column>
<property name="text">
<string>大小</string>
</property>
</column>
<column>
<property name="text">
<string>文件名</string>
</property>
</column>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="btn_search">
<property name="text">
<string>Search</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="ln_key"/>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="cb_source"/>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="state"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>cb_source</tabstop>
<tabstop>btn_search</tabstop>
<tabstop>ln_key</tabstop>
<tabstop>tb_result</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

8
run.py Normal file
View File

@ -0,0 +1,8 @@
import sys
import ux
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
search = ux.Ux()
search.show()
sys.exit(app.exec_())

308
sites.py Normal file
View File

@ -0,0 +1,308 @@
import requests
from bs4 import BeautifulSoup
class Sites:
def __init__(self, signal):
self.send_item = signal
print(self.name, 'start ...')
def __del__(self):
print(self.name, 'stop !')
def search(self, key_word):
key_word = self.trns_key(key_word)
for url in self.gen_url(key_word):
try:
soup = self.fetch_soup(url)
except:
break
for item in self.get_item(soup):
if 'link_url' in item:
try:
item['link'] = self.get_link(self.fetch_soup(item['link_url']))
except:
item['link'] = ''
if item['link']:
self.send_item.emit(item)
try:
if self.last_page(soup):
break
except:
break
@staticmethod
def fetch_soup(url):
print('fetching "' + url + '" ...', end=' ')
soup = BeautifulSoup(requests.get(url).text, 'lxml')
print('ok!')
return soup
@staticmethod
def gen_url(key_word):
raise NotImplementedError
@staticmethod
def last_page(soup):
raise NotImplementedError
@staticmethod
def get_item(soup):
raise NotImplementedError
@staticmethod
def get_link(url):
raise NotImplementedError
class Bobobt(Sites):
name = 'Bobobt'
@staticmethod
def trns_key(key_word):
return key_word.replace(' ', '%20')
@staticmethod
def gen_url(key_word):
page_number = 0
while True:
page_number += 1
yield 'https://www.bobobt.com/search/%s/%d/0/0.html' % (key_word, page_number)
@staticmethod
def last_page(soup):
return soup.find('div', 'pager').find_all('a')[-1].string not in ['&gt;&gt;', '>>']
@staticmethod
def get_item(soup):
for dom_item in soup.find_all('div', 'ss'):
try:
la = dom_item.find_all('a')
lb = dom_item.find_all('b')
yield {
'hot': lb[4].string,
'size': lb[1].string,
'name': ''.join(la[0].strings).strip(),
'link': la[1].get('href')
}
except:
continue
class BTcerise(Sites):
name = 'BTcerise'
@staticmethod
def trns_key(key_word):
return key_word.replace(' ', '%20')
@staticmethod
def gen_url(key_word):
page_number = 0
while True:
page_number += 1
yield 'http://www.btcerise.me/search?keyword=%s&p=%d' % (key_word, page_number)
@staticmethod
def last_page(soup):
return 'disable' in soup.find('ul', 'pagination').find_all('li')[-1]
@staticmethod
def get_item(soup):
for dom_item in soup.find_all('div', 'r'):
try:
yield {
'hot': '-',
'size': dom_item.find_all('span', 'prop_val')[1].string,
'name': ''.join(dom_item.find('h5').strings),
'link': dom_item.find('div').find('a').get('href')
}
except:
continue
class Cililianc(Sites):
name = 'Cililianc'
@staticmethod
def trns_key(key_word):
return key_word.replace(' ', '%2B')
@staticmethod
def gen_url(key_word):
page_number = 0
while True:
page_number += 1
yield 'http://cililianc.com/list/%s/%d.html' % (key_word, page_number)
@staticmethod
def last_page(soup):
return soup.find('div', 'pg').find_all('a')[-1].string not in ['下一页']
@staticmethod
def get_item(soup):
for dom_item in soup.find('ul', 'mlist').find_all('li'):
try:
yield {
'hot': '-',
'size': dom_item.find('dt').find('span').string,
'name': ''.join(dom_item.find('a').strings),
'link': dom_item.find('div', 'dInfo').find('a').get('href')
}
except:
continue
class BTdao(Sites):
name = 'BTdao'
@staticmethod
def trns_key(key_word):
return key_word.replace(' ', '%2B')
@staticmethod
def gen_url(key_word):
page_number = 0
while True:
page_number += 1
yield 'http://www.btdao.me/list/%s-s2d-%d.html' % (key_word, page_number)
@staticmethod
def last_page(soup):
return soup.find('div', 'pg').find_all('a')[-1].string not in ['下一页']
@staticmethod
def get_item(soup):
for dom_item in soup.find_all('li'):
try:
la = dom_item.find('a')
ls = dom_item.find('dl').find_all('span')
yield {
'hot': ls[3].string,
'size': ls[0].string,
'name': la.get('title'),
'link_url': 'http://www.btdao.me' + la.get('href')
}
except:
continue
@staticmethod
def get_link(soup):
return soup.find('dl', 'BotInfo').find('a').get('href')
class BTrabbit(Sites):
name = 'BTrabbit'
@staticmethod
def trns_key(key_word):
return key_word.replace(' ', '%20')
@staticmethod
def gen_url(key_word):
page_number = 0
while True:
page_number += 1
yield 'http://www.btrabbit.net/search/%s/default-%d.html' % (key_word, page_number)
@staticmethod
def last_page(soup):
return soup.find('div', 'bottom-pager').find_all('a')[-1].string not in ['>']
@staticmethod
def get_item(soup):
for dom_item in soup.find_all('div', 'search-item'):
try:
la = dom_item.find('a')
lb = dom_item.find('div', 'item-bar').find_all('b')
yield {
'hot': lb[2].string,
'size': lb[1].string.replace('&nbsp;', ' '),
'name': la.get('title'),
'link_url': 'http://www.btrabbit.net' + la.get('href')
}
except:
continue
@staticmethod
def get_link(soup):
return soup.find_all('textarea')[0].string
class BTanw(Sites):
name = 'BTanw'
@staticmethod
def trns_key(key_word):
return key_word.replace(' ', '%20')
@staticmethod
def gen_url(key_word):
page_number = 0
while True:
page_number += 1
yield 'http://www.btanw.com/search/%s-hot-desc-%d' % (key_word, page_number)
@staticmethod
def last_page(soup):
return len(soup.find('div', 'bottom-pager').find_all('a')[-1].get('href')) == 0
@staticmethod
def get_item(soup):
for dom_item in soup.find_all('div', 'search-item'):
try:
la = dom_item.find('a')
lb = dom_item.find('div', 'item-bar').find_all('b')
yield {
'hot': lb[1].string,
'size': lb[3].string,
'name': ''.join(la.strings),
'link_url': 'http://www.btanw.com' + la.get('href')
}
except:
continue
@staticmethod
def get_link(soup):
return soup.find('div', 'fileDetail').find_all('p')[5].find('a').get('href')
class Ciliba(Sites):
name = 'Ciliba'
@staticmethod
def trns_key(key_word):
return key_word.replace(' ', '+')
@staticmethod
def gen_url(key_word):
page_number = 0
while True:
page_number += 1
yield 'https://www.ciliba.org/s/%s_rel_%d.html' % (key_word, page_number)
@staticmethod
def last_page(soup):
return soup.find('ul', 'pagination').find_all('a')[-1].string not in ['Last']
@staticmethod
def get_item(soup):
for dom_item in soup.find_all('div', 'search-item'):
try:
la = dom_item.find('h3').find('a')
lb = dom_item.find('div', 'item-bar').find_all('b')
yield {
'hot': lb[2].string,
'size': lb[1].string,
'name': ''.join(la.strings),
'link_url': la.get('href')
}
except:
continue
@staticmethod
def get_link(soup):
return soup.find('a', 'download').get('href')
lst = (Bobobt, BTcerise, Cililianc, BTdao, BTrabbit, BTanw, Ciliba)

88
ux.py Normal file
View File

@ -0,0 +1,88 @@
import sites
import window
from PyQt5.QtGui import QClipboard
from PyQt5.QtCore import QTimer, QThread, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem
class Ux(QMainWindow, window.Ui_MainWindow):
def __init__(self):
super().__init__()
self.clipboard = QApplication.clipboard()
# timer for update status bar
self.timer = QTimer(self)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.update_state)
# setting ui
self.setupUi(self)
self.tb_result.setColumnWidth(0, 70)
self.tb_result.setColumnWidth(1, 90)
self.tb_result.setColumnWidth(2, 480)
for it in sites.lst:
self.cb_source.addItem(it.name)
def update_state(self):
self.process += 1
self.state.showMessage('Searching ' + '.' * (self.process % 10))
def stop_search(self):
self.state.showMessage('Over')
if self.timer.isActive():
self.timer.stop()
while self.th_search.isRunning():
self.th_search.exit()
def on_cb_source_currentIndexChanged(self, index):
if type(index) == type(1):
self.site = sites.lst[index]
self.stop_search()
def on_btn_search_clicked(self, b=True):
if b:
return
self.stop_search()
self.tb_result.clearContents()
self.tb_result.setRowCount(0)
self.process = 0
self.links = []
self.timer.start()
self.th_search = SearchThread(self, self.ln_key.text())
self.th_search.start()
def on_ln_key_returnPressed(self):
self.btn_search.click()
def on_tb_result_cellActivated(self, row, col):
self.clipboard.setText(self.links[row])
@pyqtSlot()
def do_stop_search(self):
self.timer.stop()
@pyqtSlot(dict)
def do_append_result(self, item):
row = self.tb_result.rowCount()
self.tb_result.insertRow(row)
self.tb_result.setItem(row, 0, QTableWidgetItem(item['hot']))
self.tb_result.setItem(row, 1, QTableWidgetItem(item['size']))
self.tb_result.setItem(row, 2, QTableWidgetItem(item['name']))
self.links.append(item['link'])
class SearchThread(QThread):
to_append_result = pyqtSignal([dict])
to_stop_search = pyqtSignal()
def __init__(self, obj, key_word, parent=None):
super(SearchThread, self).__init__(parent)
self.site = obj.site
self.key = key_word
self.to_append_result.connect(obj.do_append_result)
self.to_stop_search.connect(obj.do_stop_search)
def run(self):
if not self.key:
return
search = self.site(self.to_append_result)
search.search(self.key)
self.to_stop_search.emit()

69
window.py Normal file
View File

@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file './qt/mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.10
#
# 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(750, 600)
MainWindow.setMinimumSize(QtCore.QSize(750, 600))
MainWindow.setMaximumSize(QtCore.QSize(750, 600))
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralWidget)
self.gridLayout.setContentsMargins(11, 11, 11, 11)
self.gridLayout.setSpacing(6)
self.gridLayout.setObjectName("gridLayout")
self.tb_result = QtWidgets.QTableWidget(self.centralWidget)
self.tb_result.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.tb_result.setProperty("showDropIndicator", False)
self.tb_result.setDragDropOverwriteMode(False)
self.tb_result.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.tb_result.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.tb_result.setObjectName("tb_result")
self.tb_result.setColumnCount(3)
self.tb_result.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.tb_result.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tb_result.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tb_result.setHorizontalHeaderItem(2, item)
self.gridLayout.addWidget(self.tb_result, 1, 0, 1, 3)
self.btn_search = QtWidgets.QPushButton(self.centralWidget)
self.btn_search.setObjectName("btn_search")
self.gridLayout.addWidget(self.btn_search, 0, 1, 1, 1)
self.ln_key = QtWidgets.QLineEdit(self.centralWidget)
self.ln_key.setObjectName("ln_key")
self.gridLayout.addWidget(self.ln_key, 0, 2, 1, 1)
self.cb_source = QtWidgets.QComboBox(self.centralWidget)
self.cb_source.setObjectName("cb_source")
self.gridLayout.addWidget(self.cb_source, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralWidget)
self.state = QtWidgets.QStatusBar(MainWindow)
self.state.setObjectName("state")
MainWindow.setStatusBar(self.state)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
MainWindow.setTabOrder(self.cb_source, self.btn_search)
MainWindow.setTabOrder(self.btn_search, self.ln_key)
MainWindow.setTabOrder(self.ln_key, self.tb_result)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "BTSearcher"))
item = self.tb_result.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "热度"))
item = self.tb_result.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "大小"))
item = self.tb_result.horizontalHeaderItem(2)
item.setText(_translate("MainWindow", "文件名"))
self.btn_search.setText(_translate("MainWindow", "Search"))