【手把手】教你如何利用Python爬虫“摸鱼“

Python3.8

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

身体在工位,灵魂已放假。摸的不是鱼,是心跳,是暂时逃离KPI的方舟。

学了这么久了爬虫,却一直没有在实际生活中使用过,正好上班闲得无聊,咱们来研究下如何利用爬虫“安全”地摸鱼。

首先确定我们要爬取的目标网站,这里以爬取小说《剑来》的内容为例。

工具准备:

1. Python3.10

2. PyCharm

3. request、bs4、textwrap、pyQt5等相关库

第一步,实现咱们的爬虫功能(核心!!!先看看爬取效果怎么样,如果先封装界面再实现爬虫功能,不是很方便查看爬取效果。)

打开咱们的PyCharm新建一个.py文件,名称自拟。

学过爬虫的都知道,接下来当然是引入咱们的爬虫库了(没学过的也别慌,因为这压根不是一个知识点啊🤡)

import requests    # 爬虫库
from bs4 import BeautifulSoup    # 解析页面
import textwrap    # 处理文本

核心代码我直接端上来了,非常简单,即便是没有开深度思考的ds也能轻松实现。(注意后续完成界面封装后该部分还需要修改的。)

def auto_wrap_text(text, width=60):
    return textwrap.fill(
        text,
        width=width,
        break_long_words=True,
        break_on_hyphens=True,
        replace_whitespace=True
    )

url = '目标网站'
headers = {
    'User-Agent': '目标网站请求头'
}

try:
    response = requests.get(url, headers=headers, timeout=10)
    response.encoding = response.apparent_encoding

    if response.status_code == 200:
        soup = BeautifulSoup(response.text, 'html.parser')

        # 定位目标div元素
        content_div = soup.find('div', {'id': 'content', 'class': 'showtxt'})

        if content_div:
            # 保留原始换行符(处理<br>标签)
            text_content = (((content_div.decode_contents(formatter="html").replace('<br/>', '')
                            .replace('<br>', '')
                            .replace("&rdquo;", "")
                            .replace('&ldquo;', '')
                              .replace('\t', '')
                            .replace('&mdash;&mdash;&mdash;&mdash;  ', '')
                            .replace("。", "。\n")
                            .replace('?', '\n'))))
            text_content = text_content.strip()
            text_content = auto_wrap_text(text_content)

            # 输出结果
            print(text_content)

    else:
        print(f"请求失败,状态码:{response.status_code}")

except Exception as e:
    print(f"发生错误:{str(e)}")

不知道怎么获取请求头?请看【VCR】⬇

访问目标网站后按【F12】,之后岸图中顺序依次点击

通过调整达到自己预期的爬取效果后咱们进入下一步。

第二步,封装界面

右键咱们的项目目录,选择【外部工具】➡【qtdesigner】

如果你没有这些工具,请参考:python-在PyCharm中使用PyQt5_pycharm pyqt5-CSDN博客

然后就可以根据自己的需要创建界面了。

使用PyUIC工具将.ui文件转成.py文件。

在生成的.py中加上下面的代码就可以显示界面了。

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    widget = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(widget)
    widget.show()
    sys.exit(app.exec_())

