PyQt+界面防卡死+selenium+多进程爬取图片一次打通!

2023-05-16

  1. 创建MyUrl.py 编写爬取图片代码
    爬取图片,实际上就是对网页信息的读取。而selenium可以很好的做到这一点,相对于beautifulsoup只能爬取静态前端源码的缺点,selenium可以解析由js文件生成的动态网页信息。这篇文章主要拿开源网站https://openi.nlm.nih.gov/作为示例。

    很明显,网页信息由js文件动态生成。无法直接使用beautifulsoup获取网页信息。
    使用selenium获取网页信息:
driver = webdriver.Chrome()
search_url = "https://openi.nlm.nih.gov/gridquery?q=hand&m=1&n=100"
driver.get(search_url)

此时获得的网页信息也鼠标右键“检查”浏览到的代码一致,而不是“查看页面源代码”。
观察网页信息,找到需要获取的信息。
在这里插入图片描述
可以看到所有图片都被分到了一个id为“grid”的class下。a标签对则是每个图片的具体信息。如果你想获得缩略图,你就可以直接获取img标签对src的值,这就是缩略图的图像链接。

但是缩略图根本看不清,爬下来没有意义,我们需要做的是获取原图。显然,原图的图像链接并不在这个网页上,一般我们需要点击缩略图的图标跳转到详细信息页面才能看到原图。所以爬取图片也是一样,我们需要先爬取所有详细信息页面的链接,再去所有详细信息页面爬取原图。

在这里,详细信息页面的url就是a标签对中的ng-href的值

		driver = webdriver.Chrome()
		search_url = "https://openi.nlm.nih.gov/gridquery?q=hand&m=1&n=100"
		driver.get(search_url)
		time.sleep(3) #等待网页加载,负责会出现获取不到网页信息的情况
        tag = driver.find_element(By.ID, "grid").get_attribute("outerHTML")  # 找到定位标签对
        pattern = re.compile(r'a.*ng-href="(.*?)"')  # 正则表达式匹配原图所在网页url
        match = re.findall(pattern, tag)  # 获得所有原图所在网页url
        driver.quit()

关于driver得到的webElement属性的详细内容可以参考:

https://www.jianshu.com/p/cc91666c338d

https://blog.csdn.net/m0_49076971/article/details/126233151

由此可以获取所有详细信息页面url。爬取原图同理。
在这里插入图片描述
进入原图所在页面。"image.ng-scope"下的ng-src的值就是原图的图像链接。

    driver = webdriver.Chrome()
    pattern = re.compile(r'img.*ng-src="(.*?)"')  # 正则表达式匹配原图url
    base_url = "https://openi.nlm.nih.gov/"
    driver.get(base_url + det) # det 是原图所在页面url
    time.sleep(3) #等待网页加载,负责会出现获取不到网页信息的情况
    img_tag = driver.find_element(By.CLASS_NAME, "image.ng-scope").get_attribute("outerHTML")
    match = re.findall(pattern, img_tag)  # 获得所有原图url
    real_url = base_url + match[0] # 这里的real_url就是原图的图像链接
    driver.quit()

下载图片

        os.chdir(self.path) # 传入的保存路径
        img_name = url.split("/")[-1].split("?")[0]
        resp = requests.get(url)  # 获取网页信息
        byte = resp.content  # 转化为content二进制
        with open(img_name, "wb") as f:  # 文件写入
            f.write(byte)

如果爬取很少图片还勉强可以使用for循环,但是图片数量较大时for循环效率会非常低。因此使用多进程。

pool = Pool(processes=10)
pool.map(img.get_detail, get_page(total))

map()函数。需要传递两个参数,第一个参数就是需要引用的函数,第二个参数是一个可迭代对象,它会把需要迭代的元素一个个的传入第一个参数我们的函数中

详细内容请参考:https://blog.csdn.net/weixin_38819889/article/details/107815272

MyUrl.py 完整源码

import random
import re
import time
import more_itertools
import requests
import os
import sys