接下来咱们对界面进行调整,直接展示调整后的页面和源码。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'showtext.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class TransparentWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Form()
        self.ui.setupUi(self)

        # 设置窗口属性
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.setWindowFlags(
            QtCore.Qt.FramelessWindowHint |
            QtCore.Qt.WindowStaysOnTopHint 
        )

    def showEvent(self, event):
        # 窗口显示时定位到右下角
        screen_geometry = QtWidgets.QApplication.desktop().availableGeometry()
        self.move(
            screen_geometry.right() - self.width(),
            screen_geometry.bottom() - self.height()
        )
        super().showEvent(event)

    def keyPressEvent(self, event):
        # 按ESC键退出应用
        if event.key() == QtCore.Qt.Key_Escape:
            self.close()

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        # 设置窗口初始尺寸
        Form.resize(550, 45)

        # 使用垂直布局
        self.verticalLayout = QtWidgets.QVBoxLayout(Form)
        self.verticalLayout.setContentsMargins(10, 10, 10, 10)
        self.verticalLayout.setObjectName("verticalLayout")

        # 创建文本框
        self.plainTextEdit = QtWidgets.QPlainTextEdit(Form)
        self.plainTextEdit.setObjectName("plainTextEdit")

        # 设置文本框样式
        self.plainTextEdit.setStyleSheet("""
                    QPlainTextEdit {
                        background-color: transparent;  /* 完全透明背景 */
                        color: #FFFFFF;  /* 纯白文字,完全不透明 */
                        font-size: 14px;
                        border: none;
                        padding: 0px;
                    }
                    QScrollBar {
                        background: transparent;
                        width: 0px;
                        height: 0px;
                    }
                """)

        # 设置字体
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei")
        font.setPointSize(10)
        self.plainTextEdit.setFont(font)

        # 设置文本框为只读
        self.plainTextEdit.setReadOnly(True)

        # 设置示例文本
        text = """这是一段测试文本,
用来测试文本框的显示效果。
"""
        self.plainTextEdit.setPlainText(text)

        # 添加布局
        self.verticalLayout.addWidget(self.plainTextEdit)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "摸个大鱼"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    widget = TransparentWidget()
    widget.show()
    sys.exit(app.exec_())

是不是十分隐蔽?

接下来只要把咱们爬取到的内容绑定到这个文本框就行了!!!

创建一个新的界面用于输入目标网址和请求标头:

将爬虫部分的代码封装成一个线程类:

class CrawlerWorker(QObject):
    data_ready = pyqtSignal(str)         # 成功时发送数据
    error_occurred = pyqtSignal(str)     # 失败时发送错误信息

    def __init__(self, url, user_agent):
        super().__init__()
        self.url = url
        self.user_agent = user_agent

    def process(self):
        headers = {
            'User-Agent': self.user_agent
        }

        try:
            response = requests.get(self.url, headers=headers, timeout=10)
            response.encoding = response.apparent_encoding

            if response.status_code == 200:
                soup = BeautifulSoup(response.text, 'html.parser')
                content_div = soup.find('div', {'id': 'content', 'class': 'showtxt'})

                if content_div:
                    raw_text = content_div.decode_contents(formatter="html")
                    processed_text = (
                        raw_text
                        .replace('<br/>', '')
                        .replace('<br>', '')
                        .replace("&rdquo;", "")
                        .replace('&ldquo;', '')
                        .replace('\t', '')
                        .replace('&mdash;&mdash;&mdash;&mdash;  ', '')
                        .replace("。", "。\n")
                        .replace('?', '?\n')
                        .strip()
                    )
                    wrapped_text = auto_wrap_text(processed_text)
                    print(wrapped_text)
                    self.data_ready.emit(wrapped_text)
                else:
                    self.error_occurred.emit("未找到目标内容 <div>")

            else:
                self.error_occurred.emit(f"请求失败,状态码:{response.status_code}")

        except Exception as e:
            self.error_occurred.emit(f"发生错误:{str(e)}")

在主窗口中将【出发】按钮绑定到启动线程函数:

        self.ui.pushButton.clicked.connect(self.start_fishing)
    def start_fishing(self):
        url = self.ui.ipaddress.text()
        ua = self.ui.user_agent.text()

        self.worker = CrawlerWorker(url, ua)
        self.thread = QThread()

        self.worker.moveToThread(self.thread)

        self.worker.data_ready.connect(self.update_text)
        self.worker.error_occurred.connect(self.show_error)

        self.thread.started.connect(self.worker.process)
        self.worker.data_ready.connect(self.thread.quit)
        self.worker.error_occurred.connect(self.thread.quit)
        self.thread.finished.connect(self.thread.deleteLater)

        self.thread.start()

将爬取到的文本更新到文本框并隐藏主窗口、显示文本窗口:

    def update_text(self, text):
        self.second_window.ui.plainTextEdit.setPlainText(text)
        self.hide()
        self.second_window.show()

接下来看看效果:

输入网址和请求头后点击【出发】

隐藏主窗口、显示文本框

可以开始摸鱼了!!!

还有一些细节上的东西文中没提到,后续会慢慢优化(毕竟我自己要用啊!)

源码在这:https://github.com/victory-fcs/request.git

不过咱这种“有手就行”的玩意儿,应该没人感兴趣和需要吧

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值