from multiprocessing.pool import Pool
from selenium import webdriver
from selenium.webdriver.common.by import By


def get_url(det):
    driver = webdriver.Chrome()
    pattern = re.compile(r'img.*ng-src="(.*?)"')  # 正则表达式匹配原图url
    base_url = "https://openi.nlm.nih.gov/"
    driver.get(base_url + det)
    time.sleep(3) #等待网页加载,负责会出现获取不到网页信息的情况
    img_tag = driver.find_element(By.CLASS_NAME, "image.ng-scope").get_attribute("outerHTML")
    match = re.findall(pattern, img_tag)  # 获得所有原图url
    real_url = base_url + match[0]
    driver.quit()
    return real_url


def get_page(tot):
    if tot <= 100:
        page = [0]
    elif 100 < tot <= 1000:
        count = int(tot / 100) + 1
        page = random.sample(range(0, count), count)
    elif 1000 < tot <= 5000:
        count = 10
        page = random.sample(range(0, count), 10)
    else:
        page = random.sample(range(0, 51), 10)

    return page


def get_path(path):
    temp = path.split("/")
    real_path = ""
    for i in range(0, len(temp)):

        real_path += temp[i]
        if i != len(temp) - 1:
            real_path += "//"

    return real_path


class Img:
    text = None
    path = None

    def get_detail(self, index):
        driver = webdriver.Chrome()
        # 控制浏览器访问url地址
        m = index * 100 + 1
        n = m + 99
        search_url = "https://openi.nlm.nih.gov/gridquery?q={}&m={}&n={}".format(self.text, m, n)
        driver.get(search_url)
        time.sleep(3) #等待网页加载,负责会出现获取不到网页信息的情况
        tag = driver.find_element(By.ID, "grid").get_attribute("outerHTML")  # 找到定位标签对
        pattern = re.compile(r'a.*ng-href="(.*?)"')  # 正则表达式匹配原图所在网页url
        match = re.findall(pattern, tag)  # 获得所有原图所在网页url
        # time.sleep(1)
        driver.quit()
        return match

    def get_img(self, url):
        os.chdir(self.path)
        img_name = url.split("/")[-1].split("?")[0]
        resp = requests.get(url)  # 获取网页信息
        byte = resp.content  # 转化为content二进制
        with open(img_name, "wb") as f:  # 文件写入
            f.write(byte)

    def set_text(self, text):
        self.text = text

    def set_path(self, path):
        self.path = path


if __name__ == '__main__':
    inputText = sys.argv[1]
    numText = int(sys.argv[2])
    total = int(sys.argv[3])
    filePath = sys.argv[4]

    print(inputText, numText, total, filePath)

    # start = time.perf_counter()

    img = Img()
    img.set_text(inputText)
    img.set_path(get_path(filePath))

    pool = Pool(processes=10)

    try:
        # print("Getting web page information...")
        detail = list(more_itertools.collapse(pool.map(img.get_detail, get_page(total))))

        # print("Getting an image link...")
        imgUrl = pool.map(get_url, random.sample(detail, int(numText)))

        # print("Downloading pictures...")
        pool.map(img.get_img, imgUrl)

        print("Images download completed!")
        pool.close()
        pool.join()

        # end = time.perf_counter()
        # print('Running time: %s Seconds' % (end - start))

    except:
        print("Something went wrong...[MyUrl.py]")

  1. main.py完成窗口类
    基础内容没什么好说的,信号和槽。主要需要解决的问题有两个,第一个是如果不使用子线程运行耗时任务(爬取图片),主界面会直接卡死(显示未响应,甚至直接卡退)。第二个是怎样调用MyUrl.py中的方法。因为进程池只能写在main函数中(if name == ‘main’:),我尝试通过类名或者创建对象去调用都没能成功,所以只能直接运行py文件,然后通过获取控制台的打印信息来代替返回值(如果大佬有更好的方法欢迎评论区留言)。

子进程的构建:

class MyThread(QThread):
	signal_1 = pyqtSignal(str) # 自定义一个信号,用于传递参数

   	def run(self): #重写run方法
        if self.flag == 0:
            driver = webdriver.Chrome()
            driver.get("https://openi.nlm.nih.gov/gridquery?q={}".format(self.text))
            time.sleep(3)
            try:
                total = driver.find_element(By.CLASS_NAME, "regular.ng-binding").text.split()[5]
                self.total = total
                self.signal_1.emit(total)
            except:
                message = driver.find_element(By.CLASS_NAME, "no-results.ng-scope").text
                self.signal_1.emit(message)
            driver.quit()
	
class MainWidget(QWidget):

    def __init__(self, parent=None):
        super(MainWidget, self).__init__(parent)
        self.thread = MyThread(self)
        self.thread.signal_1.connect(self.receive_msg) # 绑定

    def receive_str(self, text):  # 接收传递来的参数
        self.timer.stop()
        self.count = 0
        self.ui.textEdit.append(text)
        self.ui.downBtn.setEnabled(True)

详细内容请参考:https://blog.csdn.net/geji001/article/details/126773317

运行并获取MyUrl.py在控制台的打印信息:

            try:
            #这里替换为自己的路径
                command = "F:\Anaconda3\python.exe C:/Users/Oceans/Desktop/MyImage/MyUrl.py {} {} {} {}".format(
                        self.text, self.num, self.total, self.file_path)
                with os.popen(command, "r") as p:
                    r = p.read().split("\n")
                    r.remove('')
                    print(r)
                    self.signal_2.emit(r[-1])

            except:
                self.signal_2.emit("Something went wrong...[main.py]")

os.popen() 方法用于从一个命令打开一个管道。read()方法可以获取到所有打印的信息。由于通过\n进行分割,得到的列表最后一个元素为空,所以再进行remove。

详细内容请参考:https://blog.csdn.net/xc_zhou/article/details/96445422

可能会报错UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xad in position
PyCharm下解决方案:
在这里插入图片描述
编码全部调整为GBK即可
还有可能出现报错SyntaxError: Non-UTF-8 code starting with ‘\xc9’ in file…
这是由于文件中出现了中文字符(包括中文注释)
第一种解决方案,将中文全部替换为英文
第二种可以参考 https://www.cnblogs.com/coco2015/p/11203212.html

main.py 完整源码:

import sys
import time
import tkinter as tk
import os

from tkinter import filedialog
from PyQt5.QtCore import QThread, pyqtSignal, QTimer
from selenium.webdriver.common.by import By
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QWidget
from selenium import webdriver


class MainWidget(QWidget):
    text = None
    total = None
    num = None

    def __init__(self, parent=None):
        super(MainWidget, self).__init__(parent)

        self.ui = uic.loadUi("./MyUI.ui")

        self.thread = MyThread(self)

        self.timer = QTimer(self)
        self.count = 0

        self.ui.searchBtn.clicked.connect(self.search_click)
        self.ui.downBtn.clicked.connect(self.download_click)
        self.thread.signal_1.connect(self.receive_msg)
        self.thread.signal_2.connect(self.receive_str)
        self.timer.timeout.connect(self.operate)

    def operate(self):

        self.count += 1

        str_time = str(self.count)

        self.ui.timeLabel.setText("Running time: " + str_time + " Seconds")

    def search_click(self):
        self.timer.start(1000)
        self.ui.textEdit.clear()
        self.ui.searchBtn.setEnabled(False)
        input_edit = self.ui.inputEdit.text()
        print(input_edit)
        if input_edit != "" and input_edit.isspace() is False:
            self.text = self.ui.inputEdit.text()
            self.ui.textEdit.setText("Search: {}".format(self.text))
            self.ui.textEdit.append("Loading...")
            self.thread.get_total(self.text)
            self.thread.start()

        else:
            self.ui.downBtn.setEnabled(False)
            self.ui.textEdit.setText("Please enter content")

    def receive_msg(self, msg):
        self.timer.stop()
        self.count = 0
        if msg.isnumeric():
            self.ui.downBtn.setEnabled(True)
            self.ui.textEdit.setText("Search: {}".format(self.text))
            self.ui.textEdit.append("Results: {}".format(msg))
            self.total = int(msg)
            self.ui.searchBtn.setEnabled(True)
        else:
            self.ui.downBtn.setEnabled(False)
            self.ui.searchBtn.setEnabled(True)
            self.ui.textEdit.setText('Search: "{}"'.format(self.text))
            self.ui.textEdit.append(msg)

    def download_click(self):
        self.timer.start(1000)
        self.ui.downBtn.setEnabled(False)
        num_edit = self.ui.numEdit.text()
        print(num_edit)

        if num_edit.isnumeric():
            if int(num_edit) > self.total:
                self.ui.textEdit.append("Cannot exceed the total")
                self.ui.downBtn.setEnabled(True)
                return
            elif int(num_edit) > 100:
                self.ui.textEdit.append("Up to 100")
                self.ui.downBtn.setEnabled(True)
                return
            root = tk.Tk()
            root.withdraw()
            file_path = filedialog.askdirectory()
            print(file_path)
            if file_path == "":
                self.ui.downBtn.setEnabled(True)
                return
            self.ui.textEdit.setText(file_path)
            self.num = int(num_edit)
            self.ui.textEdit.append("Start crawling images...")

            self.thread.get_img(self.num, file_path)
            self.thread.start()

        else:
            self.ui.textEdit.append("Please enter a positive integer")
            self.ui.downBtn.setEnabled(True)

    def receive_str(self, text):
        self.timer.stop()
        self.count = 0
        self.ui.textEdit.append(text)
        self.ui.downBtn.setEnabled(True)


class MyThread(QThread):
    signal_1 = pyqtSignal(str)
    signal_2 = pyqtSignal(str)
    flag = None
    text = None
    num = None
    total = None
    file_path = None

    def __init__(self, main_form):
        super(MyThread, self).__init__()
        self.main_form = main_form

    def get_total(self, text):
        self.text = text
        self.flag = 0

    def get_img(self, num, file_path):
        self.num = num
        self.file_path = file_path
        self.flag = 1

    def run(self):
        if self.flag == 0:
            driver = webdriver.Chrome()
            driver.get("https://openi.nlm.nih.gov/gridquery?q={}".format(self.text))
            time.sleep(3)
            try:
                total = driver.find_element(By.CLASS_NAME, "regular.ng-binding").text.split()[5]
                self.total = total
                self.signal_1.emit(total)
            except:
                message = driver.find_element(By.CLASS_NAME, "no-results.ng-scope").text
                self.signal_1.emit(message)
            driver.quit()

        elif self.flag == 1:
            try:
                command = "F:\Anaconda3\python.exe C:/Users/Oceans/Desktop/DataAcquisition/MyImage/MyUrl.py {} {} {} {}".format(
                        self.text, self.num, self.total, self.file_path)
                with os.popen(command, "r") as p:
                    r = p.read().split("\n")
                    r.remove('')
                    print(r)
                    self.signal_2.emit(r[-1])

            except:
                self.signal_2.emit("Something went wrong...[main.py]")


if __name__ == '__main__':
    myapp = QApplication(sys.argv)
    myWidget = MainWidget()
    myWidget.ui.show()
    sys.exit(myapp.exec_())

  1. 运行效果
    在这里插入图片描述

完整项目(含ui文件):https://download.csdn.net/download/Oceansssss/87173745

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PyQt+界面防卡死+selenium+多进程爬取图片一次打通! 的相关文章

  • 用Java实现两个有序数组合并成一个有序数组

    需求 有序数组a 和b xff0c 将它们合并成有序数组c 思路 xff1a 新建一个以两个集合长度之和为长度的新数组 xff0c 从两数组最左边开始比起 xff0c 把小的放入新集合 xff0c 并用变量标记后一位置 xff0c 每次比较
  • Spring Bean加载的8种方式

    一 在xml文件中通过标签 lt bean gt 实现 二 使用 64 Component以及其衍生的三种注解 64 Controller 64 Service 64 Repository 三 加载第三方bean 复制代码 64 Confi
  • 非对称加密分段处理加密大量数据

    基于RSA非对称加密 属于轻量型加密 加密数据的大小有严格限制 我们可以通过对分段加密方式 实现对大量数据的非对称加密 本文在参考非对称的加密的资料基础之上 实现了大数据的非对称加密 因此少量数据于大量数据都可以实现加密处理 如果仅想实现这
  • 如何理解反向代理

    通常的代理服务器 xff0c 只用于代理内部网络对Internet的连接请求 xff0c 客户机必须指定代理服务器 并将本来要直接发送到Web服务器上的http请求发送到代理服务器中 由于外部网络上的主机并不会配置并使用这个代理服务器 xf
  • ping: www.baidu.com: 未知的名称或服务

    如果如何怎么都连不上外网 可以照搬下面配置 一定可以连通 VMc16 centos7 NAT模式下 注意子网IP和子网掩码的设置 这个决定的IP的取值范围 文件配置如下
  • 权限精确到按钮级别

    在使用sa token轻量级框架下 如何将权限精确到按钮级别 权限精确到按钮级的意思就是指 xff1a 权限范围可以控制到页面上的每一个按钮是否显示 思路 xff1a 如此精确的范围控制只依赖后端已经难以完成 xff0c 此时需要前端进行一
  • 单点登录的发展与应用

    早期我们开发web应用都是所有的包放在一起打成一个war包放入tomcat容器来运行的 所有的功能 所有的业务 后台管理 门户界面 都是由这一个war来支持的 这样的单应用 也称之为单体应用 因为十分不好扩展和拆分 在单体应用下 用户的登录
  • The command could not be located because '/sbin' is not included in the PATH environment variable.

    问题来源 重启Ubuntu后习惯性的执行ifconfig 报错如下 Command span class hljs string 39 ifconfig 39 span span class hljs keyword is span ava
  • bean实例化的方式

    1 最常见 使用构造方法 2 早些年 使用静态工厂的方式 3 更早些年的 使用实例化工厂的方式 4 spring框架常用 实现FactoryBean接口的方式
  • @Autowired

    1 Autowired依赖注入底层是通过反射暴力获取对象并赋值给属性 2 setter与构造器注入是通过给IOC容器提供入口注入的
  • C语言 Hanoi(汉诺)塔问题,用递归解决

    问题 古代有一个梵塔 xff0c 塔内有3个座A xff0c B xff0c C 开始时A座上有64个盘子 xff0c 盘子大小不等 xff0c 大的在下 xff0c 小的在上 有一个老和尚想把64个盘子从A作移到C座 xff0c 但规定每
  • Ubuntu server 22.04 安装kvm

    本人有一台工控机 xff0c 5500u cpu xff0c 8g 内存 xff0c 本来是打算用来跑docker的 xff0c 但是因为要装 k8s 虚拟机会更加合适方便 xff0c 宿主机的系统是ubuntu server 22 04
  • win10 linux 子系统 wsl2实现ip自动转发

    win10 系统带linux子系统有两个版本 第一个是wsl xff0c 它与windows 系统公用同1个ip地址 xff0c 但是没有自己内核 xff0c 不支持docker 第二个版本是wsl2 xff0c 它可以使用docker x
  • 【独家】互联网变现与计算广告(干货+5000字精彩问答)

    本讲座选自2015年9月28日刘鹏先生在清华大数据 技术 前沿 讲座上所做的题为 互联网变现与计算广告 的演讲 刘鹏 xff1a 大家好 xff0c 我是老的清华人 xff0c 诸位都是95后了 xff0c 你们出生的时候我是95年入学 清
  • 本地(window)使用alist和RaiDav网盘挂载

    一 背景 百度网盘的限速可能会让你转战阿里云盘 xff0c 但是阿里云盘的缺点在于不能分享 xff0c 网络上的资源都是通过各类网盘来分享的 xff0c 这样就会让你可能同时拥有不同网盘的账号 那么我们有没有一款工具 xff0c 可以将这些
  • 【笔记】ssd mobilenet 网络

    之前实习用过太多次mobilenet ssd xff0c 但是一直只是用 xff0c 没有去了解它的原理 今日参考了一位大神的博客 xff0c 写得很详细 xff0c 也很容易懂 xff0c 这里做一个自己的整理 xff0c 供自己理解 x
  • 添加与删除 Ubuntu 环境变量

    1 作者的系统是Ubuntu 13 10 xff0c 在其他linux发行版中环境变量的设置方式类似但会有不同 xff1b 2 这里以环境变量PATH为例 xff0c 环境变量还可以有很多 xff0c 也可以自己定义名称 什么是环境变量 环
  • [Kali Linux 安全渗透教程新手版]

    1 1什么是安全渗透 渗透测试时通过模拟黑客的攻击方法 来评估计算机网络系统安全的一种评估方法 通常的评估方式对评估结果更具全面性 而渗透测试更注重安全露的严重性 1 6Kali更新与升级 Ctrl 43 F1 快捷键提示 Ctrl 43
  • CTreeList 拖拽功能实现

    转载地址 http tech ddvip com 2008 11 122662837992492 html Visual C 43 43 中提供的MFC类CtreeCtrl xff08 树型控件 xff09 用来显示具有一定层次结构的数据项
  • 使用hex编码绕过主机卫士IIS版本继续注入

    本文作者 xff1a 非主流 测试文件的源码如下 xff1a 我们先直接加上单引号试试 xff1a http 192 168 0 20 conn asp id 61 1 27 很好 xff0c 没有报错 那我们继续 xff0c and 1

随机推荐

  • Win10启动VMware虚拟机结果宿主机蓝屏重启

    VM启动虚拟机结果宿主机蓝屏重启 xff0c 按照以下步骤处理即可 xff0c 我是通过升级VM版本最终解决的 xff0c 自己看自己的情况 xff0c 都试一下就行 1 操作控制面板 右键windows图标 xff0c 点击搜索 xff0
  • Debian9.12镜像下载及网络、软件源配置

    Debian9 12安装 配置 文章目录 获取镜像虚拟机安装配置网络配置合适的仓库源更新软件包 安装所需工具 搭建环境Debian镜像下载链接其他资源 获取镜像 Debian9 12 Debian 9 12 官方原版镜像下载 任我乐 ren
  • dpkg: 处理软件包 xxx (--configure)时出错 解决办法

    第一步 xff1a 备份 sudo mv var lib dpkg info var lib dpkg info bk 1 第二步 xff1a 新建 sudo mkdir var lib dpkg info 1 第三步 xff1a 更新 s
  • 解决SQL server中提示对象名无效

    用SQL server的时间不长 xff0c 但现在遇到两种情况 xff0c 在这里分别说一下解决办法 1 刚打开SQL server Manager Studio xff0c 想看看表里的信息 xff0c 就写一个查询语句 xff0c 结
  • 解决maven无法下载依赖的问题

    大概从2020年1月底的时候第一次遇到这个问题 xff0c 当时在假期期间自己写小Demo玩 xff0c 依赖下载不了就去找了个包放进去 xff0c 并没有太在意 直至几天后因为疫情在家远程办公的时候新项目的依赖一直下载不了 xff0c 困
  • 解决idea已经添加外部jar包但仍然找不到包的错误

    对于开发人员来说 xff0c 开发项目时除了maven下载的依赖之外 xff0c 一般都需要引入一些公司内部封装的jar包依赖 xff0c 但是有时候会出现明明已经build path了 xff0c 但是build项目的时候还是报错说某某包
  • vmware安装虚拟机提示此主机不支持64位系统,此系统无法运行

    原因 安装虚拟机提示这个是因为和电脑上的Hyper V服务冲突了 xff0c 解决办法是关闭Hyper V服务就可以了 步骤 打开控制面板找到程序和功能 点击启用或关闭Windows功能 找到Hyper V xff0c 此时状态是勾选的 取
  • springboot项目启动指定项目外部yml配置文件

    spring boot的经典项目配置是application yml xff0c 在项目打包部署运行的时候 xff0c 这个文件也会一同打进包里 xff0c 随之启动 这就带来了一个问题 xff1a 如果部署的服务器发生了变动 xff0c
  • MyEclipse安装SVN插件及插件下载地址

    在网上找了很多安装教程 xff0c 但是找到的subclipse的下载地址都访问不到 xff0c 不知道是不是需要翻墙 xff0c 我自己找了个测试过有效的 xff1a 网盘下载地址 xff1a https pan baidu com s
  • Linux 安装并配置 OpenLDAP 新编(3)YUM安装

    Linux 安装并配置 OpenLDAP 新编 xff08 3 xff09 YUM安装 我实操OpenLDAP的过程 xff0c 是先根据官网资料编译安装 xff0c 大约花费了近2周时间 xff0c 也有点陷入牛角尖了 xff0c 一时不
  • org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException

    问题描述 xff1a 1 在application yml文件里的注释乱码 2 idea编辑器提示这个文件被错误的编码UTF 8加载 xff0c 并提示重新使用GBK加载等等 3 项目启动报错 xff1a java nio charset
  • 解决java.lang.IllegalStateException: Cannot call sendError() after the response has been committe

    错误截图 xff1a 错误代码 xff1a 错误原因 xff1a 输出流关闭之后 xff0c socket也已经关闭 xff0c 不能再次发送response xff0c 所以导致错误的就是return的返回值信息 xff0c 这时候把re
  • Object转成JSONObject

    object转jsonObject的时候经常会因为符号报错 xff0c 类似于 xff1a span class token function expect span at span class token number 0 span ac
  • Comparison method violates its general contract!null

    span class token annotation punctuation 64 Override span span class token keyword public span span class token keyword i
  • bigDecimal存到数据库后变成0

    检查数据库该字段 xff0c 小数点栏是不是默认为0了 xff0c 像这样 xff1a 如果是 xff0c 就改成你需要该字段保留的小数点后位数 xff0c 比如你要保留两位 xff0c 这一栏就改成2
  • [教程] 中兴光猫f477V2改固话桥接,支持电脑、手机SIP APP拨打

    坐标北京 联通免费开通固话 xff0c 新给的光猫是比较新的型号中兴F477V2 光猫本身支持voip xff0c 买个最普通的座机接到phone口就可以用了 xff0c 固话号码是01082xxxxxxx打头的 xff0c 资费市内0 1
  • PVE安装笔记

    PVE新安装 1 安装 iso准备 xff0c 系统盘目录有6 2的iso xff0c 挺好用 准备一个U盘 xff0c 最好是usb2 0的 xff0c 用ultraiso写入硬盘镜像 xff0c 注意选择raw格式 xff08 非常重要
  • pve 6.2增加CPU温度显示

    1 安装PVE xff0c 建议用refus烧录U盘 xff0c 记得选DD镜像模式 2 iso文件名 proxmox ve 6 2 1 iso 3 安装 4 替换如下文件中相关字段 具体参考上传文件pve主页添加温度显示 6 2 zip
  • VC++工程头文件重复和循环引用

    复杂工程中头文件众多 xff0c 很容易发生包含顺序 重复引用以及循环引用导致的编译链接错误 xff01 最近整理工程中文件引用时遇到不少这方面的问题 xff01 一般来说 xff0c 包含顺序问题会导致某些类型 函数等无定义 xff0c
  • PyQt+界面防卡死+selenium+多进程爬取图片一次打通!

    创建MyUrl py 编写爬取图片代码 爬取图片 xff0c 实际上就是对网页信息的读取 而selenium可以很好的做到这一点 xff0c 相对于beautifulsoup只能爬取静态前端源码的缺点 xff0c selenium可以解析由